@raindrop-ai/wizard 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/lib/agent-interface.js +24 -0
- package/dist/src/lib/agent-interface.js.map +1 -1
- package/dist/src/lib/handlers.js +8 -9
- package/dist/src/lib/handlers.js.map +1 -1
- package/dist/src/lib/sdk-messages.d.ts +1 -1
- package/dist/src/lib/sdk-messages.js +14 -10
- package/dist/src/lib/sdk-messages.js.map +1 -1
- package/package.json +2 -2
|
@@ -297,6 +297,30 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
|
|
|
297
297
|
context: {
|
|
298
298
|
userId: orgId,
|
|
299
299
|
},
|
|
300
|
+
selfDiagnostics: {
|
|
301
|
+
signals: {
|
|
302
|
+
code_dumping: {
|
|
303
|
+
description: 'The user pasted code or console logs to the agent.',
|
|
304
|
+
sentiment: 'NEGATIVE',
|
|
305
|
+
},
|
|
306
|
+
user_wake_up: {
|
|
307
|
+
description: 'The user is waking up the agent e.g. "hello", "continue", etc.',
|
|
308
|
+
sentiment: 'NEGATIVE',
|
|
309
|
+
},
|
|
310
|
+
user_correction: {
|
|
311
|
+
description: "The user is correcting the agent's original plan or approach.",
|
|
312
|
+
sentiment: 'NEGATIVE',
|
|
313
|
+
},
|
|
314
|
+
tool_failure: {
|
|
315
|
+
description: 'A tool call returned an error, timed out, or produced unusable output.',
|
|
316
|
+
sentiment: 'NEGATIVE',
|
|
317
|
+
},
|
|
318
|
+
stuck_in_loop: {
|
|
319
|
+
description: 'The same approach has been attempted multiple times without progress.',
|
|
320
|
+
sentiment: 'NEGATIVE',
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
},
|
|
300
324
|
});
|
|
301
325
|
queryObject = wrappedSDK.query({
|
|
302
326
|
prompt: inputQueue,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-interface.js","sourceRoot":"","sources":["../../../src/lib/agent-interface.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared agent interface for wizards\n * Uses Claude Agent SDK directly with streaming input support\n */\n\nimport type { SDKUserMessage } from '@anthropic-ai/claude-agent-sdk';\nimport * as claudeAgentSDK from '@anthropic-ai/claude-agent-sdk';\nimport { createRaindropClaudeAgentSDK } from '@raindrop-ai/claude-agent-sdk';\nimport { existsSync, writeFileSync } from 'fs';\nimport { createRequire } from 'module';\nimport os from 'os';\nimport path from 'path';\nimport type { AgentQueryHandle } from '../ui/types.js';\nimport {\n debug,\n initLogFile,\n LOG_FILE_PATH,\n logToFile,\n} from '../utils/debug.js';\nimport type { WizardOptions } from '../utils/types.js';\nimport ui from '../utils/ui.js';\nimport { RAINDROP_ENDPOINT } from './constants.js';\nimport {\n createAgentQueryHandle,\n createCanUseToolHandler,\n createPreToolUseHook,\n type PendingToolCall,\n type SessionInfo,\n} from './handlers.js';\nimport { createMcpServer } from './mcp.js';\nimport { processSDKMessage } from './sdk-messages.js';\n\n// Create a require function for ESM compatibility\nconst require = createRequire(import.meta.url);\n\n/**\n * Get the path to the bundled Claude Code CLI from the SDK package.\n * This ensures we use the SDK's bundled version rather than the user's installed Claude Code.\n */\nfunction getClaudeCodeExecutablePath(): string {\n // require.resolve finds the package's main entry, then we get cli.js from same dir\n const sdkPackagePath = require.resolve('@anthropic-ai/claude-agent-sdk');\n return path.join(path.dirname(sdkPackagePath), 'cli.js');\n}\n\n/**\n * Ensure Claude CLI has a config file to read during startup.\n * Some SDK/CLI versions error if ~/.claude.json is missing.\n */\nfunction ensureClaudeConfigFileExists(): void {\n const claudeConfigPath = path.join(os.homedir(), '.claude.json');\n if (existsSync(claudeConfigPath)) {\n return;\n }\n\n writeFileSync(claudeConfigPath, '{}\\n', { encoding: 'utf-8' });\n logToFile('Created missing Claude config file:', claudeConfigPath);\n}\n\n// Re-export AgentQueryHandle for external use\nexport type { AgentQueryHandle };\n\nexport type AgentConfig = {\n workingDirectory: string;\n};\n\n/**\n * Result from runAgentLoop including session ID and query handle\n */\nexport interface AgentRunResult {\n sessionId?: string;\n handle: AgentQueryHandle;\n completed: boolean;\n support?: boolean;\n}\n\n/**\n * Internal configuration object returned by initializeAgent\n */\nexport type AgentRunConfig = {\n workingDirectory: string;\n model: string;\n};\n\ntype QueuedUserMessage = {\n type: 'user';\n message: {\n role: 'user';\n content: string;\n };\n};\n\ntype QueryMessage = {\n type?: string;\n session_id?: string;\n [key: string]: unknown;\n};\n\ntype QueryObject = AsyncIterable<QueryMessage> & {\n interrupt?: () => Promise<void>;\n};\n\n/**\n * Async queue for user messages.\n * Messages are pushed by UI callbacks and consumed by the SDK as an async iterable.\n */\nclass UserMessageQueue implements AsyncIterable<QueuedUserMessage> {\n private messages: QueuedUserMessage[] = [];\n\n private waitingResolver:\n | ((message: QueuedUserMessage | null) => void)\n | null = null;\n\n private closed = false;\n\n push(content: string): void {\n if (this.closed) {\n return;\n }\n\n const message: QueuedUserMessage = {\n type: 'user',\n message: {\n role: 'user',\n content,\n },\n };\n\n if (this.waitingResolver) {\n this.waitingResolver(message);\n this.waitingResolver = null;\n return;\n }\n\n this.messages.push(message);\n }\n\n hasPending(): boolean {\n return this.messages.length > 0;\n }\n\n close(): void {\n this.closed = true;\n if (this.waitingResolver) {\n this.waitingResolver(null);\n this.waitingResolver = null;\n }\n }\n\n async *[Symbol.asyncIterator](): AsyncIterableIterator<QueuedUserMessage> {\n while (!this.closed) {\n if (this.messages.length > 0) {\n const nextMessage = this.messages.shift();\n if (nextMessage) {\n yield nextMessage;\n }\n continue;\n }\n\n const nextMessage = await new Promise<QueuedUserMessage | null>(\n (resolve) => {\n this.waitingResolver = resolve;\n },\n );\n\n if (!nextMessage) {\n return;\n }\n\n yield nextMessage;\n }\n }\n}\n\n/**\n * Initialize agent configuration for the Claude agent\n */\nexport function initializeAgent(\n config: AgentConfig,\n options: WizardOptions,\n): AgentRunConfig {\n // Initialize log file for this run\n initLogFile();\n logToFile('Agent initialization starting');\n logToFile('Install directory:', options.installDir);\n\n try {\n ensureClaudeConfigFileExists();\n process.env.MAX_THINKING_TOKENS = '10000';\n process.env.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS = 'true';\n // Set default subagent model to Sonnet\n process.env.CLAUDE_CODE_SUBAGENT_MODEL = 'claude-sonnet-4-5-20250929';\n\n const agentRunConfig: AgentRunConfig = {\n workingDirectory: config.workingDirectory,\n model: 'sonnet',\n };\n\n logToFile('Agent config:', {\n workingDirectory: agentRunConfig.workingDirectory,\n });\n\n if (options.debug) {\n debug('Agent config:', {\n workingDirectory: agentRunConfig.workingDirectory,\n });\n }\n\n ui.addItem({\n type: 'step',\n text: `I'll keep verbose logs for this session at: ${LOG_FILE_PATH}`,\n });\n return agentRunConfig;\n } catch (error) {\n ui.addItem({\n type: 'error',\n text: `Failed to initialize agent: ${(error as Error).message}`,\n });\n logToFile('Agent initialization error:', error);\n debug('Agent initialization error:', error);\n throw error;\n }\n}\n\n/**\n * Configuration for runAgentLoop\n */\nexport interface RunAgentConfig {\n spinnerMessage?: string;\n accessToken: string;\n orgId: string;\n onCompleteIntegration?: () => Promise<boolean | string>;\n}\n\n/**\n * Execute an agent with the provided prompt and options.\n * Supports streaming input for user interruption and follow-up messages.\n * Uses a single long-lived SDK query fed by an async message queue.\n *\n * @returns Session ID and query handle for controlling the agent\n */\nexport async function runAgentLoop(\n agentConfig: AgentRunConfig,\n prompt: string,\n options: WizardOptions,\n config: RunAgentConfig,\n): Promise<AgentRunResult> {\n const {\n spinnerMessage = 'Raindrop wizard is working...',\n accessToken,\n orgId,\n onCompleteIntegration,\n } = config;\n\n // Add header to indicate start of interactive agent phase\n ui.addItem({ type: 'phase', text: '─── Agent ───' });\n\n const cliPath = getClaudeCodeExecutablePath();\n logToFile('Starting agent run');\n logToFile('Claude Code executable:', cliPath);\n\n const startTime = Date.now();\n const inputQueue = new UserMessageQueue();\n inputQueue.push(prompt);\n\n const approvedFilesCache = new Set<string>();\n const collectedText: string[] = [];\n const pendingToolCalls = new Map<string, PendingToolCall>();\n\n const hasCompletedWorkRef = { value: false };\n const isInterruptingRef = { value: false };\n const waitingForUserInputRef = { value: false };\n const exitHintShownRef = { value: false };\n\n let sessionId: string | undefined;\n let queryObject: QueryObject | null = null;\n let isSpinnerRunning = false;\n let completed = false;\n let shouldEndSession = false;\n let supportRequested = false;\n\n const spinner = ui.spinner();\n\n // Track current spinner base message and when it last changed.\n let currentSpinnerMsg = spinnerMessage;\n let lastActivityTime = Date.now();\n\n const updateSpinner = (msg: string) => {\n if (!isSpinnerRunning) return;\n currentSpinnerMsg = msg;\n lastActivityTime = Date.now();\n spinner.message(msg);\n };\n\n // Every second, if the agent has been silent for >= 10s, append a counting thinking indicator.\n // Pure JS interval — Ink only re-renders when the string actually changes.\n const thinkingTimer = setInterval(() => {\n if (!isSpinnerRunning) return;\n const idleS = Math.floor((Date.now() - lastActivityTime) / 1000);\n if (idleS >= 20) {\n const mins = Math.floor(idleS / 60);\n const secs = idleS % 60;\n const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;\n spinner.message(`${currentSpinnerMsg} (thinking · ${timeStr})`);\n }\n }, 1000);\n\n const setAgentRunning = (isRunning: boolean) => {\n if (isRunning) {\n if (!isSpinnerRunning) {\n spinner.start(spinnerMessage);\n isSpinnerRunning = true;\n }\n ui.setAgentState({ isRunning: true });\n return;\n }\n\n if (isSpinnerRunning) {\n spinner.stop();\n isSpinnerRunning = false;\n }\n ui.setAgentState({ isRunning: false });\n };\n\n // Create MCP server with CompleteIntegration tool\n const toolsMcpServer = createMcpServer(hasCompletedWorkRef, {\n sessionId: options.sessionId,\n accessToken,\n orgId,\n installDir: agentConfig.workingDirectory,\n });\n\n // Session info for notifications\n const sessionInfo: SessionInfo = {\n sessionId: options.sessionId,\n accessToken,\n orgId,\n };\n\n const handle = createAgentQueryHandle({\n isInterruptingRef,\n waitingForUserInputRef,\n pendingToolCalls,\n getQueryObject: () => queryObject,\n sendMessage: (message: string) => {\n inputQueue.push(message);\n },\n });\n\n const startPersistentInput = (placeholder?: string) => {\n ui.startPersistentInput({\n onSubmit: handlePersistentSubmit,\n onInterrupt: handlePersistentInterrupt,\n onCtrlC: handlePersistentCtrlC,\n placeholder,\n });\n };\n\n // Define callbacks for persistent input\n const handlePersistentSubmit = (message: string) => {\n const trimmedMessage = message.trim();\n if (!trimmedMessage) {\n return;\n }\n\n exitHintShownRef.value = false;\n\n ui.addItem({\n type: 'user-message',\n text: trimmedMessage,\n });\n\n handle.sendMessage(trimmedMessage);\n\n if (waitingForUserInputRef.value) {\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n setAgentRunning(true);\n return;\n }\n\n if (!isInterruptingRef.value) {\n logToFile(\n 'User submitted message while agent is running - interrupting current turn',\n );\n void handle.interrupt(true);\n }\n };\n\n const handlePersistentInterrupt = () => {\n logToFile('User requested interrupt (Esc)');\n setAgentRunning(false);\n void handle.interrupt();\n };\n\n const handlePersistentCtrlC = () => {\n logToFile('User pressed Ctrl+C');\n\n // If already interrupted and exit hint was shown, exit immediately\n if (\n (isInterruptingRef.value || waitingForUserInputRef.value) &&\n exitHintShownRef.value\n ) {\n logToFile('Second Ctrl+C - exiting');\n ui.stopPersistentInput();\n ui.exit();\n // Small delay to allow UI to clean up before exit\n setTimeout(() => process.exit(130), 100);\n return;\n }\n\n // If already interrupted but hint not shown yet, show hint and clear input\n if (isInterruptingRef.value || waitingForUserInputRef.value) {\n logToFile('First Ctrl+C while interrupted - showing exit hint');\n exitHintShownRef.value = true;\n ui.stopPersistentInput();\n startPersistentInput('Press Ctrl+C again to exit');\n return;\n }\n\n // Not interrupted yet - treat as normal interrupt\n logToFile('First Ctrl+C - triggering interrupt');\n setAgentRunning(false);\n void handle.interrupt();\n };\n\n startPersistentInput();\n setAgentRunning(true);\n\n // Create Raindrop client and wrap the Claude Agent SDK for observability\n const raindrop = createRaindropClaudeAgentSDK({\n writeKey: accessToken,\n endpoint: RAINDROP_ENDPOINT,\n });\n const wrappedSDK = raindrop.wrap(claudeAgentSDK, {\n context: {\n userId: orgId,\n },\n });\n\n queryObject = wrappedSDK.query({\n prompt: inputQueue as unknown as AsyncIterable<SDKUserMessage>,\n options: {\n model: agentConfig.model,\n cwd: agentConfig.workingDirectory,\n permissionMode: 'default',\n disallowedTools: ['Skill'],\n mcpServers: {\n 'raindrop-wizard': toolsMcpServer,\n },\n systemPrompt: '{WIZARD_SYSTEM_PROMPT}',\n env: { ...process.env },\n canUseTool: createCanUseToolHandler(approvedFilesCache),\n hooks: {\n PreToolUse: [{ hooks: [createPreToolUseHook(sessionInfo)] }],\n },\n stderr: (data: string) => {\n logToFile('CLI stderr:', data);\n if (options.debug) {\n debug('CLI stderr:', data);\n }\n },\n },\n });\n\n // Update agent state\n ui.setAgentState({\n isRunning: true,\n queryHandle: handle,\n });\n\n try {\n if (!queryObject) {\n throw new Error('queryObject was not initialized');\n }\n for await (const message of queryObject) {\n // Capture session_id from any message\n if (message.session_id && !sessionId) {\n sessionId = message.session_id;\n ui.setAgentState({ sessionId });\n }\n\n // If we were waiting for user input but got a new message,\n // the queued message has started processing.\n if (\n waitingForUserInputRef.value &&\n !isInterruptingRef.value &&\n message.type !== 'result'\n ) {\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n setAgentRunning(true);\n }\n\n processSDKMessage(\n message,\n options,\n collectedText,\n pendingToolCalls,\n isInterruptingRef.value,\n { updateSpinner, baseSpinnerMessage: spinnerMessage },\n );\n\n if (message.type !== 'result') {\n continue;\n }\n\n if (hasCompletedWorkRef.value) {\n setAgentRunning(false);\n ui.stopPersistentInput();\n\n const completionDecision = onCompleteIntegration\n ? await onCompleteIntegration()\n : true;\n\n if (completionDecision === 'support') {\n logToFile('User requested support - ending session');\n completed = false;\n supportRequested = true;\n shouldEndSession = true;\n inputQueue.close();\n break;\n }\n\n if (typeof completionDecision === 'string') {\n const feedbackPrompt = completionDecision.trim();\n if (!feedbackPrompt) {\n logToFile('Received empty feedback prompt - ending session');\n completed = false;\n shouldEndSession = true;\n inputQueue.close();\n break;\n }\n\n logToFile('Received testing feedback - queueing feedback prompt');\n hasCompletedWorkRef.value = false;\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n handle.sendMessage(feedbackPrompt);\n startPersistentInput();\n setAgentRunning(true);\n continue;\n }\n\n completed = completionDecision;\n shouldEndSession = true;\n inputQueue.close();\n break;\n }\n\n // Turn ended without completion. If there are no queued messages,\n // we are waiting for the user to submit the next one.\n isInterruptingRef.value = false;\n\n if (!inputQueue.hasPending()) {\n waitingForUserInputRef.value = true;\n setAgentRunning(false);\n } else {\n waitingForUserInputRef.value = false;\n setAgentRunning(true);\n }\n }\n } finally {\n inputQueue.close();\n clearInterval(thinkingTimer);\n await raindrop.flush();\n }\n\n const durationMs = Date.now() - startTime;\n logToFile(`Agent session completed in ${Math.round(durationMs / 1000)}s`);\n logToFile('Session ID:', sessionId);\n logToFile('Completion status:', hasCompletedWorkRef.value);\n\n if (!shouldEndSession && hasCompletedWorkRef.value) {\n // Fallback: if stream ended after completion, mark as completed.\n completed = true;\n }\n\n ui.stopPersistentInput();\n ui.setAgentState({ isRunning: false });\n\n if (completed || isSpinnerRunning) {\n spinner.stop();\n }\n\n return { sessionId, handle, completed, support: supportRequested };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent-interface.js","sourceRoot":"","sources":["../../../src/lib/agent-interface.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared agent interface for wizards\n * Uses Claude Agent SDK directly with streaming input support\n */\n\nimport type { SDKUserMessage } from '@anthropic-ai/claude-agent-sdk';\nimport * as claudeAgentSDK from '@anthropic-ai/claude-agent-sdk';\nimport { createRaindropClaudeAgentSDK } from '@raindrop-ai/claude-agent-sdk';\nimport { existsSync, writeFileSync } from 'fs';\nimport { createRequire } from 'module';\nimport os from 'os';\nimport path from 'path';\nimport type { AgentQueryHandle } from '../ui/types.js';\nimport {\n debug,\n initLogFile,\n LOG_FILE_PATH,\n logToFile,\n} from '../utils/debug.js';\nimport type { WizardOptions } from '../utils/types.js';\nimport ui from '../utils/ui.js';\nimport { RAINDROP_ENDPOINT } from './constants.js';\nimport {\n createAgentQueryHandle,\n createCanUseToolHandler,\n createPreToolUseHook,\n type PendingToolCall,\n type SessionInfo,\n} from './handlers.js';\nimport { createMcpServer } from './mcp.js';\nimport { processSDKMessage } from './sdk-messages.js';\n\n// Create a require function for ESM compatibility\nconst require = createRequire(import.meta.url);\n\n/**\n * Get the path to the bundled Claude Code CLI from the SDK package.\n * This ensures we use the SDK's bundled version rather than the user's installed Claude Code.\n */\nfunction getClaudeCodeExecutablePath(): string {\n // require.resolve finds the package's main entry, then we get cli.js from same dir\n const sdkPackagePath = require.resolve('@anthropic-ai/claude-agent-sdk');\n return path.join(path.dirname(sdkPackagePath), 'cli.js');\n}\n\n/**\n * Ensure Claude CLI has a config file to read during startup.\n * Some SDK/CLI versions error if ~/.claude.json is missing.\n */\nfunction ensureClaudeConfigFileExists(): void {\n const claudeConfigPath = path.join(os.homedir(), '.claude.json');\n if (existsSync(claudeConfigPath)) {\n return;\n }\n\n writeFileSync(claudeConfigPath, '{}\\n', { encoding: 'utf-8' });\n logToFile('Created missing Claude config file:', claudeConfigPath);\n}\n\n// Re-export AgentQueryHandle for external use\nexport type { AgentQueryHandle };\n\nexport type AgentConfig = {\n workingDirectory: string;\n};\n\n/**\n * Result from runAgentLoop including session ID and query handle\n */\nexport interface AgentRunResult {\n sessionId?: string;\n handle: AgentQueryHandle;\n completed: boolean;\n support?: boolean;\n}\n\n/**\n * Internal configuration object returned by initializeAgent\n */\nexport type AgentRunConfig = {\n workingDirectory: string;\n model: string;\n};\n\ntype QueuedUserMessage = {\n type: 'user';\n message: {\n role: 'user';\n content: string;\n };\n};\n\ntype QueryMessage = {\n type?: string;\n session_id?: string;\n [key: string]: unknown;\n};\n\ntype QueryObject = AsyncIterable<QueryMessage> & {\n interrupt?: () => Promise<void>;\n};\n\n/**\n * Async queue for user messages.\n * Messages are pushed by UI callbacks and consumed by the SDK as an async iterable.\n */\nclass UserMessageQueue implements AsyncIterable<QueuedUserMessage> {\n private messages: QueuedUserMessage[] = [];\n\n private waitingResolver:\n | ((message: QueuedUserMessage | null) => void)\n | null = null;\n\n private closed = false;\n\n push(content: string): void {\n if (this.closed) {\n return;\n }\n\n const message: QueuedUserMessage = {\n type: 'user',\n message: {\n role: 'user',\n content,\n },\n };\n\n if (this.waitingResolver) {\n this.waitingResolver(message);\n this.waitingResolver = null;\n return;\n }\n\n this.messages.push(message);\n }\n\n hasPending(): boolean {\n return this.messages.length > 0;\n }\n\n close(): void {\n this.closed = true;\n if (this.waitingResolver) {\n this.waitingResolver(null);\n this.waitingResolver = null;\n }\n }\n\n async *[Symbol.asyncIterator](): AsyncIterableIterator<QueuedUserMessage> {\n while (!this.closed) {\n if (this.messages.length > 0) {\n const nextMessage = this.messages.shift();\n if (nextMessage) {\n yield nextMessage;\n }\n continue;\n }\n\n const nextMessage = await new Promise<QueuedUserMessage | null>(\n (resolve) => {\n this.waitingResolver = resolve;\n },\n );\n\n if (!nextMessage) {\n return;\n }\n\n yield nextMessage;\n }\n }\n}\n\n/**\n * Initialize agent configuration for the Claude agent\n */\nexport function initializeAgent(\n config: AgentConfig,\n options: WizardOptions,\n): AgentRunConfig {\n // Initialize log file for this run\n initLogFile();\n logToFile('Agent initialization starting');\n logToFile('Install directory:', options.installDir);\n\n try {\n ensureClaudeConfigFileExists();\n process.env.MAX_THINKING_TOKENS = '10000';\n process.env.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS = 'true';\n // Set default subagent model to Sonnet\n process.env.CLAUDE_CODE_SUBAGENT_MODEL = 'claude-sonnet-4-5-20250929';\n\n const agentRunConfig: AgentRunConfig = {\n workingDirectory: config.workingDirectory,\n model: 'sonnet',\n };\n\n logToFile('Agent config:', {\n workingDirectory: agentRunConfig.workingDirectory,\n });\n\n if (options.debug) {\n debug('Agent config:', {\n workingDirectory: agentRunConfig.workingDirectory,\n });\n }\n\n ui.addItem({\n type: 'step',\n text: `I'll keep verbose logs for this session at: ${LOG_FILE_PATH}`,\n });\n return agentRunConfig;\n } catch (error) {\n ui.addItem({\n type: 'error',\n text: `Failed to initialize agent: ${(error as Error).message}`,\n });\n logToFile('Agent initialization error:', error);\n debug('Agent initialization error:', error);\n throw error;\n }\n}\n\n/**\n * Configuration for runAgentLoop\n */\nexport interface RunAgentConfig {\n spinnerMessage?: string;\n accessToken: string;\n orgId: string;\n onCompleteIntegration?: () => Promise<boolean | string>;\n}\n\n/**\n * Execute an agent with the provided prompt and options.\n * Supports streaming input for user interruption and follow-up messages.\n * Uses a single long-lived SDK query fed by an async message queue.\n *\n * @returns Session ID and query handle for controlling the agent\n */\nexport async function runAgentLoop(\n agentConfig: AgentRunConfig,\n prompt: string,\n options: WizardOptions,\n config: RunAgentConfig,\n): Promise<AgentRunResult> {\n const {\n spinnerMessage = 'Raindrop wizard is working...',\n accessToken,\n orgId,\n onCompleteIntegration,\n } = config;\n\n // Add header to indicate start of interactive agent phase\n ui.addItem({ type: 'phase', text: '─── Agent ───' });\n\n const cliPath = getClaudeCodeExecutablePath();\n logToFile('Starting agent run');\n logToFile('Claude Code executable:', cliPath);\n\n const startTime = Date.now();\n const inputQueue = new UserMessageQueue();\n inputQueue.push(prompt);\n\n const approvedFilesCache = new Set<string>();\n const collectedText: string[] = [];\n const pendingToolCalls = new Map<string, PendingToolCall>();\n\n const hasCompletedWorkRef = { value: false };\n const isInterruptingRef = { value: false };\n const waitingForUserInputRef = { value: false };\n const exitHintShownRef = { value: false };\n\n let sessionId: string | undefined;\n let queryObject: QueryObject | null = null;\n let isSpinnerRunning = false;\n let completed = false;\n let shouldEndSession = false;\n let supportRequested = false;\n\n const spinner = ui.spinner();\n\n // Track current spinner base message and when it last changed.\n let currentSpinnerMsg = spinnerMessage;\n let lastActivityTime = Date.now();\n\n const updateSpinner = (msg: string) => {\n if (!isSpinnerRunning) return;\n currentSpinnerMsg = msg;\n lastActivityTime = Date.now();\n spinner.message(msg);\n };\n\n // Every second, if the agent has been silent for >= 10s, append a counting thinking indicator.\n // Pure JS interval — Ink only re-renders when the string actually changes.\n const thinkingTimer = setInterval(() => {\n if (!isSpinnerRunning) return;\n const idleS = Math.floor((Date.now() - lastActivityTime) / 1000);\n if (idleS >= 20) {\n const mins = Math.floor(idleS / 60);\n const secs = idleS % 60;\n const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;\n spinner.message(`${currentSpinnerMsg} (thinking · ${timeStr})`);\n }\n }, 1000);\n\n const setAgentRunning = (isRunning: boolean) => {\n if (isRunning) {\n if (!isSpinnerRunning) {\n spinner.start(spinnerMessage);\n isSpinnerRunning = true;\n }\n ui.setAgentState({ isRunning: true });\n return;\n }\n\n if (isSpinnerRunning) {\n spinner.stop();\n isSpinnerRunning = false;\n }\n ui.setAgentState({ isRunning: false });\n };\n\n // Create MCP server with CompleteIntegration tool\n const toolsMcpServer = createMcpServer(hasCompletedWorkRef, {\n sessionId: options.sessionId,\n accessToken,\n orgId,\n installDir: agentConfig.workingDirectory,\n });\n\n // Session info for notifications\n const sessionInfo: SessionInfo = {\n sessionId: options.sessionId,\n accessToken,\n orgId,\n };\n\n const handle = createAgentQueryHandle({\n isInterruptingRef,\n waitingForUserInputRef,\n pendingToolCalls,\n getQueryObject: () => queryObject,\n sendMessage: (message: string) => {\n inputQueue.push(message);\n },\n });\n\n const startPersistentInput = (placeholder?: string) => {\n ui.startPersistentInput({\n onSubmit: handlePersistentSubmit,\n onInterrupt: handlePersistentInterrupt,\n onCtrlC: handlePersistentCtrlC,\n placeholder,\n });\n };\n\n // Define callbacks for persistent input\n const handlePersistentSubmit = (message: string) => {\n const trimmedMessage = message.trim();\n if (!trimmedMessage) {\n return;\n }\n\n exitHintShownRef.value = false;\n\n ui.addItem({\n type: 'user-message',\n text: trimmedMessage,\n });\n\n handle.sendMessage(trimmedMessage);\n\n if (waitingForUserInputRef.value) {\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n setAgentRunning(true);\n return;\n }\n\n if (!isInterruptingRef.value) {\n logToFile(\n 'User submitted message while agent is running - interrupting current turn',\n );\n void handle.interrupt(true);\n }\n };\n\n const handlePersistentInterrupt = () => {\n logToFile('User requested interrupt (Esc)');\n setAgentRunning(false);\n void handle.interrupt();\n };\n\n const handlePersistentCtrlC = () => {\n logToFile('User pressed Ctrl+C');\n\n // If already interrupted and exit hint was shown, exit immediately\n if (\n (isInterruptingRef.value || waitingForUserInputRef.value) &&\n exitHintShownRef.value\n ) {\n logToFile('Second Ctrl+C - exiting');\n ui.stopPersistentInput();\n ui.exit();\n // Small delay to allow UI to clean up before exit\n setTimeout(() => process.exit(130), 100);\n return;\n }\n\n // If already interrupted but hint not shown yet, show hint and clear input\n if (isInterruptingRef.value || waitingForUserInputRef.value) {\n logToFile('First Ctrl+C while interrupted - showing exit hint');\n exitHintShownRef.value = true;\n ui.stopPersistentInput();\n startPersistentInput('Press Ctrl+C again to exit');\n return;\n }\n\n // Not interrupted yet - treat as normal interrupt\n logToFile('First Ctrl+C - triggering interrupt');\n setAgentRunning(false);\n void handle.interrupt();\n };\n\n startPersistentInput();\n setAgentRunning(true);\n\n // Create Raindrop client and wrap the Claude Agent SDK for observability\n const raindrop = createRaindropClaudeAgentSDK({\n writeKey: accessToken,\n endpoint: RAINDROP_ENDPOINT,\n });\n const wrappedSDK = raindrop.wrap(claudeAgentSDK, {\n context: {\n userId: orgId,\n },\n selfDiagnostics: {\n signals: {\n code_dumping: {\n description: 'The user pasted code or console logs to the agent.',\n sentiment: 'NEGATIVE',\n },\n user_wake_up: {\n description:\n 'The user is waking up the agent e.g. \"hello\", \"continue\", etc.',\n sentiment: 'NEGATIVE',\n },\n user_correction: {\n description:\n \"The user is correcting the agent's original plan or approach.\",\n sentiment: 'NEGATIVE',\n },\n tool_failure: {\n description:\n 'A tool call returned an error, timed out, or produced unusable output.',\n sentiment: 'NEGATIVE',\n },\n stuck_in_loop: {\n description:\n 'The same approach has been attempted multiple times without progress.',\n sentiment: 'NEGATIVE',\n },\n },\n },\n });\n\n queryObject = wrappedSDK.query({\n prompt: inputQueue as unknown as AsyncIterable<SDKUserMessage>,\n options: {\n model: agentConfig.model,\n cwd: agentConfig.workingDirectory,\n permissionMode: 'default',\n disallowedTools: ['Skill'],\n mcpServers: {\n 'raindrop-wizard': toolsMcpServer,\n },\n systemPrompt: '{WIZARD_SYSTEM_PROMPT}',\n env: { ...process.env },\n canUseTool: createCanUseToolHandler(approvedFilesCache),\n hooks: {\n PreToolUse: [{ hooks: [createPreToolUseHook(sessionInfo)] }],\n },\n stderr: (data: string) => {\n logToFile('CLI stderr:', data);\n if (options.debug) {\n debug('CLI stderr:', data);\n }\n },\n },\n });\n\n // Update agent state\n ui.setAgentState({\n isRunning: true,\n queryHandle: handle,\n });\n\n try {\n if (!queryObject) {\n throw new Error('queryObject was not initialized');\n }\n for await (const message of queryObject) {\n // Capture session_id from any message\n if (message.session_id && !sessionId) {\n sessionId = message.session_id;\n ui.setAgentState({ sessionId });\n }\n\n // If we were waiting for user input but got a new message,\n // the queued message has started processing.\n if (\n waitingForUserInputRef.value &&\n !isInterruptingRef.value &&\n message.type !== 'result'\n ) {\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n setAgentRunning(true);\n }\n\n processSDKMessage(\n message,\n options,\n collectedText,\n pendingToolCalls,\n isInterruptingRef.value,\n { updateSpinner, baseSpinnerMessage: spinnerMessage },\n );\n\n if (message.type !== 'result') {\n continue;\n }\n\n if (hasCompletedWorkRef.value) {\n setAgentRunning(false);\n ui.stopPersistentInput();\n\n const completionDecision = onCompleteIntegration\n ? await onCompleteIntegration()\n : true;\n\n if (completionDecision === 'support') {\n logToFile('User requested support - ending session');\n completed = false;\n supportRequested = true;\n shouldEndSession = true;\n inputQueue.close();\n break;\n }\n\n if (typeof completionDecision === 'string') {\n const feedbackPrompt = completionDecision.trim();\n if (!feedbackPrompt) {\n logToFile('Received empty feedback prompt - ending session');\n completed = false;\n shouldEndSession = true;\n inputQueue.close();\n break;\n }\n\n logToFile('Received testing feedback - queueing feedback prompt');\n hasCompletedWorkRef.value = false;\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n handle.sendMessage(feedbackPrompt);\n startPersistentInput();\n setAgentRunning(true);\n continue;\n }\n\n completed = completionDecision;\n shouldEndSession = true;\n inputQueue.close();\n break;\n }\n\n // Turn ended without completion. If there are no queued messages,\n // we are waiting for the user to submit the next one.\n isInterruptingRef.value = false;\n\n if (!inputQueue.hasPending()) {\n waitingForUserInputRef.value = true;\n setAgentRunning(false);\n } else {\n waitingForUserInputRef.value = false;\n setAgentRunning(true);\n }\n }\n } finally {\n inputQueue.close();\n clearInterval(thinkingTimer);\n await raindrop.flush();\n }\n\n const durationMs = Date.now() - startTime;\n logToFile(`Agent session completed in ${Math.round(durationMs / 1000)}s`);\n logToFile('Session ID:', sessionId);\n logToFile('Completion status:', hasCompletedWorkRef.value);\n\n if (!shouldEndSession && hasCompletedWorkRef.value) {\n // Fallback: if stream ended after completion, mark as completed.\n completed = true;\n }\n\n ui.stopPersistentInput();\n ui.setAgentState({ isRunning: false });\n\n if (completed || isSpinnerRunning) {\n spinner.stop();\n }\n\n return { sessionId, handle, completed, support: supportRequested };\n}\n"]}
|
package/dist/src/lib/handlers.js
CHANGED
|
@@ -301,15 +301,13 @@ async function handlePlanApproval(input, sessionInfo) {
|
|
|
301
301
|
updatedInput: input,
|
|
302
302
|
};
|
|
303
303
|
}
|
|
304
|
+
/** Prefix for MCP tools (e.g. mcp__server__tool or mcp____server____tool). All are auto-approved and not shown in approval UI. */
|
|
305
|
+
const MCP_TOOL_PREFIX = 'mcp__';
|
|
304
306
|
/**
|
|
305
|
-
* Tools that are automatically approved without user confirmation
|
|
307
|
+
* Tools that are automatically approved without user confirmation.
|
|
308
|
+
* MCP tools (name starts with mcp__) are approved via wildcard in PreToolUse.
|
|
306
309
|
*/
|
|
307
|
-
const AUTO_APPROVED_TOOLS = new Set([
|
|
308
|
-
'mcp__raindrop-wizard__CompleteIntegration',
|
|
309
|
-
'mcp__raindrop-wizard__LoadDocumentation',
|
|
310
|
-
'mcp__raindrop-wizard__InitializeSession',
|
|
311
|
-
'EnterPlanMode',
|
|
312
|
-
]);
|
|
310
|
+
const AUTO_APPROVED_TOOLS = new Set(['EnterPlanMode']);
|
|
313
311
|
/**
|
|
314
312
|
* Patterns indicating a file path or glob likely targets secret/credential files.
|
|
315
313
|
* Used to auto-deny Read/Glob/Grep operations on sensitive files.
|
|
@@ -411,8 +409,9 @@ export function createPreToolUseHook(sessionInfo) {
|
|
|
411
409
|
},
|
|
412
410
|
};
|
|
413
411
|
}
|
|
414
|
-
// Auto-approve
|
|
415
|
-
if (
|
|
412
|
+
// Auto-approve all MCP tools (mcp__*) and EnterPlanMode — no approval UI
|
|
413
|
+
if (tool_name.startsWith(MCP_TOOL_PREFIX) ||
|
|
414
|
+
AUTO_APPROVED_TOOLS.has(tool_name)) {
|
|
416
415
|
return {
|
|
417
416
|
hookSpecificOutput: {
|
|
418
417
|
hookEventName: 'PreToolUse',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../../src/lib/handlers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tool approval handlers for the Claude agent\n * Handles UI integration for tool approvals and clarifying questions\n */\n\nimport type { HookInput, HookJSONOutput } from '@anthropic-ai/claude-agent-sdk';\nimport { createTwoFilesPatch } from 'diff';\nimport type { AgentQueryHandle, ToolApprovalResult } from '../ui/types.js';\nimport { logToFile } from '../utils/debug.js';\nimport { sendSessionUpdate } from '../utils/session.js';\nimport ui from '../utils/ui.js';\nimport { SAFE_BASH_PATTERNS } from './constants.js';\n\n// ============================================================================\n// Session-wide Approval Tracking\n// ============================================================================\n\n/**\n * Set of file paths that have been granted blanket approval for the session.\n * When a file is in this set, Edit/Write operations on it are auto-approved.\n */\nconst approvedFilesForSession = new Set<string>();\n\n/**\n * Set of command patterns that have been granted blanket approval for the session.\n * When a command matches a pattern in this set, Bash operations are auto-approved.\n * Patterns use simple prefix matching (e.g., \"npm install\" matches \"npm install axios\").\n */\nconst approvedCommandPatternsForSession = new Set<string>();\n\n/**\n * Clear all session-wide file approvals.\n * Useful when starting a new session or resetting permissions.\n */\nexport function clearApprovedFiles(): void {\n approvedFilesForSession.clear();\n logToFile('Cleared all approved files for session');\n}\n\n/**\n * Clear all session-wide command pattern approvals.\n * Useful when starting a new session or resetting permissions.\n */\nexport function clearApprovedCommandPatterns(): void {\n approvedCommandPatternsForSession.clear();\n logToFile('Cleared all approved command patterns for session');\n}\n\n/**\n * Get the list of currently approved files (for debugging/display purposes)\n */\nexport function getApprovedFiles(): string[] {\n return Array.from(approvedFilesForSession);\n}\n\n/**\n * Get the list of currently approved command patterns (for debugging/display purposes)\n */\nexport function getApprovedCommandPatterns(): string[] {\n return Array.from(approvedCommandPatternsForSession);\n}\n\n/**\n * Extract the command pattern from a bash command for session approval.\n * Returns the base command with the first argument(s) to match similar commands.\n * Examples:\n * \"npm install axios\" -> \"npm install\"\n * \"npm run build\" -> \"npm run\"\n * \"pip install requests\" -> \"pip install\"\n * \"yarn add lodash\" -> \"yarn add\"\n */\nfunction extractCommandPattern(command: string): string {\n const trimmed = command.trim();\n const parts = trimmed.split(/\\s+/);\n\n // For package managers with subcommands, include the subcommand\n if (parts.length >= 2) {\n const [cmd, subcmd] = parts;\n // Common package managers\n if (\n ['npm', 'yarn', 'bun', 'pip', 'pip3', 'poetry', 'cargo', 'go'].includes(\n cmd,\n )\n ) {\n return `${cmd} ${subcmd}`;\n }\n }\n\n // For other commands, just return the first part\n return parts[0] || trimmed;\n}\n\n/**\n * Check if a bash command matches any approved command pattern for the session.\n */\nfunction isCommandApprovedForSession(command: string): boolean {\n const pattern = extractCommandPattern(command);\n return approvedCommandPatternsForSession.has(pattern);\n}\n\n// ============================================================================\n// Pending Tool Call Types\n// ============================================================================\n\n/**\n * Pending tool call info stored while waiting for result\n */\nexport interface PendingToolCall {\n toolName: string;\n input: Record<string, unknown>;\n description?: string;\n /** ID of the 'executing' history item, used to update it on completion/interrupt */\n historyItemId?: number;\n}\n\n// ============================================================================\n// Agent Query Handle Factory\n// ============================================================================\n\n/**\n * Dependencies required for creating an AgentQueryHandle\n */\nexport interface AgentQueryHandleDeps {\n isInterruptingRef: { value: boolean };\n waitingForUserInputRef: { value: boolean };\n pendingToolCalls: Map<string, PendingToolCall>;\n getQueryObject: () => { interrupt?: () => Promise<void> } | null;\n sendMessage: (message: string) => void;\n}\n\n/**\n * Create an AgentQueryHandle for external control of the agent.\n * Handles interrupts by marking pending tool calls (keeps persistent input running).\n */\nexport function createAgentQueryHandle(\n deps: AgentQueryHandleDeps,\n): AgentQueryHandle {\n const {\n isInterruptingRef,\n waitingForUserInputRef,\n pendingToolCalls,\n getQueryObject,\n sendMessage,\n } = deps;\n\n return {\n interrupt: async (fromUserMessage?: boolean) => {\n logToFile('Soft interrupt requested (Esc)');\n\n // If already interrupted, don't add another \"Interrupted\" item\n if (isInterruptingRef.value || waitingForUserInputRef.value) {\n logToFile('Already interrupted - ignoring duplicate interrupt request');\n return;\n }\n\n isInterruptingRef.value = true;\n waitingForUserInputRef.value = true;\n\n // Mark all pending tool calls as interrupted and show them in history\n if (pendingToolCalls.size > 0) {\n for (const [toolUseId, pendingCall] of pendingToolCalls) {\n const interruptedToolCall = {\n toolName: pendingCall.toolName,\n status: 'interrupted' as const,\n input: pendingCall.input,\n description: pendingCall.description,\n };\n if (pendingCall.historyItemId !== undefined) {\n ui.updateItem(pendingCall.historyItemId, {\n type: 'tool-call',\n text: pendingCall.toolName,\n toolCall: interruptedToolCall,\n });\n } else {\n ui.addItem({\n type: 'tool-call',\n text: pendingCall.toolName,\n toolCall: interruptedToolCall,\n });\n }\n pendingToolCalls.delete(toolUseId);\n }\n } else if (!fromUserMessage) {\n // No pending tool calls and not interrupted by a user message - show generic indicator\n ui.addItem({\n type: 'error',\n text: 'Interrupted',\n });\n }\n\n // Note: Don't stop persistent input here - keep it visible for user to type their message\n // The spinner will be stopped separately, and the input remains for user to submit\n\n // Call SDK interrupt\n const queryObject = getQueryObject();\n if (queryObject?.interrupt) {\n logToFile('Calling queryObject.interrupt()');\n await queryObject.interrupt();\n logToFile('queryObject.interrupt() completed');\n } else {\n logToFile('No queryObject.interrupt available');\n }\n },\n sendMessage: (message: string) => {\n const trimmedMessage = message.trim();\n if (!trimmedMessage) {\n return;\n }\n logToFile('Queueing user message for active session');\n sendMessage(trimmedMessage);\n },\n };\n}\n\n// ============================================================================\n// Enhanced canUseTool Handler with UI Integration\n// ============================================================================\n\n/**\n * Generate a unified diff for Edit tool inputs (old_string -> new_string)\n */\nfunction generateEditDiff(\n filePath: string,\n oldString: string,\n newString: string,\n): string {\n // createTwoFilesPatch generates a unified diff\n return createTwoFilesPatch(\n filePath,\n filePath,\n oldString,\n newString,\n '', // old header\n '', // new header\n { context: 3 }, // context lines\n );\n}\n\n/**\n * Handle tool approval request by showing approval UI\n */\nasync function handleToolApproval(\n toolName: string,\n input: Record<string, unknown>,\n approvedFilesCache?: Set<string>,\n): Promise<ToolApprovalResult> {\n logToFile('Showing tool approval UI:', { toolName, input });\n\n // Extract file path\n const fileName =\n typeof input.file_path === 'string'\n ? input.file_path\n : typeof input.path === 'string'\n ? input.path\n : undefined;\n\n // Check if this file has been approved for all edits\n if (\n approvedFilesCache &&\n fileName &&\n (toolName === 'Edit' || toolName === 'Write') &&\n approvedFilesCache.has(fileName)\n ) {\n logToFile('Auto-approving edit to previously approved file:', fileName);\n return {\n behavior: 'allow',\n updatedInput: input,\n };\n }\n\n // Stop spinner while waiting for user approval\n const spinner = ui.spinner();\n spinner.stop();\n\n // Generate diff content for file modification tools\n let diffContent: string | undefined;\n if (\n toolName === 'Edit' &&\n typeof input.old_string === 'string' &&\n typeof input.new_string === 'string' &&\n fileName\n ) {\n // Edit: show old -> new diff\n diffContent = generateEditDiff(\n fileName,\n input.old_string,\n input.new_string,\n );\n } else if (\n toolName === 'Write' &&\n typeof input.content === 'string' &&\n fileName\n ) {\n // Write: show content as all additions (empty -> content)\n diffContent = generateEditDiff(fileName, '', input.content);\n } else if (typeof input.file_diff === 'string') {\n // Use pre-generated diff if available\n diffContent = input.file_diff;\n }\n\n // Build props for the approval prompt\n const props = {\n toolName,\n input,\n description:\n typeof input.description === 'string' ? input.description : undefined,\n diffContent,\n fileName,\n };\n\n try {\n const result = await ui.toolApproval(props);\n logToFile('Tool approval result:', result);\n\n // If user chose \"allow all edits to this file\", add to both caches\n if (\n result.behavior === 'allow' &&\n 'allowAllForFile' in result &&\n result.allowAllForFile\n ) {\n approvedFilesForSession.add(result.allowAllForFile);\n logToFile('Added file to approved list:', result.allowAllForFile);\n }\n if (\n result.behavior === 'allow' &&\n result.allowAllEdits &&\n fileName &&\n approvedFilesCache\n ) {\n logToFile('Adding file to approved files cache:', fileName);\n approvedFilesCache.add(fileName);\n }\n\n // If user selected \"allow all for this command pattern\", add to approved set\n if (\n result.behavior === 'allow' &&\n 'allowAllForCommandPattern' in result &&\n result.allowAllForCommandPattern\n ) {\n approvedCommandPatternsForSession.add(result.allowAllForCommandPattern);\n logToFile(\n 'Added command pattern to approved list:',\n result.allowAllForCommandPattern,\n );\n }\n\n // Restart spinner after user responds\n spinner.start();\n\n return result;\n } catch (error) {\n logToFile('Error in tool approval:', error);\n return {\n behavior: 'deny',\n message: 'Failed to get user approval',\n };\n }\n}\n\n/**\n * Handle the AskUserQuestion tool by showing clarifying questions UI.\n * Input already contains { questions: [...] } in the correct format.\n * Returns { questions, answers } as expected by the SDK.\n */\nasync function handleClarifyingQuestions(\n input: Record<string, unknown>,\n): Promise<ToolApprovalResult> {\n logToFile('Handling AskUserQuestion:', input);\n\n // Stop spinner while waiting for user input\n const spinner = ui.spinner();\n spinner.stop();\n\n try {\n // Input is already in ClarifyingQuestionsProps format\n const result = await ui.clarifyingQuestions(input as any);\n logToFile('Clarifying questions result:', result);\n\n // Restart spinner after user responds\n spinner.start();\n\n // Return questions + answers as expected by SDK\n return {\n behavior: 'allow',\n updatedInput: {\n questions: result.questions,\n answers: result.answers,\n },\n };\n } catch (error) {\n logToFile('Error in clarifying questions:', error);\n return {\n behavior: 'deny',\n message: 'Failed to get user answers',\n };\n }\n}\n\n/**\n * Session info for notifications\n */\nexport interface SessionInfo {\n sessionId: string;\n accessToken: string;\n orgId: string;\n}\n\n/**\n * Handle the ExitPlanMode tool by showing plan approval UI.\n * Input contains { plan: \"...\" } with the plan in markdown format.\n * If user approves, returns allow. If user rejects, returns deny with feedback.\n */\nasync function handlePlanApproval(\n input: Record<string, unknown>,\n sessionInfo?: SessionInfo,\n): Promise<ToolApprovalResult> {\n logToFile('Handling ExitPlanMode:', input);\n\n const planContent = typeof input.plan === 'string' ? input.plan : '';\n\n // Send session update with plan content\n if (sessionInfo) {\n sendSessionUpdate(\n sessionInfo.sessionId,\n planContent,\n sessionInfo.accessToken,\n sessionInfo.orgId,\n );\n }\n\n return {\n behavior: 'allow',\n updatedInput: input,\n };\n}\n\n/**\n * Tools that are automatically approved without user confirmation\n */\nconst AUTO_APPROVED_TOOLS = new Set([\n 'mcp__raindrop-wizard__CompleteIntegration',\n 'mcp__raindrop-wizard__LoadDocumentation',\n 'mcp__raindrop-wizard__InitializeSession',\n 'EnterPlanMode',\n]);\n\n/**\n * Patterns indicating a file path or glob likely targets secret/credential files.\n * Used to auto-deny Read/Glob/Grep operations on sensitive files.\n */\nconst SECRET_PATH_PATTERNS: RegExp[] = [\n /\\.env(\\.|$)/, // .env, .env.local, .env.production, etc.\n /\\bsecrets?\\b/i, // secrets.json, secret.yaml, etc.\n /\\bcredentials?\\b/i, // credentials.json, credential.yaml\n /private[._-]?key/i, // private_key.pem, privatekey.pem\n /\\.pem$/i, // PEM certificates/keys\n /\\.key$/i, // Key files (e.g. myapp.key, certificate.key)\n /\\.p12$/i, // PKCS12 keystores\n /\\.pfx$/i, // PFX keystores\n /\\bid_rsa\\b/, // SSH private keys\n /\\bid_ed25519\\b/, // SSH private keys\n /\\bid_ecdsa\\b/, // SSH private keys\n /\\.netrc$/, // .netrc files\n /serviceaccount.*\\.json$/i, // GCP service account keys\n];\n\nconst SECRET_PATH_ALLOWLIST: RegExp[] = [\n /\\.env\\.example$/, // .env.example is safe to read\n];\n\n/**\n * Returns true if a file path or glob pattern likely targets a secrets file.\n */\nfunction isSecretPath(value: string): boolean {\n if (SECRET_PATH_ALLOWLIST.some((re) => re.test(value))) return false;\n return SECRET_PATH_PATTERNS.some((re) => re.test(value));\n}\n\n/**\n * Check if a Read/Glob/Grep input targets a secrets file and should be denied.\n * For Grep, only the file-targeting fields (path, glob) are checked — not the\n * search pattern itself.\n */\nfunction targetsSecretFile(\n toolName: string,\n input: Record<string, unknown>,\n): boolean {\n if (toolName === 'Read' || toolName === 'Edit' || toolName === 'Write') {\n const filePath = typeof input.file_path === 'string'\n ? input.file_path\n : typeof input.path === 'string'\n ? input.path\n : '';\n return isSecretPath(filePath);\n }\n if (toolName === 'NotebookEdit') {\n const notebookPath =\n typeof input.notebook_path === 'string' ? input.notebook_path : '';\n return isSecretPath(notebookPath);\n }\n if (toolName === 'Glob') {\n const pattern = typeof input.pattern === 'string' ? input.pattern : '';\n const path = typeof input.path === 'string' ? input.path : '';\n return isSecretPath(pattern) || isSecretPath(path);\n }\n if (toolName === 'Grep') {\n const path = typeof input.path === 'string' ? input.path : '';\n const glob = typeof input.glob === 'string' ? input.glob : '';\n return isSecretPath(path) || isSecretPath(glob);\n }\n return false;\n}\n\n/**\n * Returns true if a bash command string references a secret/credential file.\n * Splits on shell delimiters and checks each token against SECRET_PATH_PATTERNS.\n */\nfunction bashCommandTargetsSecretFile(command: string): boolean {\n const tokens = command.split(/[\\s|;&<>]+/);\n for (const token of tokens) {\n // Strip surrounding quotes\n const cleaned = token.replace(/^['\"]|['\"]$/g, '');\n if (cleaned && !cleaned.startsWith('-') && isSecretPath(cleaned)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * PreToolUse hook that handles all silent auto-approve/deny decisions.\n * Fires for every tool call before canUseTool, so this is the right place\n * for decisions that don't require user interaction.\n * Returns { continue: true } for tools that need canUseTool (UI interaction).\n */\nexport function createPreToolUseHook(sessionInfo?: SessionInfo) {\n return async (input: HookInput): Promise<HookJSONOutput> => {\n if (input.hook_event_name !== 'PreToolUse') return { continue: true };\n const { tool_name, tool_input } = input;\n const inp = (tool_input ?? {}) as Record<string, unknown>;\n\n // Block secret file access for all relevant tools\n if (\n targetsSecretFile(tool_name, inp) ||\n (tool_name === 'Bash' &&\n typeof inp.command === 'string' &&\n bashCommandTargetsSecretFile(inp.command))\n ) {\n logToFile(\n `PreToolUse: blocking ${tool_name} - secret file pattern detected`,\n inp,\n );\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'deny',\n permissionDecisionReason:\n 'Reading or writing secret or credential files is not allowed.',\n },\n };\n }\n\n // Auto-approve internal MCP tools and EnterPlanMode\n if (AUTO_APPROVED_TOOLS.has(tool_name)) {\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'allow',\n },\n };\n }\n\n // Auto-approve read-only file tools\n if (tool_name === 'Read' || tool_name === 'Glob' || tool_name === 'Grep') {\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'allow',\n },\n };\n }\n\n // Auto-approve safe or session-approved bash commands\n if (tool_name === 'Bash' && typeof inp.command === 'string') {\n if (\n isSafeBashCommand(inp.command) ||\n isCommandApprovedForSession(inp.command)\n ) {\n logToFile('PreToolUse: auto-approving bash command:', inp.command);\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'allow',\n },\n };\n }\n }\n\n // Auto-approve WebSearch with domain restriction applied via updatedInput\n if (tool_name === 'WebSearch') {\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'allow',\n updatedInput: {\n ...inp,\n allowed_domains: ['raindrop.ai/docs', 'ai-sdk.dev/docs/'],\n },\n },\n };\n }\n\n // Auto-approve ExitPlanMode and fire session update\n if (tool_name === 'ExitPlanMode') {\n const planContent = typeof inp.plan === 'string' ? inp.plan : '';\n if (sessionInfo) {\n sendSessionUpdate(\n sessionInfo.sessionId,\n planContent,\n sessionInfo.accessToken,\n sessionInfo.orgId,\n );\n }\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'allow',\n permissionDecisionReason: 'System automatically approved.',\n },\n };\n }\n\n // Auto-approve edits to files that were already approved this session\n if (tool_name === 'Edit' || tool_name === 'Write') {\n const fileName =\n typeof inp.file_path === 'string'\n ? inp.file_path\n : typeof inp.path === 'string'\n ? inp.path\n : undefined;\n if (fileName && approvedFilesForSession.has(fileName)) {\n logToFile(\n 'PreToolUse: auto-approving edit to session-approved file:',\n fileName,\n );\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'allow',\n },\n };\n }\n }\n\n // Anything else needs user interaction — let canUseTool handle it\n return {};\n };\n}\n\n/**\n * Check if a bash command matches a safe pattern and can be auto-approved.\n */\nfunction isSafeBashCommand(command: string): boolean {\n const trimmed = command.trim();\n return SAFE_BASH_PATTERNS.some((pattern) => {\n if (pattern.startsWith('*')) {\n // Suffix match (e.g., '*--version')\n return trimmed.endsWith(pattern.slice(1));\n } else if (pattern.endsWith('*')) {\n // Prefix match (e.g., 'npm install*')\n return trimmed.startsWith(pattern.slice(0, -1));\n } else {\n // Exact match\n return trimmed === pattern;\n }\n });\n}\n\n/**\n * Create a canUseTool handler for tools that require user interaction.\n * Auto-approve/deny logic lives in createPreToolUseHook instead.\n * This handler is only reached for tools that PreToolUse passes through.\n */\nexport function createCanUseToolHandler(approvedFilesCache?: Set<string>) {\n return async (\n toolName: string,\n input: unknown,\n ): Promise<ToolApprovalResult> => {\n const inputRecord = input as Record<string, unknown>;\n logToFile('canUseTool called:', { toolName, input: inputRecord });\n\n // Handle AskUserQuestion specially\n if (toolName === 'AskUserQuestion') {\n return handleClarifyingQuestions(inputRecord);\n }\n\n // ExitPlanMode is auto-approved (session update already fired in PreToolUse hook)\n if (toolName === 'ExitPlanMode') {\n return { behavior: 'allow', updatedInput: inputRecord };\n }\n\n // Show approval UI for all other tools\n return handleToolApproval(toolName, inputRecord, approvedFilesCache);\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../../src/lib/handlers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tool approval handlers for the Claude agent\n * Handles UI integration for tool approvals and clarifying questions\n */\n\nimport type { HookInput, HookJSONOutput } from '@anthropic-ai/claude-agent-sdk';\nimport { createTwoFilesPatch } from 'diff';\nimport type { AgentQueryHandle, ToolApprovalResult } from '../ui/types.js';\nimport { logToFile } from '../utils/debug.js';\nimport { sendSessionUpdate } from '../utils/session.js';\nimport ui from '../utils/ui.js';\nimport { SAFE_BASH_PATTERNS } from './constants.js';\n\n// ============================================================================\n// Session-wide Approval Tracking\n// ============================================================================\n\n/**\n * Set of file paths that have been granted blanket approval for the session.\n * When a file is in this set, Edit/Write operations on it are auto-approved.\n */\nconst approvedFilesForSession = new Set<string>();\n\n/**\n * Set of command patterns that have been granted blanket approval for the session.\n * When a command matches a pattern in this set, Bash operations are auto-approved.\n * Patterns use simple prefix matching (e.g., \"npm install\" matches \"npm install axios\").\n */\nconst approvedCommandPatternsForSession = new Set<string>();\n\n/**\n * Clear all session-wide file approvals.\n * Useful when starting a new session or resetting permissions.\n */\nexport function clearApprovedFiles(): void {\n approvedFilesForSession.clear();\n logToFile('Cleared all approved files for session');\n}\n\n/**\n * Clear all session-wide command pattern approvals.\n * Useful when starting a new session or resetting permissions.\n */\nexport function clearApprovedCommandPatterns(): void {\n approvedCommandPatternsForSession.clear();\n logToFile('Cleared all approved command patterns for session');\n}\n\n/**\n * Get the list of currently approved files (for debugging/display purposes)\n */\nexport function getApprovedFiles(): string[] {\n return Array.from(approvedFilesForSession);\n}\n\n/**\n * Get the list of currently approved command patterns (for debugging/display purposes)\n */\nexport function getApprovedCommandPatterns(): string[] {\n return Array.from(approvedCommandPatternsForSession);\n}\n\n/**\n * Extract the command pattern from a bash command for session approval.\n * Returns the base command with the first argument(s) to match similar commands.\n * Examples:\n * \"npm install axios\" -> \"npm install\"\n * \"npm run build\" -> \"npm run\"\n * \"pip install requests\" -> \"pip install\"\n * \"yarn add lodash\" -> \"yarn add\"\n */\nfunction extractCommandPattern(command: string): string {\n const trimmed = command.trim();\n const parts = trimmed.split(/\\s+/);\n\n // For package managers with subcommands, include the subcommand\n if (parts.length >= 2) {\n const [cmd, subcmd] = parts;\n // Common package managers\n if (\n ['npm', 'yarn', 'bun', 'pip', 'pip3', 'poetry', 'cargo', 'go'].includes(\n cmd,\n )\n ) {\n return `${cmd} ${subcmd}`;\n }\n }\n\n // For other commands, just return the first part\n return parts[0] || trimmed;\n}\n\n/**\n * Check if a bash command matches any approved command pattern for the session.\n */\nfunction isCommandApprovedForSession(command: string): boolean {\n const pattern = extractCommandPattern(command);\n return approvedCommandPatternsForSession.has(pattern);\n}\n\n// ============================================================================\n// Pending Tool Call Types\n// ============================================================================\n\n/**\n * Pending tool call info stored while waiting for result\n */\nexport interface PendingToolCall {\n toolName: string;\n input: Record<string, unknown>;\n description?: string;\n /** ID of the 'executing' history item, used to update it on completion/interrupt */\n historyItemId?: number;\n}\n\n// ============================================================================\n// Agent Query Handle Factory\n// ============================================================================\n\n/**\n * Dependencies required for creating an AgentQueryHandle\n */\nexport interface AgentQueryHandleDeps {\n isInterruptingRef: { value: boolean };\n waitingForUserInputRef: { value: boolean };\n pendingToolCalls: Map<string, PendingToolCall>;\n getQueryObject: () => { interrupt?: () => Promise<void> } | null;\n sendMessage: (message: string) => void;\n}\n\n/**\n * Create an AgentQueryHandle for external control of the agent.\n * Handles interrupts by marking pending tool calls (keeps persistent input running).\n */\nexport function createAgentQueryHandle(\n deps: AgentQueryHandleDeps,\n): AgentQueryHandle {\n const {\n isInterruptingRef,\n waitingForUserInputRef,\n pendingToolCalls,\n getQueryObject,\n sendMessage,\n } = deps;\n\n return {\n interrupt: async (fromUserMessage?: boolean) => {\n logToFile('Soft interrupt requested (Esc)');\n\n // If already interrupted, don't add another \"Interrupted\" item\n if (isInterruptingRef.value || waitingForUserInputRef.value) {\n logToFile('Already interrupted - ignoring duplicate interrupt request');\n return;\n }\n\n isInterruptingRef.value = true;\n waitingForUserInputRef.value = true;\n\n // Mark all pending tool calls as interrupted and show them in history\n if (pendingToolCalls.size > 0) {\n for (const [toolUseId, pendingCall] of pendingToolCalls) {\n const interruptedToolCall = {\n toolName: pendingCall.toolName,\n status: 'interrupted' as const,\n input: pendingCall.input,\n description: pendingCall.description,\n };\n if (pendingCall.historyItemId !== undefined) {\n ui.updateItem(pendingCall.historyItemId, {\n type: 'tool-call',\n text: pendingCall.toolName,\n toolCall: interruptedToolCall,\n });\n } else {\n ui.addItem({\n type: 'tool-call',\n text: pendingCall.toolName,\n toolCall: interruptedToolCall,\n });\n }\n pendingToolCalls.delete(toolUseId);\n }\n } else if (!fromUserMessage) {\n // No pending tool calls and not interrupted by a user message - show generic indicator\n ui.addItem({\n type: 'error',\n text: 'Interrupted',\n });\n }\n\n // Note: Don't stop persistent input here - keep it visible for user to type their message\n // The spinner will be stopped separately, and the input remains for user to submit\n\n // Call SDK interrupt\n const queryObject = getQueryObject();\n if (queryObject?.interrupt) {\n logToFile('Calling queryObject.interrupt()');\n await queryObject.interrupt();\n logToFile('queryObject.interrupt() completed');\n } else {\n logToFile('No queryObject.interrupt available');\n }\n },\n sendMessage: (message: string) => {\n const trimmedMessage = message.trim();\n if (!trimmedMessage) {\n return;\n }\n logToFile('Queueing user message for active session');\n sendMessage(trimmedMessage);\n },\n };\n}\n\n// ============================================================================\n// Enhanced canUseTool Handler with UI Integration\n// ============================================================================\n\n/**\n * Generate a unified diff for Edit tool inputs (old_string -> new_string)\n */\nfunction generateEditDiff(\n filePath: string,\n oldString: string,\n newString: string,\n): string {\n // createTwoFilesPatch generates a unified diff\n return createTwoFilesPatch(\n filePath,\n filePath,\n oldString,\n newString,\n '', // old header\n '', // new header\n { context: 3 }, // context lines\n );\n}\n\n/**\n * Handle tool approval request by showing approval UI\n */\nasync function handleToolApproval(\n toolName: string,\n input: Record<string, unknown>,\n approvedFilesCache?: Set<string>,\n): Promise<ToolApprovalResult> {\n logToFile('Showing tool approval UI:', { toolName, input });\n\n // Extract file path\n const fileName =\n typeof input.file_path === 'string'\n ? input.file_path\n : typeof input.path === 'string'\n ? input.path\n : undefined;\n\n // Check if this file has been approved for all edits\n if (\n approvedFilesCache &&\n fileName &&\n (toolName === 'Edit' || toolName === 'Write') &&\n approvedFilesCache.has(fileName)\n ) {\n logToFile('Auto-approving edit to previously approved file:', fileName);\n return {\n behavior: 'allow',\n updatedInput: input,\n };\n }\n\n // Stop spinner while waiting for user approval\n const spinner = ui.spinner();\n spinner.stop();\n\n // Generate diff content for file modification tools\n let diffContent: string | undefined;\n if (\n toolName === 'Edit' &&\n typeof input.old_string === 'string' &&\n typeof input.new_string === 'string' &&\n fileName\n ) {\n // Edit: show old -> new diff\n diffContent = generateEditDiff(\n fileName,\n input.old_string,\n input.new_string,\n );\n } else if (\n toolName === 'Write' &&\n typeof input.content === 'string' &&\n fileName\n ) {\n // Write: show content as all additions (empty -> content)\n diffContent = generateEditDiff(fileName, '', input.content);\n } else if (typeof input.file_diff === 'string') {\n // Use pre-generated diff if available\n diffContent = input.file_diff;\n }\n\n // Build props for the approval prompt\n const props = {\n toolName,\n input,\n description:\n typeof input.description === 'string' ? input.description : undefined,\n diffContent,\n fileName,\n };\n\n try {\n const result = await ui.toolApproval(props);\n logToFile('Tool approval result:', result);\n\n // If user chose \"allow all edits to this file\", add to both caches\n if (\n result.behavior === 'allow' &&\n 'allowAllForFile' in result &&\n result.allowAllForFile\n ) {\n approvedFilesForSession.add(result.allowAllForFile);\n logToFile('Added file to approved list:', result.allowAllForFile);\n }\n if (\n result.behavior === 'allow' &&\n result.allowAllEdits &&\n fileName &&\n approvedFilesCache\n ) {\n logToFile('Adding file to approved files cache:', fileName);\n approvedFilesCache.add(fileName);\n }\n\n // If user selected \"allow all for this command pattern\", add to approved set\n if (\n result.behavior === 'allow' &&\n 'allowAllForCommandPattern' in result &&\n result.allowAllForCommandPattern\n ) {\n approvedCommandPatternsForSession.add(result.allowAllForCommandPattern);\n logToFile(\n 'Added command pattern to approved list:',\n result.allowAllForCommandPattern,\n );\n }\n\n // Restart spinner after user responds\n spinner.start();\n\n return result;\n } catch (error) {\n logToFile('Error in tool approval:', error);\n return {\n behavior: 'deny',\n message: 'Failed to get user approval',\n };\n }\n}\n\n/**\n * Handle the AskUserQuestion tool by showing clarifying questions UI.\n * Input already contains { questions: [...] } in the correct format.\n * Returns { questions, answers } as expected by the SDK.\n */\nasync function handleClarifyingQuestions(\n input: Record<string, unknown>,\n): Promise<ToolApprovalResult> {\n logToFile('Handling AskUserQuestion:', input);\n\n // Stop spinner while waiting for user input\n const spinner = ui.spinner();\n spinner.stop();\n\n try {\n // Input is already in ClarifyingQuestionsProps format\n const result = await ui.clarifyingQuestions(input as any);\n logToFile('Clarifying questions result:', result);\n\n // Restart spinner after user responds\n spinner.start();\n\n // Return questions + answers as expected by SDK\n return {\n behavior: 'allow',\n updatedInput: {\n questions: result.questions,\n answers: result.answers,\n },\n };\n } catch (error) {\n logToFile('Error in clarifying questions:', error);\n return {\n behavior: 'deny',\n message: 'Failed to get user answers',\n };\n }\n}\n\n/**\n * Session info for notifications\n */\nexport interface SessionInfo {\n sessionId: string;\n accessToken: string;\n orgId: string;\n}\n\n/**\n * Handle the ExitPlanMode tool by showing plan approval UI.\n * Input contains { plan: \"...\" } with the plan in markdown format.\n * If user approves, returns allow. If user rejects, returns deny with feedback.\n */\nasync function handlePlanApproval(\n input: Record<string, unknown>,\n sessionInfo?: SessionInfo,\n): Promise<ToolApprovalResult> {\n logToFile('Handling ExitPlanMode:', input);\n\n const planContent = typeof input.plan === 'string' ? input.plan : '';\n\n // Send session update with plan content\n if (sessionInfo) {\n sendSessionUpdate(\n sessionInfo.sessionId,\n planContent,\n sessionInfo.accessToken,\n sessionInfo.orgId,\n );\n }\n\n return {\n behavior: 'allow',\n updatedInput: input,\n };\n}\n\n/** Prefix for MCP tools (e.g. mcp__server__tool or mcp____server____tool). All are auto-approved and not shown in approval UI. */\nconst MCP_TOOL_PREFIX = 'mcp__';\n\n/**\n * Tools that are automatically approved without user confirmation.\n * MCP tools (name starts with mcp__) are approved via wildcard in PreToolUse.\n */\nconst AUTO_APPROVED_TOOLS = new Set(['EnterPlanMode']);\n\n/**\n * Patterns indicating a file path or glob likely targets secret/credential files.\n * Used to auto-deny Read/Glob/Grep operations on sensitive files.\n */\nconst SECRET_PATH_PATTERNS: RegExp[] = [\n /\\.env(\\.|$)/, // .env, .env.local, .env.production, etc.\n /\\bsecrets?\\b/i, // secrets.json, secret.yaml, etc.\n /\\bcredentials?\\b/i, // credentials.json, credential.yaml\n /private[._-]?key/i, // private_key.pem, privatekey.pem\n /\\.pem$/i, // PEM certificates/keys\n /\\.key$/i, // Key files (e.g. myapp.key, certificate.key)\n /\\.p12$/i, // PKCS12 keystores\n /\\.pfx$/i, // PFX keystores\n /\\bid_rsa\\b/, // SSH private keys\n /\\bid_ed25519\\b/, // SSH private keys\n /\\bid_ecdsa\\b/, // SSH private keys\n /\\.netrc$/, // .netrc files\n /serviceaccount.*\\.json$/i, // GCP service account keys\n];\n\nconst SECRET_PATH_ALLOWLIST: RegExp[] = [\n /\\.env\\.example$/, // .env.example is safe to read\n];\n\n/**\n * Returns true if a file path or glob pattern likely targets a secrets file.\n */\nfunction isSecretPath(value: string): boolean {\n if (SECRET_PATH_ALLOWLIST.some((re) => re.test(value))) return false;\n return SECRET_PATH_PATTERNS.some((re) => re.test(value));\n}\n\n/**\n * Check if a Read/Glob/Grep input targets a secrets file and should be denied.\n * For Grep, only the file-targeting fields (path, glob) are checked — not the\n * search pattern itself.\n */\nfunction targetsSecretFile(\n toolName: string,\n input: Record<string, unknown>,\n): boolean {\n if (toolName === 'Read' || toolName === 'Edit' || toolName === 'Write') {\n const filePath =\n typeof input.file_path === 'string'\n ? input.file_path\n : typeof input.path === 'string'\n ? input.path\n : '';\n return isSecretPath(filePath);\n }\n if (toolName === 'NotebookEdit') {\n const notebookPath =\n typeof input.notebook_path === 'string' ? input.notebook_path : '';\n return isSecretPath(notebookPath);\n }\n if (toolName === 'Glob') {\n const pattern = typeof input.pattern === 'string' ? input.pattern : '';\n const path = typeof input.path === 'string' ? input.path : '';\n return isSecretPath(pattern) || isSecretPath(path);\n }\n if (toolName === 'Grep') {\n const path = typeof input.path === 'string' ? input.path : '';\n const glob = typeof input.glob === 'string' ? input.glob : '';\n return isSecretPath(path) || isSecretPath(glob);\n }\n return false;\n}\n\n/**\n * Returns true if a bash command string references a secret/credential file.\n * Splits on shell delimiters and checks each token against SECRET_PATH_PATTERNS.\n */\nfunction bashCommandTargetsSecretFile(command: string): boolean {\n const tokens = command.split(/[\\s|;&<>]+/);\n for (const token of tokens) {\n // Strip surrounding quotes\n const cleaned = token.replace(/^['\"]|['\"]$/g, '');\n if (cleaned && !cleaned.startsWith('-') && isSecretPath(cleaned)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * PreToolUse hook that handles all silent auto-approve/deny decisions.\n * Fires for every tool call before canUseTool, so this is the right place\n * for decisions that don't require user interaction.\n * Returns { continue: true } for tools that need canUseTool (UI interaction).\n */\nexport function createPreToolUseHook(sessionInfo?: SessionInfo) {\n return async (input: HookInput): Promise<HookJSONOutput> => {\n if (input.hook_event_name !== 'PreToolUse') return { continue: true };\n const { tool_name, tool_input } = input;\n const inp = (tool_input ?? {}) as Record<string, unknown>;\n\n // Block secret file access for all relevant tools\n if (\n targetsSecretFile(tool_name, inp) ||\n (tool_name === 'Bash' &&\n typeof inp.command === 'string' &&\n bashCommandTargetsSecretFile(inp.command))\n ) {\n logToFile(\n `PreToolUse: blocking ${tool_name} - secret file pattern detected`,\n inp,\n );\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'deny',\n permissionDecisionReason:\n 'Reading or writing secret or credential files is not allowed.',\n },\n };\n }\n\n // Auto-approve all MCP tools (mcp__*) and EnterPlanMode — no approval UI\n if (\n tool_name.startsWith(MCP_TOOL_PREFIX) ||\n AUTO_APPROVED_TOOLS.has(tool_name)\n ) {\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'allow',\n },\n };\n }\n\n // Auto-approve read-only file tools\n if (tool_name === 'Read' || tool_name === 'Glob' || tool_name === 'Grep') {\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'allow',\n },\n };\n }\n\n // Auto-approve safe or session-approved bash commands\n if (tool_name === 'Bash' && typeof inp.command === 'string') {\n if (\n isSafeBashCommand(inp.command) ||\n isCommandApprovedForSession(inp.command)\n ) {\n logToFile('PreToolUse: auto-approving bash command:', inp.command);\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'allow',\n },\n };\n }\n }\n\n // Auto-approve WebSearch with domain restriction applied via updatedInput\n if (tool_name === 'WebSearch') {\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'allow',\n updatedInput: {\n ...inp,\n allowed_domains: ['raindrop.ai/docs', 'ai-sdk.dev/docs/'],\n },\n },\n };\n }\n\n // Auto-approve ExitPlanMode and fire session update\n if (tool_name === 'ExitPlanMode') {\n const planContent = typeof inp.plan === 'string' ? inp.plan : '';\n if (sessionInfo) {\n sendSessionUpdate(\n sessionInfo.sessionId,\n planContent,\n sessionInfo.accessToken,\n sessionInfo.orgId,\n );\n }\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'allow',\n permissionDecisionReason: 'System automatically approved.',\n },\n };\n }\n\n // Auto-approve edits to files that were already approved this session\n if (tool_name === 'Edit' || tool_name === 'Write') {\n const fileName =\n typeof inp.file_path === 'string'\n ? inp.file_path\n : typeof inp.path === 'string'\n ? inp.path\n : undefined;\n if (fileName && approvedFilesForSession.has(fileName)) {\n logToFile(\n 'PreToolUse: auto-approving edit to session-approved file:',\n fileName,\n );\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'allow',\n },\n };\n }\n }\n\n // Anything else needs user interaction — let canUseTool handle it\n return {};\n };\n}\n\n/**\n * Check if a bash command matches a safe pattern and can be auto-approved.\n */\nfunction isSafeBashCommand(command: string): boolean {\n const trimmed = command.trim();\n return SAFE_BASH_PATTERNS.some((pattern) => {\n if (pattern.startsWith('*')) {\n // Suffix match (e.g., '*--version')\n return trimmed.endsWith(pattern.slice(1));\n } else if (pattern.endsWith('*')) {\n // Prefix match (e.g., 'npm install*')\n return trimmed.startsWith(pattern.slice(0, -1));\n } else {\n // Exact match\n return trimmed === pattern;\n }\n });\n}\n\n/**\n * Create a canUseTool handler for tools that require user interaction.\n * Auto-approve/deny logic lives in createPreToolUseHook instead.\n * This handler is only reached for tools that PreToolUse passes through.\n */\nexport function createCanUseToolHandler(approvedFilesCache?: Set<string>) {\n return async (\n toolName: string,\n input: unknown,\n ): Promise<ToolApprovalResult> => {\n const inputRecord = input as Record<string, unknown>;\n logToFile('canUseTool called:', { toolName, input: inputRecord });\n\n // Handle AskUserQuestion specially\n if (toolName === 'AskUserQuestion') {\n return handleClarifyingQuestions(inputRecord);\n }\n\n // ExitPlanMode is auto-approved (session update already fired in PreToolUse hook)\n if (toolName === 'ExitPlanMode') {\n return { behavior: 'allow', updatedInput: inputRecord };\n }\n\n // Show approval UI for all other tools\n return handleToolApproval(toolName, inputRecord, approvedFilesCache);\n };\n}\n"]}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* SDK message processing utilities
|
|
3
3
|
* Handles parsing and displaying SDK messages from the Claude agent
|
|
4
4
|
*/
|
|
5
|
-
import type { PendingToolCall } from './handlers.js';
|
|
6
5
|
import type { WizardOptions } from '../utils/types.js';
|
|
6
|
+
import type { PendingToolCall } from './handlers.js';
|
|
7
7
|
type SDKMessage = any;
|
|
8
8
|
/**
|
|
9
9
|
* Extract result summary from tool result content
|
|
@@ -2,20 +2,22 @@
|
|
|
2
2
|
* SDK message processing utilities
|
|
3
3
|
* Handles parsing and displaying SDK messages from the Claude agent
|
|
4
4
|
*/
|
|
5
|
-
import ui from '../utils/ui.js';
|
|
6
|
-
import { debug, logToFile } from '../utils/debug.js';
|
|
7
5
|
import { createTwoFilesPatch } from 'diff';
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
import { debug, logToFile } from '../utils/debug.js';
|
|
7
|
+
import ui from '../utils/ui.js';
|
|
8
|
+
/** Internal SDK tools that should not be stored/displayed in the UI */
|
|
9
|
+
const INTERNAL_TOOL_NAMES = new Set([
|
|
10
10
|
'Task',
|
|
11
11
|
'AskUserQuestion',
|
|
12
12
|
'TodoWrite',
|
|
13
|
-
'mcp__raindrop-wizard__CompleteIntegration',
|
|
14
|
-
'mcp__raindrop-wizard__LoadDocumentation',
|
|
15
|
-
'mcp__raindrop-wizard__InitializeSession',
|
|
16
13
|
'EnterPlanMode',
|
|
17
14
|
'ExitPlanMode',
|
|
18
15
|
]);
|
|
16
|
+
/** Prefix for MCP tools; all are internal (not shown in UI). Matches mcp__server__tool and mcp____... */
|
|
17
|
+
const MCP_TOOL_PREFIX = 'mcp__';
|
|
18
|
+
function isInternalTool(toolName) {
|
|
19
|
+
return (INTERNAL_TOOL_NAMES.has(toolName) || toolName.startsWith(MCP_TOOL_PREFIX));
|
|
20
|
+
}
|
|
19
21
|
/**
|
|
20
22
|
* Generate a unified diff for Edit tool inputs (old_string -> new_string)
|
|
21
23
|
*/
|
|
@@ -188,8 +190,8 @@ export function processSDKMessage(message, options, collectedText, pendingToolCa
|
|
|
188
190
|
const toolInput = block.input || {};
|
|
189
191
|
const toolUseId = block.id;
|
|
190
192
|
logToFile(`Tool use requested: ${toolName} (id: ${toolUseId})`, toolInput);
|
|
191
|
-
// Skip storing/displaying internal SDK tools
|
|
192
|
-
if (
|
|
193
|
+
// Skip storing/displaying internal SDK tools (including all mcp__* tools)
|
|
194
|
+
if (isInternalTool(toolName)) {
|
|
193
195
|
continue;
|
|
194
196
|
}
|
|
195
197
|
// Show tool as executing immediately (pretooluse)
|
|
@@ -252,7 +254,9 @@ export function processSDKMessage(message, options, collectedText, pendingToolCa
|
|
|
252
254
|
description: pendingCall.description,
|
|
253
255
|
result: resultSummary,
|
|
254
256
|
error: isError
|
|
255
|
-
? `Error: ${String(resultContent)
|
|
257
|
+
? `Error: ${String(resultContent)
|
|
258
|
+
.replace(/<\/?tool_use_error>/g, '')
|
|
259
|
+
.trim()}`
|
|
256
260
|
: undefined,
|
|
257
261
|
diffContent,
|
|
258
262
|
fileName,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-messages.js","sourceRoot":"","sources":["../../../src/lib/sdk-messages.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SDK message processing utilities\n * Handles parsing and displaying SDK messages from the Claude agent\n */\n\nimport ui from '../utils/ui.js';\nimport { debug, logToFile } from '../utils/debug.js';\nimport type { PendingToolCall } from './handlers.js';\nimport type { WizardOptions } from '../utils/types.js';\nimport { createTwoFilesPatch } from 'diff';\n\n// Using `any` because typed imports from ESM modules require import attributes\n// syntax which prettier cannot parse.\ntype SDKMessage = any;\n\n/** Internal SDK tools that should not be stored/displayed */\nconst INTERNAL_TOOLS = new Set([\n 'Task',\n 'AskUserQuestion',\n 'TodoWrite',\n 'mcp__raindrop-wizard__CompleteIntegration',\n 'mcp__raindrop-wizard__LoadDocumentation',\n 'mcp__raindrop-wizard__InitializeSession',\n 'EnterPlanMode',\n 'ExitPlanMode',\n]);\n\n/**\n * Generate a unified diff for Edit tool inputs (old_string -> new_string)\n */\nfunction generateEditDiff(\n filePath: string,\n oldString: string,\n newString: string,\n): string {\n return createTwoFilesPatch(\n filePath,\n filePath,\n oldString,\n newString,\n '', // old header\n '', // new header\n { context: 3 }, // context lines\n );\n}\n\n/**\n * Extract summary for Edit tool (line changes)\n */\nfunction extractEditSummary(input: Record<string, unknown>): string {\n const oldString =\n typeof input.old_string === 'string' ? input.old_string : '';\n const newString =\n typeof input.new_string === 'string' ? input.new_string : '';\n\n const oldLines = oldString ? oldString.split('\\n').length : 0;\n const newLines = newString ? newString.split('\\n').length : 0;\n\n const added = Math.max(0, newLines - oldLines);\n const removed = Math.max(0, oldLines - newLines);\n\n // Handle the case where lines are replaced (same count but different content)\n if (added === 0 && removed === 0 && oldString !== newString) {\n return `Updated ${oldLines} line${oldLines === 1 ? '' : 's'}`;\n }\n\n const parts: string[] = [];\n if (added > 0) parts.push(`Added ${added} line${added === 1 ? '' : 's'}`);\n if (removed > 0)\n parts.push(`removed ${removed} line${removed === 1 ? '' : 's'}`);\n\n return parts.length > 0 ? parts.join(', ') : 'No changes';\n}\n\n/**\n * Extract summary for Write tool (lines written)\n */\nfunction extractWriteSummary(input: Record<string, unknown>): string {\n const content = typeof input.content === 'string' ? input.content : '';\n const lines = content ? content.split('\\n').length : 0;\n const fileName =\n typeof input.path === 'string' ? input.path.split('/').pop() : 'file';\n return `Wrote ${lines} line${lines === 1 ? '' : 's'} to ${fileName}`;\n}\n\n/**\n * Generate diff content and file name for Edit/Write tools\n */\nfunction extractEditWriteInfo(\n toolName: string,\n input: Record<string, unknown>,\n): { diffContent?: string; fileName?: string } {\n const fileName =\n typeof input.file_path === 'string'\n ? input.file_path\n : typeof input.path === 'string'\n ? input.path\n : undefined;\n\n if (toolName === 'Edit' && fileName) {\n const oldString =\n typeof input.old_string === 'string' ? input.old_string : '';\n const newString =\n typeof input.new_string === 'string' ? input.new_string : '';\n const diffContent = generateEditDiff(fileName, oldString, newString);\n return { diffContent, fileName };\n }\n\n if (toolName === 'Write' && fileName) {\n const content = typeof input.content === 'string' ? input.content : '';\n const diffContent = generateEditDiff(fileName, '', content);\n return { diffContent, fileName };\n }\n\n return {};\n}\n\n/**\n * Extract result summary from tool result content\n */\nexport function extractResultSummary(\n toolName: string,\n resultContent: unknown,\n input?: Record<string, unknown>,\n): string | undefined {\n // Handle string content\n const content =\n typeof resultContent === 'string'\n ? resultContent\n : Array.isArray(resultContent)\n ? resultContent.map((c: any) => c.text || '').join('\\n')\n : '';\n\n if (!content) return undefined;\n\n switch (toolName) {\n case 'Glob': {\n // Count non-empty lines (each line is a file path)\n const lines = content\n .trim()\n .split('\\n')\n .filter((l: string) => l.trim());\n return `Found ${lines.length} files`;\n }\n case 'Read': {\n // Count lines in the file content\n const lineCount = content.split('\\n').length;\n return `Read ${lineCount} lines`;\n }\n case 'Grep': {\n // Count match lines\n const lines = content\n .trim()\n .split('\\n')\n .filter((l: string) => l.trim());\n return `Found ${lines.length} matches`;\n }\n case 'Edit': {\n if (input) {\n return extractEditSummary(input);\n }\n return undefined;\n }\n case 'Write': {\n if (input) {\n return extractWriteSummary(input);\n }\n return undefined;\n }\n default:\n return undefined;\n }\n}\n\n/**\n * Build a contextual spinner message based on the completed tool call.\n */\nfunction getToolSpinnerMessage(\n toolName: string,\n input: Record<string, unknown>,\n): string {\n switch (toolName) {\n case 'Grep':\n return `Analysing results`;\n case 'Read':\n return `Analysing`;\n case 'Bash':\n return `Analysing output`;\n case 'Edit':\n case 'Write':\n return `Working`;\n case 'Glob':\n return `Browsing files`;\n case 'WebSearch':\n return `Searching the web`;\n case 'WebFetch':\n return `Fetching documentation`;\n case 'EnterPlanMode':\n return `Planning`;\n default:\n if (toolName.startsWith('mcp__raindrop-wizard__Load')) {\n return `Loading Raindrop documentation`;\n }\n return `Working`;\n }\n}\n\n/**\n * Context passed into processSDKMessage for spinner updates.\n */\nexport interface SDKMessageContext {\n updateSpinner: (msg: string) => void;\n baseSpinnerMessage: string;\n}\n\n/**\n * Process SDK messages and provide user feedback.\n * Handles assistant text, tool use, tool results, and system messages.\n */\nexport function processSDKMessage(\n message: SDKMessage,\n options: WizardOptions,\n collectedText: string[],\n pendingToolCalls: Map<string, PendingToolCall>,\n isInterrupting: boolean,\n context?: SDKMessageContext,\n): void {\n logToFile(`SDK Message: ${message.type}`, JSON.stringify(message, null, 2));\n\n if (options.debug) {\n debug(`SDK Message type: ${message.type}`);\n }\n\n switch (message.type) {\n case 'assistant': {\n // Extract text content from assistant messages\n const content = message.message?.content;\n if (Array.isArray(content)) {\n for (const block of content) {\n if (block.type === 'text' && typeof block.text === 'string') {\n collectedText.push(block.text);\n\n // Add agent message to history for visibility\n ui.addItem({\n type: 'agent-message',\n text: block.text,\n });\n\n // Reset spinner after assistant responds — \"Analysing\" after \"Perfect!\" looks wrong\n if (context?.updateSpinner) {\n context.updateSpinner(context.baseSpinnerMessage);\n }\n }\n // Handle tool_use blocks - store pending, don't add to history yet\n if (block.type === 'tool_use') {\n const toolName = block.name || 'Unknown tool';\n const toolInput = block.input || {};\n const toolUseId = block.id;\n logToFile(\n `Tool use requested: ${toolName} (id: ${toolUseId})`,\n toolInput,\n );\n\n // Skip storing/displaying internal SDK tools\n if (INTERNAL_TOOLS.has(toolName)) {\n continue;\n }\n\n // Show tool as executing immediately (pretooluse)\n const historyItemId = ui.addItem({\n type: 'tool-call',\n text: toolName,\n toolCall: {\n toolName,\n status: 'executing',\n input: toolInput,\n description:\n typeof toolInput.description === 'string'\n ? toolInput.description\n : undefined,\n },\n });\n\n // Store pending tool call with history ID so we can update it on completion\n pendingToolCalls.set(toolUseId, {\n toolName,\n input: toolInput,\n description:\n typeof toolInput.description === 'string'\n ? toolInput.description\n : undefined,\n historyItemId,\n });\n }\n }\n }\n break;\n }\n\n case 'user': {\n // Tool results come as 'user' messages with tool_result content\n const content = message.message?.content;\n if (Array.isArray(content)) {\n for (const block of content) {\n if (block.type === 'tool_result') {\n const toolUseId = block.tool_use_id;\n const isError = block.is_error === true;\n const resultContent = block.content;\n\n logToFile(`Tool result for ${toolUseId}:`, {\n isError,\n content: resultContent,\n });\n\n // Look up the pending tool call\n const pendingCall = pendingToolCalls.get(toolUseId);\n if (pendingCall) {\n pendingToolCalls.delete(toolUseId);\n\n // Extract diff content and file name for Edit/Write tools\n const { diffContent, fileName } = extractEditWriteInfo(\n pendingCall.toolName,\n pendingCall.input,\n );\n\n // Skip displaying tool calls for plan files\n if (fileName && fileName.includes('plans/')) {\n continue;\n }\n\n // Extract result summary based on tool type\n const resultSummary = extractResultSummary(\n pendingCall.toolName,\n resultContent,\n pendingCall.input,\n );\n\n // Update the existing 'executing' history item with the final result (posttooluse)\n const completedToolCall = {\n toolName: pendingCall.toolName,\n status: (isError ? 'error' : 'success') as 'error' | 'success',\n input: pendingCall.input,\n description: pendingCall.description,\n result: resultSummary,\n error: isError\n ? `Error: ${String(resultContent).replace(/<\\/?tool_use_error>/g, '').trim()}`\n : undefined,\n diffContent,\n fileName,\n };\n if (pendingCall.historyItemId !== undefined) {\n ui.updateItem(pendingCall.historyItemId, {\n type: 'tool-call',\n text: pendingCall.toolName,\n toolCall: completedToolCall,\n });\n } else {\n ui.addItem({\n type: 'tool-call',\n text: pendingCall.toolName,\n toolCall: completedToolCall,\n });\n }\n\n // Update spinner with contextual message after tool completes (skip errors)\n if (!isError && context?.updateSpinner) {\n context.updateSpinner(\n getToolSpinnerMessage(pendingCall.toolName, pendingCall.input),\n );\n }\n }\n\n if (isError && options.debug) {\n debug(`Tool error: ${resultContent}`);\n }\n }\n }\n }\n break;\n }\n\n case 'result': {\n if (message.subtype === 'success') {\n logToFile('Agent completed successfully');\n if (typeof message.result === 'string') {\n collectedText.push(message.result);\n // Note: We intentionally don't display the result message here.\n // The SDK's result.result field contains the same text as the last\n // assistant message, which we already render above. Displaying both\n // would cause duplicate output in the UI.\n }\n } else {\n // Error result - suppress if it's an interrupt-related error\n logToFile('Agent error result:', message.subtype);\n if (message.errors && !isInterrupting) {\n for (const err of message.errors) {\n // Check if error is interrupt-related\n const errStr = String(err);\n const isInterruptError =\n errStr.includes('aborted') ||\n errStr.includes('interrupted') ||\n errStr.includes('403');\n if (!isInterruptError) {\n ui.addItem({ type: 'error', text: `Error: ${err}` });\n }\n logToFile('ERROR:', err);\n }\n }\n }\n break;\n }\n\n case 'system': {\n if (message.subtype === 'init') {\n logToFile('Agent session initialized', {\n model: message.model,\n tools: message.tools?.length,\n });\n }\n break;\n }\n\n default:\n // Log other message types for debugging\n if (options.debug) {\n debug(`Unhandled message type: ${message.type}`);\n }\n break;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sdk-messages.js","sourceRoot":"","sources":["../../../src/lib/sdk-messages.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SDK message processing utilities\n * Handles parsing and displaying SDK messages from the Claude agent\n */\n\nimport { createTwoFilesPatch } from 'diff';\nimport { debug, logToFile } from '../utils/debug.js';\nimport type { WizardOptions } from '../utils/types.js';\nimport ui from '../utils/ui.js';\nimport type { PendingToolCall } from './handlers.js';\n\n// Using `any` because typed imports from ESM modules require import attributes\n// syntax which prettier cannot parse.\ntype SDKMessage = any;\n\n/** Internal SDK tools that should not be stored/displayed in the UI */\nconst INTERNAL_TOOL_NAMES = new Set([\n 'Task',\n 'AskUserQuestion',\n 'TodoWrite',\n 'EnterPlanMode',\n 'ExitPlanMode',\n]);\n\n/** Prefix for MCP tools; all are internal (not shown in UI). Matches mcp__server__tool and mcp____... */\nconst MCP_TOOL_PREFIX = 'mcp__';\n\nfunction isInternalTool(toolName: string): boolean {\n return (\n INTERNAL_TOOL_NAMES.has(toolName) || toolName.startsWith(MCP_TOOL_PREFIX)\n );\n}\n\n/**\n * Generate a unified diff for Edit tool inputs (old_string -> new_string)\n */\nfunction generateEditDiff(\n filePath: string,\n oldString: string,\n newString: string,\n): string {\n return createTwoFilesPatch(\n filePath,\n filePath,\n oldString,\n newString,\n '', // old header\n '', // new header\n { context: 3 }, // context lines\n );\n}\n\n/**\n * Extract summary for Edit tool (line changes)\n */\nfunction extractEditSummary(input: Record<string, unknown>): string {\n const oldString =\n typeof input.old_string === 'string' ? input.old_string : '';\n const newString =\n typeof input.new_string === 'string' ? input.new_string : '';\n\n const oldLines = oldString ? oldString.split('\\n').length : 0;\n const newLines = newString ? newString.split('\\n').length : 0;\n\n const added = Math.max(0, newLines - oldLines);\n const removed = Math.max(0, oldLines - newLines);\n\n // Handle the case where lines are replaced (same count but different content)\n if (added === 0 && removed === 0 && oldString !== newString) {\n return `Updated ${oldLines} line${oldLines === 1 ? '' : 's'}`;\n }\n\n const parts: string[] = [];\n if (added > 0) parts.push(`Added ${added} line${added === 1 ? '' : 's'}`);\n if (removed > 0)\n parts.push(`removed ${removed} line${removed === 1 ? '' : 's'}`);\n\n return parts.length > 0 ? parts.join(', ') : 'No changes';\n}\n\n/**\n * Extract summary for Write tool (lines written)\n */\nfunction extractWriteSummary(input: Record<string, unknown>): string {\n const content = typeof input.content === 'string' ? input.content : '';\n const lines = content ? content.split('\\n').length : 0;\n const fileName =\n typeof input.path === 'string' ? input.path.split('/').pop() : 'file';\n return `Wrote ${lines} line${lines === 1 ? '' : 's'} to ${fileName}`;\n}\n\n/**\n * Generate diff content and file name for Edit/Write tools\n */\nfunction extractEditWriteInfo(\n toolName: string,\n input: Record<string, unknown>,\n): { diffContent?: string; fileName?: string } {\n const fileName =\n typeof input.file_path === 'string'\n ? input.file_path\n : typeof input.path === 'string'\n ? input.path\n : undefined;\n\n if (toolName === 'Edit' && fileName) {\n const oldString =\n typeof input.old_string === 'string' ? input.old_string : '';\n const newString =\n typeof input.new_string === 'string' ? input.new_string : '';\n const diffContent = generateEditDiff(fileName, oldString, newString);\n return { diffContent, fileName };\n }\n\n if (toolName === 'Write' && fileName) {\n const content = typeof input.content === 'string' ? input.content : '';\n const diffContent = generateEditDiff(fileName, '', content);\n return { diffContent, fileName };\n }\n\n return {};\n}\n\n/**\n * Extract result summary from tool result content\n */\nexport function extractResultSummary(\n toolName: string,\n resultContent: unknown,\n input?: Record<string, unknown>,\n): string | undefined {\n // Handle string content\n const content =\n typeof resultContent === 'string'\n ? resultContent\n : Array.isArray(resultContent)\n ? resultContent.map((c: any) => c.text || '').join('\\n')\n : '';\n\n if (!content) return undefined;\n\n switch (toolName) {\n case 'Glob': {\n // Count non-empty lines (each line is a file path)\n const lines = content\n .trim()\n .split('\\n')\n .filter((l: string) => l.trim());\n return `Found ${lines.length} files`;\n }\n case 'Read': {\n // Count lines in the file content\n const lineCount = content.split('\\n').length;\n return `Read ${lineCount} lines`;\n }\n case 'Grep': {\n // Count match lines\n const lines = content\n .trim()\n .split('\\n')\n .filter((l: string) => l.trim());\n return `Found ${lines.length} matches`;\n }\n case 'Edit': {\n if (input) {\n return extractEditSummary(input);\n }\n return undefined;\n }\n case 'Write': {\n if (input) {\n return extractWriteSummary(input);\n }\n return undefined;\n }\n default:\n return undefined;\n }\n}\n\n/**\n * Build a contextual spinner message based on the completed tool call.\n */\nfunction getToolSpinnerMessage(\n toolName: string,\n input: Record<string, unknown>,\n): string {\n switch (toolName) {\n case 'Grep':\n return `Analysing results`;\n case 'Read':\n return `Analysing`;\n case 'Bash':\n return `Analysing output`;\n case 'Edit':\n case 'Write':\n return `Working`;\n case 'Glob':\n return `Browsing files`;\n case 'WebSearch':\n return `Searching the web`;\n case 'WebFetch':\n return `Fetching documentation`;\n case 'EnterPlanMode':\n return `Planning`;\n default:\n if (toolName.startsWith('mcp__raindrop-wizard__Load')) {\n return `Loading Raindrop documentation`;\n }\n return `Working`;\n }\n}\n\n/**\n * Context passed into processSDKMessage for spinner updates.\n */\nexport interface SDKMessageContext {\n updateSpinner: (msg: string) => void;\n baseSpinnerMessage: string;\n}\n\n/**\n * Process SDK messages and provide user feedback.\n * Handles assistant text, tool use, tool results, and system messages.\n */\nexport function processSDKMessage(\n message: SDKMessage,\n options: WizardOptions,\n collectedText: string[],\n pendingToolCalls: Map<string, PendingToolCall>,\n isInterrupting: boolean,\n context?: SDKMessageContext,\n): void {\n logToFile(`SDK Message: ${message.type}`, JSON.stringify(message, null, 2));\n\n if (options.debug) {\n debug(`SDK Message type: ${message.type}`);\n }\n\n switch (message.type) {\n case 'assistant': {\n // Extract text content from assistant messages\n const content = message.message?.content;\n if (Array.isArray(content)) {\n for (const block of content) {\n if (block.type === 'text' && typeof block.text === 'string') {\n collectedText.push(block.text);\n\n // Add agent message to history for visibility\n ui.addItem({\n type: 'agent-message',\n text: block.text,\n });\n\n // Reset spinner after assistant responds — \"Analysing\" after \"Perfect!\" looks wrong\n if (context?.updateSpinner) {\n context.updateSpinner(context.baseSpinnerMessage);\n }\n }\n // Handle tool_use blocks - store pending, don't add to history yet\n if (block.type === 'tool_use') {\n const toolName = block.name || 'Unknown tool';\n const toolInput = block.input || {};\n const toolUseId = block.id;\n logToFile(\n `Tool use requested: ${toolName} (id: ${toolUseId})`,\n toolInput,\n );\n\n // Skip storing/displaying internal SDK tools (including all mcp__* tools)\n if (isInternalTool(toolName)) {\n continue;\n }\n\n // Show tool as executing immediately (pretooluse)\n const historyItemId = ui.addItem({\n type: 'tool-call',\n text: toolName,\n toolCall: {\n toolName,\n status: 'executing',\n input: toolInput,\n description:\n typeof toolInput.description === 'string'\n ? toolInput.description\n : undefined,\n },\n });\n\n // Store pending tool call with history ID so we can update it on completion\n pendingToolCalls.set(toolUseId, {\n toolName,\n input: toolInput,\n description:\n typeof toolInput.description === 'string'\n ? toolInput.description\n : undefined,\n historyItemId,\n });\n }\n }\n }\n break;\n }\n\n case 'user': {\n // Tool results come as 'user' messages with tool_result content\n const content = message.message?.content;\n if (Array.isArray(content)) {\n for (const block of content) {\n if (block.type === 'tool_result') {\n const toolUseId = block.tool_use_id;\n const isError = block.is_error === true;\n const resultContent = block.content;\n\n logToFile(`Tool result for ${toolUseId}:`, {\n isError,\n content: resultContent,\n });\n\n // Look up the pending tool call\n const pendingCall = pendingToolCalls.get(toolUseId);\n if (pendingCall) {\n pendingToolCalls.delete(toolUseId);\n\n // Extract diff content and file name for Edit/Write tools\n const { diffContent, fileName } = extractEditWriteInfo(\n pendingCall.toolName,\n pendingCall.input,\n );\n\n // Skip displaying tool calls for plan files\n if (fileName && fileName.includes('plans/')) {\n continue;\n }\n\n // Extract result summary based on tool type\n const resultSummary = extractResultSummary(\n pendingCall.toolName,\n resultContent,\n pendingCall.input,\n );\n\n // Update the existing 'executing' history item with the final result (posttooluse)\n const completedToolCall = {\n toolName: pendingCall.toolName,\n status: (isError ? 'error' : 'success') as 'error' | 'success',\n input: pendingCall.input,\n description: pendingCall.description,\n result: resultSummary,\n error: isError\n ? `Error: ${String(resultContent)\n .replace(/<\\/?tool_use_error>/g, '')\n .trim()}`\n : undefined,\n diffContent,\n fileName,\n };\n if (pendingCall.historyItemId !== undefined) {\n ui.updateItem(pendingCall.historyItemId, {\n type: 'tool-call',\n text: pendingCall.toolName,\n toolCall: completedToolCall,\n });\n } else {\n ui.addItem({\n type: 'tool-call',\n text: pendingCall.toolName,\n toolCall: completedToolCall,\n });\n }\n\n // Update spinner with contextual message after tool completes (skip errors)\n if (!isError && context?.updateSpinner) {\n context.updateSpinner(\n getToolSpinnerMessage(\n pendingCall.toolName,\n pendingCall.input,\n ),\n );\n }\n }\n\n if (isError && options.debug) {\n debug(`Tool error: ${resultContent}`);\n }\n }\n }\n }\n break;\n }\n\n case 'result': {\n if (message.subtype === 'success') {\n logToFile('Agent completed successfully');\n if (typeof message.result === 'string') {\n collectedText.push(message.result);\n // Note: We intentionally don't display the result message here.\n // The SDK's result.result field contains the same text as the last\n // assistant message, which we already render above. Displaying both\n // would cause duplicate output in the UI.\n }\n } else {\n // Error result - suppress if it's an interrupt-related error\n logToFile('Agent error result:', message.subtype);\n if (message.errors && !isInterrupting) {\n for (const err of message.errors) {\n // Check if error is interrupt-related\n const errStr = String(err);\n const isInterruptError =\n errStr.includes('aborted') ||\n errStr.includes('interrupted') ||\n errStr.includes('403');\n if (!isInterruptError) {\n ui.addItem({ type: 'error', text: `Error: ${err}` });\n }\n logToFile('ERROR:', err);\n }\n }\n }\n break;\n }\n\n case 'system': {\n if (message.subtype === 'init') {\n logToFile('Agent session initialized', {\n model: message.model,\n tools: message.tools?.length,\n });\n }\n break;\n }\n\n default:\n // Log other message types for debugging\n if (options.debug) {\n debug(`Unhandled message type: ${message.type}`);\n }\n break;\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raindrop-ai/wizard",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"homepage": "https://github.com/raindrop/wizard",
|
|
6
6
|
"repository": "https://github.com/raindrop/wizard",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@anthropic-ai/claude-agent-sdk": "0.2.50",
|
|
38
38
|
"@inkkit/ink-markdown": "^1.0.0",
|
|
39
|
-
"@raindrop-ai/claude-agent-sdk": "^0.0.
|
|
39
|
+
"@raindrop-ai/claude-agent-sdk": "^0.0.6",
|
|
40
40
|
"chalk": "^2.4.1",
|
|
41
41
|
"clipboardy": "^4.0.0",
|
|
42
42
|
"diff": "^8.0.3",
|