@raindrop-ai/wizard 0.0.11 → 0.0.12
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/docs/python.mdx +6 -0
- package/dist/src/docs/typescript.mdx +125 -28
- package/dist/src/lib/__tests__/sdk-messages.test.d.ts +4 -0
- package/dist/src/lib/__tests__/sdk-messages.test.js +296 -0
- package/dist/src/lib/__tests__/sdk-messages.test.js.map +1 -0
- package/dist/src/lib/agent-interface.js +40 -14
- package/dist/src/lib/agent-interface.js.map +1 -1
- package/dist/src/lib/agent-prompts.js +4 -1
- package/dist/src/lib/agent-prompts.js.map +1 -1
- package/dist/src/lib/constants.d.ts +7 -0
- package/dist/src/lib/constants.js +15 -0
- package/dist/src/lib/constants.js.map +1 -1
- package/dist/src/lib/handlers.js +21 -18
- package/dist/src/lib/handlers.js.map +1 -1
- package/dist/src/lib/sdk-messages.d.ts +41 -2
- package/dist/src/lib/sdk-messages.js +89 -41
- package/dist/src/lib/sdk-messages.js.map +1 -1
- package/dist/src/lib/wizard.js +1 -1
- package/dist/src/lib/wizard.js.map +1 -1
- package/dist/src/ui/components/ToolCallDisplay.js +30 -0
- package/dist/src/ui/components/ToolCallDisplay.js.map +1 -1
- package/dist/src/ui/contexts/WizardContext.d.ts +0 -11
- package/dist/src/ui/contexts/WizardContext.js +2 -19
- package/dist/src/ui/contexts/WizardContext.js.map +1 -1
- package/dist/src/utils/__mocks__/ui.d.ts +10 -0
- package/dist/src/utils/__mocks__/ui.js +7 -0
- package/dist/src/utils/__mocks__/ui.js.map +1 -0
- package/dist/src/utils/session.d.ts +22 -0
- package/dist/src/utils/session.js +67 -1
- package/dist/src/utils/session.js.map +1 -1
- package/package.json +16 -1
|
@@ -104,11 +104,11 @@ export function initializeAgent(config, options) {
|
|
|
104
104
|
ensureClaudeConfigFileExists();
|
|
105
105
|
process.env.MAX_THINKING_TOKENS = '10000';
|
|
106
106
|
process.env.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS = 'true';
|
|
107
|
-
// Set default subagent model to
|
|
108
|
-
process.env.CLAUDE_CODE_SUBAGENT_MODEL = 'claude-
|
|
107
|
+
// Set default subagent model to Opus
|
|
108
|
+
process.env.CLAUDE_CODE_SUBAGENT_MODEL = 'claude-opus-4-6';
|
|
109
109
|
const agentRunConfig = {
|
|
110
110
|
workingDirectory: config.workingDirectory,
|
|
111
|
-
model: '
|
|
111
|
+
model: 'opus',
|
|
112
112
|
};
|
|
113
113
|
logToFile('Agent config:', {
|
|
114
114
|
workingDirectory: agentRunConfig.workingDirectory,
|
|
@@ -152,7 +152,6 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
|
|
|
152
152
|
const inputQueue = new UserMessageQueue();
|
|
153
153
|
inputQueue.push(prompt);
|
|
154
154
|
const approvedFilesCache = new Set();
|
|
155
|
-
const collectedText = [];
|
|
156
155
|
const pendingToolCalls = new Map();
|
|
157
156
|
const hasCompletedWorkRef = { value: false };
|
|
158
157
|
const isInterruptingRef = { value: false };
|
|
@@ -194,14 +193,12 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
|
|
|
194
193
|
spinner.start(spinnerMessage);
|
|
195
194
|
isSpinnerRunning = true;
|
|
196
195
|
}
|
|
197
|
-
ui.setAgentState({ isRunning: true });
|
|
198
196
|
return;
|
|
199
197
|
}
|
|
200
198
|
if (isSpinnerRunning) {
|
|
201
199
|
spinner.stop();
|
|
202
200
|
isSpinnerRunning = false;
|
|
203
201
|
}
|
|
204
|
-
ui.setAgentState({ isRunning: false });
|
|
205
202
|
};
|
|
206
203
|
// Create MCP server with CompleteIntegration tool
|
|
207
204
|
const toolsMcpServer = createMcpServer(hasCompletedWorkRef, {
|
|
@@ -249,6 +246,7 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
|
|
|
249
246
|
waitingForUserInputRef.value = false;
|
|
250
247
|
isInterruptingRef.value = false;
|
|
251
248
|
setAgentRunning(true);
|
|
249
|
+
updateSpinner(currentSpinnerMsg);
|
|
252
250
|
return;
|
|
253
251
|
}
|
|
254
252
|
if (!isInterruptingRef.value) {
|
|
@@ -288,6 +286,7 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
|
|
|
288
286
|
};
|
|
289
287
|
startPersistentInput();
|
|
290
288
|
setAgentRunning(true);
|
|
289
|
+
updateSpinner(currentSpinnerMsg);
|
|
291
290
|
// Create Raindrop client and wrap the Claude Agent SDK for observability
|
|
292
291
|
const raindrop = createRaindropClaudeAgentSDK({
|
|
293
292
|
writeKey: accessToken,
|
|
@@ -299,6 +298,14 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
|
|
|
299
298
|
},
|
|
300
299
|
selfDiagnostics: {
|
|
301
300
|
signals: {
|
|
301
|
+
learnings: {
|
|
302
|
+
description: 'The agent learned something new that it did not know before.',
|
|
303
|
+
sentiment: 'NEGATIVE',
|
|
304
|
+
},
|
|
305
|
+
misleading_docs: {
|
|
306
|
+
description: 'The agent followed the documentation and then realised later that it was not the correct approach.',
|
|
307
|
+
sentiment: 'NEGATIVE',
|
|
308
|
+
},
|
|
302
309
|
code_dumping: {
|
|
303
310
|
description: 'The user pasted code or console logs to the agent.',
|
|
304
311
|
sentiment: 'NEGATIVE',
|
|
@@ -332,7 +339,11 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
|
|
|
332
339
|
mcpServers: {
|
|
333
340
|
'raindrop-wizard': toolsMcpServer,
|
|
334
341
|
},
|
|
335
|
-
systemPrompt:
|
|
342
|
+
systemPrompt: {
|
|
343
|
+
type: 'preset',
|
|
344
|
+
preset: 'claude_code',
|
|
345
|
+
append: '{WIZARD_SYSTEM_PROMPT}',
|
|
346
|
+
},
|
|
336
347
|
env: { ...process.env },
|
|
337
348
|
canUseTool: createCanUseToolHandler(approvedFilesCache),
|
|
338
349
|
hooks: {
|
|
@@ -347,19 +358,16 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
|
|
|
347
358
|
},
|
|
348
359
|
});
|
|
349
360
|
// Update agent state
|
|
350
|
-
ui.setAgentState({
|
|
351
|
-
isRunning: true,
|
|
352
|
-
queryHandle: handle,
|
|
353
|
-
});
|
|
361
|
+
ui.setAgentState({ queryHandle: handle });
|
|
354
362
|
try {
|
|
355
363
|
if (!queryObject) {
|
|
356
364
|
throw new Error('queryObject was not initialized');
|
|
357
365
|
}
|
|
366
|
+
let lastAssistantHadVisibleContent = true;
|
|
358
367
|
for await (const message of queryObject) {
|
|
359
368
|
// Capture session_id from any message
|
|
360
369
|
if (message.session_id && !sessionId) {
|
|
361
370
|
sessionId = message.session_id;
|
|
362
|
-
ui.setAgentState({ sessionId });
|
|
363
371
|
}
|
|
364
372
|
// If we were waiting for user input but got a new message,
|
|
365
373
|
// the queued message has started processing.
|
|
@@ -369,8 +377,25 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
|
|
|
369
377
|
waitingForUserInputRef.value = false;
|
|
370
378
|
isInterruptingRef.value = false;
|
|
371
379
|
setAgentRunning(true);
|
|
380
|
+
updateSpinner(currentSpinnerMsg);
|
|
381
|
+
}
|
|
382
|
+
const sdkResult = processSDKMessage(message, options, pendingToolCalls, isInterruptingRef.value, {
|
|
383
|
+
updateSpinner,
|
|
384
|
+
baseSpinnerMessage: spinnerMessage,
|
|
385
|
+
lastAssistantHadVisibleContent,
|
|
386
|
+
queueFollowUpPrompt: (prompt) => inputQueue.push(prompt),
|
|
387
|
+
hasCompletedWork: hasCompletedWorkRef.value,
|
|
388
|
+
onError: {
|
|
389
|
+
wizardSessionId: options.sessionId,
|
|
390
|
+
accessToken,
|
|
391
|
+
orgId,
|
|
392
|
+
workingDirectory: path.resolve(agentConfig.workingDirectory),
|
|
393
|
+
},
|
|
394
|
+
});
|
|
395
|
+
if (sdkResult?.lastAssistantHadVisibleContent !== undefined) {
|
|
396
|
+
lastAssistantHadVisibleContent =
|
|
397
|
+
sdkResult.lastAssistantHadVisibleContent;
|
|
372
398
|
}
|
|
373
|
-
processSDKMessage(message, options, collectedText, pendingToolCalls, isInterruptingRef.value, { updateSpinner, baseSpinnerMessage: spinnerMessage });
|
|
374
399
|
if (message.type !== 'result') {
|
|
375
400
|
continue;
|
|
376
401
|
}
|
|
@@ -404,6 +429,7 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
|
|
|
404
429
|
handle.sendMessage(feedbackPrompt);
|
|
405
430
|
startPersistentInput();
|
|
406
431
|
setAgentRunning(true);
|
|
432
|
+
updateSpinner(currentSpinnerMsg);
|
|
407
433
|
continue;
|
|
408
434
|
}
|
|
409
435
|
completed = completionDecision;
|
|
@@ -421,6 +447,7 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
|
|
|
421
447
|
else {
|
|
422
448
|
waitingForUserInputRef.value = false;
|
|
423
449
|
setAgentRunning(true);
|
|
450
|
+
updateSpinner(currentSpinnerMsg);
|
|
424
451
|
}
|
|
425
452
|
}
|
|
426
453
|
}
|
|
@@ -438,7 +465,6 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
|
|
|
438
465
|
completed = true;
|
|
439
466
|
}
|
|
440
467
|
ui.stopPersistentInput();
|
|
441
|
-
ui.setAgentState({ isRunning: false });
|
|
442
468
|
if (completed || isSpinnerRunning) {
|
|
443
469
|
spinner.stop();
|
|
444
470
|
}
|
|
@@ -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 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"]}
|
|
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 Opus\n process.env.CLAUDE_CODE_SUBAGENT_MODEL = 'claude-opus-4-6';\n\n const agentRunConfig: AgentRunConfig = {\n workingDirectory: config.workingDirectory,\n model: 'opus',\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 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 return;\n }\n\n if (isSpinnerRunning) {\n spinner.stop();\n isSpinnerRunning = false;\n }\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 updateSpinner(currentSpinnerMsg);\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 updateSpinner(currentSpinnerMsg);\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 learnings: {\n description:\n 'The agent learned something new that it did not know before.',\n sentiment: 'NEGATIVE',\n },\n misleading_docs: {\n description:\n 'The agent followed the documentation and then realised later that it was not the correct approach.',\n sentiment: 'NEGATIVE',\n },\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: {\n type: 'preset',\n preset: 'claude_code',\n append: '{WIZARD_SYSTEM_PROMPT}',\n },\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({ queryHandle: handle });\n\n try {\n if (!queryObject) {\n throw new Error('queryObject was not initialized');\n }\n let lastAssistantHadVisibleContent = true;\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 }\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 updateSpinner(currentSpinnerMsg);\n }\n\n const sdkResult = processSDKMessage(\n message,\n options,\n pendingToolCalls,\n isInterruptingRef.value,\n {\n updateSpinner,\n baseSpinnerMessage: spinnerMessage,\n lastAssistantHadVisibleContent,\n queueFollowUpPrompt: (prompt: string) => inputQueue.push(prompt),\n hasCompletedWork: hasCompletedWorkRef.value,\n onError: {\n wizardSessionId: options.sessionId,\n accessToken,\n orgId,\n workingDirectory: path.resolve(agentConfig.workingDirectory),\n },\n },\n );\n if (sdkResult?.lastAssistantHadVisibleContent !== undefined) {\n lastAssistantHadVisibleContent =\n sdkResult.lastAssistantHadVisibleContent;\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 updateSpinner(currentSpinnerMsg);\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 updateSpinner(currentSpinnerMsg);\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\n if (completed || isSpinnerRunning) {\n spinner.stop();\n }\n\n return { sessionId, handle, completed, support: supportRequested };\n}\n"]}
|
|
@@ -22,7 +22,10 @@ Analyze the events and user feedback, then fix the code to address any issues:
|
|
|
22
22
|
2. Identify what's missing or incorrect
|
|
23
23
|
3. Update the integration code to fix the problems
|
|
24
24
|
4. Verify the build still succeeds after your fixes
|
|
25
|
-
5. Call CompleteIntegration when done. Do not announce that you are calling the tool
|
|
25
|
+
5. Call CompleteIntegration when done. Do not announce that you are calling the tool.
|
|
26
|
+
|
|
27
|
+
## Fix
|
|
28
|
+
Begin the integration by immediately announcing that you will analyse the events and user feedback and then fix the code to address any issues.`;
|
|
26
29
|
}
|
|
27
30
|
// =============================================================================
|
|
28
31
|
// Helper Functions
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-prompts.js","sourceRoot":"","sources":["../../../src/lib/agent-prompts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,UAAU,wBAAwB,CACtC,MAAyC,EACzC,YAAoB;IAEpB,OAAO;;;;EAIP,kBAAkB,CAAC,MAAM,CAAC;;;;GAIzB,YAAY
|
|
1
|
+
{"version":3,"file":"agent-prompts.js","sourceRoot":"","sources":["../../../src/lib/agent-prompts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,UAAU,wBAAwB,CACtC,MAAyC,EACzC,YAAoB;IAEpB,OAAO;;;;EAIP,kBAAkB,CAAC,MAAM,CAAC;;;;GAIzB,YAAY;;;;;;;;;;;;gJAYiI,CAAC;AACjJ,CAAC;AAED,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;GAEG;AACH,SAAS,kBAAkB,CAAC,MAAyC;IACnE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAED,OAAO,MAAM;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QAClB,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QAC9D,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC,IAAI,CAAC;QAEtD,OAAO,UAAU,GAAG,GAAG,CAAC,OAAO,KAAK,CAAC,GAAG;UACpC,MAAM;EACd,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE;QACpC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;IACvC,CAAC,CAAC;SACD,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC","sourcesContent":["/**\n * Agent prompt templates for Raindrop integration wizard\n */\n\n/**\n * Build test feedback message for agent\n */\nexport function buildTestFeedbackMessage(\n events: Array<{ url: string; data: any }>,\n userFeedback: string,\n): string {\n return `# Integration Test Results\n\n## Events Collected\n\n${formatEventSummary(events)}\n\n## User Feedback\n\n\"${userFeedback}\"\n\n## Your Task\n\nAnalyze the events and user feedback, then fix the code to address any issues:\n1. Review the event data structure and user's comments\n2. Identify what's missing or incorrect\n3. Update the integration code to fix the problems\n4. Verify the build still succeeds after your fixes\n5. Call CompleteIntegration when done. Do not announce that you are calling the tool.\n\n## Fix\nBegin the integration by immediately announcing that you will analyse the events and user feedback and then fix the code to address any issues.`;\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Format event summary for test feedback\n */\nfunction formatEventSummary(events: Array<{ url: string; data: any }>): string {\n if (events.length === 0) {\n return 'No events received.';\n }\n\n return events\n .map((event, idx) => {\n const format = event.data.format === 'otel' ? 'OTEL' : 'JSON';\n const spanCount = event.data.spans?.length || 0;\n const aiAttrs = event.data.aiAttributes || event.data;\n\n return `Event #${idx + 1} at ${event.url}:\nFormat: ${format}\n${spanCount > 0 ? `Spans: ${spanCount}` : ''}\nData: ${JSON.stringify(aiAttrs, null, 2)}`;\n })\n .join('\\n\\n');\n}\n"]}
|
|
@@ -15,12 +15,19 @@ export declare const ANTHROPIC_BASE_URL: string;
|
|
|
15
15
|
export declare const SESSION_START_ENDPOINT: string;
|
|
16
16
|
export declare const SESSION_UPDATE_ENDPOINT: string;
|
|
17
17
|
export declare const SESSION_COMPLETE_ENDPOINT: string;
|
|
18
|
+
export declare const SESSION_ERROR_ENDPOINT: string;
|
|
18
19
|
export declare const SUPPORT_ENDPOINT: string;
|
|
19
20
|
export declare const RAINDROP_ENDPOINT: string;
|
|
20
21
|
/**
|
|
21
22
|
* Spinner message shown during wizard execution
|
|
22
23
|
*/
|
|
23
24
|
export declare const SPINNER_MESSAGE = "Raindrop wizard is working...";
|
|
25
|
+
/** Prefix for MCP tools (e.g. mcp__server__tool). Shared by handlers and SDK message processing. */
|
|
26
|
+
export declare const MCP_TOOL_PREFIX = "mcp__";
|
|
27
|
+
/** Tool names that are internal to the wizard and not shown in the UI (e.g. Task, EnterPlanMode). */
|
|
28
|
+
export declare const INTERNAL_TOOL_NAMES: Set<string>;
|
|
29
|
+
/** Canned message when assistant content is an error (message.error set). Optional code e.g. "504". */
|
|
30
|
+
export declare const ERROR_DISPLAY_MESSAGE: (code?: string) => string;
|
|
24
31
|
/**
|
|
25
32
|
* Safe bash command patterns that can be auto-approved without user confirmation.
|
|
26
33
|
* Uses simple prefix matching with optional * wildcard at the end.
|
|
@@ -32,12 +32,27 @@ export const ANTHROPIC_BASE_URL = `${RAINDROP_API_URL}/api/cli`;
|
|
|
32
32
|
export const SESSION_START_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/init`;
|
|
33
33
|
export const SESSION_UPDATE_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/update`;
|
|
34
34
|
export const SESSION_COMPLETE_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/complete`;
|
|
35
|
+
export const SESSION_ERROR_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/error`;
|
|
35
36
|
export const SUPPORT_ENDPOINT = `${RAINDROP_API_URL}/api/cli/support`;
|
|
36
37
|
export const RAINDROP_ENDPOINT = `${RAINDROP_API_URL}/api/cli/raindrop`;
|
|
37
38
|
/**
|
|
38
39
|
* Spinner message shown during wizard execution
|
|
39
40
|
*/
|
|
40
41
|
export const SPINNER_MESSAGE = 'Raindrop wizard is working...';
|
|
42
|
+
/** Prefix for MCP tools (e.g. mcp__server__tool). Shared by handlers and SDK message processing. */
|
|
43
|
+
export const MCP_TOOL_PREFIX = 'mcp__';
|
|
44
|
+
/** Tool names that are internal to the wizard and not shown in the UI (e.g. Task, EnterPlanMode). */
|
|
45
|
+
export const INTERNAL_TOOL_NAMES = new Set([
|
|
46
|
+
'Task',
|
|
47
|
+
'AskUserQuestion',
|
|
48
|
+
'TodoWrite',
|
|
49
|
+
'EnterPlanMode',
|
|
50
|
+
'ExitPlanMode',
|
|
51
|
+
]);
|
|
52
|
+
/** Canned message when assistant content is an error (message.error set). Optional code e.g. "504". */
|
|
53
|
+
export const ERROR_DISPLAY_MESSAGE = (code) => code
|
|
54
|
+
? `Sorry, I encountered a ${code} error. Send another message to continue. If the issue persists, please contact support@raindrop.ai`
|
|
55
|
+
: `Sorry, I encountered an error. Send another message to continue. If the issue persists, please contact support@raindrop.ai`;
|
|
41
56
|
/**
|
|
42
57
|
* Safe bash command patterns that can be auto-approved without user confirmation.
|
|
43
58
|
* Uses simple prefix matching with optional * wildcard at the end.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/lib/constants.ts"],"names":[],"mappings":"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","sourcesContent":["export enum Integration {\n python = 'python',\n typescript = 'typescript',\n vercelAiSdk = 'vercel-ai-sdk',\n}\n\nexport function getIntegrationDescription(type: string): string {\n switch (type) {\n case Integration.python:\n return 'a Python SDK';\n case Integration.typescript:\n return 'a TypeScript SDK';\n case Integration.vercelAiSdk:\n return 'the Vercel AI SDK';\n default:\n throw new Error(`Unknown integration ${type}`);\n }\n}\n\nexport const IS_DEV = ['test', 'development'].includes(\n process.env.NODE_ENV ?? '',\n);\n\nexport const ISSUES_URL = 'https://github.com/raindrop/wizard/issues';\n\nexport const CALLBACK_PORT = 8259;\nconst useLocalUrls = ['1', 'true'].includes(\n (process.env.RAINDROP_USE_LOCAL ?? '').toLowerCase(),\n);\n\nexport const APP_URL = useLocalUrls\n ? 'http://localhost:5173'\n : 'https://app.raindrop.ai';\nexport const RAINDROP_API_URL = useLocalUrls\n ? 'http://localhost:3000'\n : 'https://api.dawnai.com';\nexport const WRITE_KEY_ENDPOINT = `${RAINDROP_API_URL}/api/cli/users/key`;\nexport const EVENTS_LIST_ENDPOINT = `${RAINDROP_API_URL}/api/cli/events/list`;\nexport const ANTHROPIC_BASE_URL = `${RAINDROP_API_URL}/api/cli`;\nexport const SESSION_START_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/init`;\nexport const SESSION_UPDATE_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/update`;\nexport const SESSION_COMPLETE_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/complete`;\nexport const SUPPORT_ENDPOINT = `${RAINDROP_API_URL}/api/cli/support`;\nexport const RAINDROP_ENDPOINT = `${RAINDROP_API_URL}/api/cli/raindrop`;\n\n/**\n * Spinner message shown during wizard execution\n */\nexport const SPINNER_MESSAGE = 'Raindrop wizard is working...';\n\n/**\n * Safe bash command patterns that can be auto-approved without user confirmation.\n * Uses simple prefix matching with optional * wildcard at the end.\n *\n * NOTE: Package manager install/build/run commands are NOT auto-approved and require user confirmation.\n */\nexport const SAFE_BASH_PATTERNS: string[] = [\n // === Package Managers - Read-only commands ===\n 'npm ls*',\n 'npm outdated*',\n 'npm audit*',\n\n 'pip list*',\n 'pip show*',\n 'pip freeze*',\n\n 'poetry show*',\n\n 'uv pip list*',\n\n 'cargo check*',\n 'cargo clippy*',\n 'cargo fmt*',\n\n 'go fmt*',\n\n // === Type Checking / Linting / Formatting ===\n 'tsc*',\n 'eslint *',\n 'prettier *',\n 'biome *',\n 'mypy *',\n 'python -m mypy*',\n 'ruff *',\n 'black *',\n 'flake8 *',\n 'pylint *',\n 'pyright*',\n 'rubocop*',\n 'rustfmt*',\n 'gofmt*',\n 'swiftlint*',\n 'ktlint*',\n\n // === Build Tools ===\n 'make',\n 'make build*',\n 'make test*',\n 'make lint*',\n 'make check*',\n 'cmake *',\n 'gradle build*',\n 'gradle test*',\n './gradlew build*',\n './gradlew test*',\n 'mvn compile*',\n 'mvn test*',\n 'mvn package*',\n\n // === Testing ===\n 'jest*',\n 'vitest*',\n 'mocha*',\n 'pytest*',\n 'python -m pytest*',\n 'npx playwright test*',\n 'npx cypress run*',\n 'npx jest*',\n 'npx vitest*',\n\n // === Git (read-only operations) ===\n 'git status*',\n 'git diff*',\n 'git log*',\n 'git show*',\n 'git branch*',\n 'git fetch*',\n 'git remote -v*',\n 'git ls-files*',\n 'git rev-parse*',\n\n // === File/Directory Info (read-only) ===\n 'ls *',\n 'ls',\n 'cat *',\n 'head *',\n 'tail *',\n 'less *',\n 'find *',\n 'grep *',\n 'rg *',\n 'ag *',\n 'tree*',\n 'pwd',\n 'wc *',\n 'file *',\n 'stat *',\n 'du *',\n 'df *',\n\n // === Environment/System Info ===\n 'which *',\n 'whereis *',\n 'type *',\n 'command -v *',\n 'node --version*',\n 'node -v*',\n 'npm --version*',\n 'npm -v*',\n 'python --version*',\n 'python -V*',\n 'python3 --version*',\n '*--version',\n '*-v',\n '*-V',\n 'env',\n 'printenv*',\n 'echo *',\n 'uname*',\n 'hostname',\n 'whoami',\n 'date',\n 'uptime',\n\n // === Docker (read-only / safe) ===\n 'docker ps*',\n 'docker images*',\n 'docker logs*',\n 'docker inspect*',\n 'docker-compose ps*',\n 'docker-compose logs*',\n 'docker build*',\n 'docker compose build*',\n 'docker compose up*',\n\n // === Directory Navigation ===\n 'cd *',\n 'pushd *',\n 'popd',\n];\n"]}
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/lib/constants.ts"],"names":[],"mappings":"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","sourcesContent":["export enum Integration {\n python = 'python',\n typescript = 'typescript',\n vercelAiSdk = 'vercel-ai-sdk',\n}\n\nexport function getIntegrationDescription(type: string): string {\n switch (type) {\n case Integration.python:\n return 'a Python SDK';\n case Integration.typescript:\n return 'a TypeScript SDK';\n case Integration.vercelAiSdk:\n return 'the Vercel AI SDK';\n default:\n throw new Error(`Unknown integration ${type}`);\n }\n}\n\nexport const IS_DEV = ['test', 'development'].includes(\n process.env.NODE_ENV ?? '',\n);\n\nexport const ISSUES_URL = 'https://github.com/raindrop/wizard/issues';\n\nexport const CALLBACK_PORT = 8259;\nconst useLocalUrls = ['1', 'true'].includes(\n (process.env.RAINDROP_USE_LOCAL ?? '').toLowerCase(),\n);\n\nexport const APP_URL = useLocalUrls\n ? 'http://localhost:5173'\n : 'https://app.raindrop.ai';\nexport const RAINDROP_API_URL = useLocalUrls\n ? 'http://localhost:3000'\n : 'https://api.dawnai.com';\nexport const WRITE_KEY_ENDPOINT = `${RAINDROP_API_URL}/api/cli/users/key`;\nexport const EVENTS_LIST_ENDPOINT = `${RAINDROP_API_URL}/api/cli/events/list`;\nexport const ANTHROPIC_BASE_URL = `${RAINDROP_API_URL}/api/cli`;\nexport const SESSION_START_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/init`;\nexport const SESSION_UPDATE_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/update`;\nexport const SESSION_COMPLETE_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/complete`;\nexport const SESSION_ERROR_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/error`;\nexport const SUPPORT_ENDPOINT = `${RAINDROP_API_URL}/api/cli/support`;\nexport const RAINDROP_ENDPOINT = `${RAINDROP_API_URL}/api/cli/raindrop`;\n\n/**\n * Spinner message shown during wizard execution\n */\nexport const SPINNER_MESSAGE = 'Raindrop wizard is working...';\n\n/** Prefix for MCP tools (e.g. mcp__server__tool). Shared by handlers and SDK message processing. */\nexport const MCP_TOOL_PREFIX = 'mcp__';\n\n/** Tool names that are internal to the wizard and not shown in the UI (e.g. Task, EnterPlanMode). */\nexport const INTERNAL_TOOL_NAMES = new Set([\n 'Task',\n 'AskUserQuestion',\n 'TodoWrite',\n 'EnterPlanMode',\n 'ExitPlanMode',\n]);\n\n/** Canned message when assistant content is an error (message.error set). Optional code e.g. \"504\". */\nexport const ERROR_DISPLAY_MESSAGE = (code?: string) =>\n code\n ? `Sorry, I encountered a ${code} error. Send another message to continue. If the issue persists, please contact support@raindrop.ai`\n : `Sorry, I encountered an error. Send another message to continue. If the issue persists, please contact support@raindrop.ai`;\n\n/**\n * Safe bash command patterns that can be auto-approved without user confirmation.\n * Uses simple prefix matching with optional * wildcard at the end.\n *\n * NOTE: Package manager install/build/run commands are NOT auto-approved and require user confirmation.\n */\nexport const SAFE_BASH_PATTERNS: string[] = [\n // === Package Managers - Read-only commands ===\n 'npm ls*',\n 'npm outdated*',\n 'npm audit*',\n\n 'pip list*',\n 'pip show*',\n 'pip freeze*',\n\n 'poetry show*',\n\n 'uv pip list*',\n\n 'cargo check*',\n 'cargo clippy*',\n 'cargo fmt*',\n\n 'go fmt*',\n\n // === Type Checking / Linting / Formatting ===\n 'tsc*',\n 'eslint *',\n 'prettier *',\n 'biome *',\n 'mypy *',\n 'python -m mypy*',\n 'ruff *',\n 'black *',\n 'flake8 *',\n 'pylint *',\n 'pyright*',\n 'rubocop*',\n 'rustfmt*',\n 'gofmt*',\n 'swiftlint*',\n 'ktlint*',\n\n // === Build Tools ===\n 'make',\n 'make build*',\n 'make test*',\n 'make lint*',\n 'make check*',\n 'cmake *',\n 'gradle build*',\n 'gradle test*',\n './gradlew build*',\n './gradlew test*',\n 'mvn compile*',\n 'mvn test*',\n 'mvn package*',\n\n // === Testing ===\n 'jest*',\n 'vitest*',\n 'mocha*',\n 'pytest*',\n 'python -m pytest*',\n 'npx playwright test*',\n 'npx cypress run*',\n 'npx jest*',\n 'npx vitest*',\n\n // === Git (read-only operations) ===\n 'git status*',\n 'git diff*',\n 'git log*',\n 'git show*',\n 'git branch*',\n 'git fetch*',\n 'git remote -v*',\n 'git ls-files*',\n 'git rev-parse*',\n\n // === File/Directory Info (read-only) ===\n 'ls *',\n 'ls',\n 'cat *',\n 'head *',\n 'tail *',\n 'less *',\n 'find *',\n 'grep *',\n 'rg *',\n 'ag *',\n 'tree*',\n 'pwd',\n 'wc *',\n 'file *',\n 'stat *',\n 'du *',\n 'df *',\n\n // === Environment/System Info ===\n 'which *',\n 'whereis *',\n 'type *',\n 'command -v *',\n 'node --version*',\n 'node -v*',\n 'npm --version*',\n 'npm -v*',\n 'python --version*',\n 'python -V*',\n 'python3 --version*',\n '*--version',\n '*-v',\n '*-V',\n 'env',\n 'printenv*',\n 'echo *',\n 'uname*',\n 'hostname',\n 'whoami',\n 'date',\n 'uptime',\n\n // === Docker (read-only / safe) ===\n 'docker ps*',\n 'docker images*',\n 'docker logs*',\n 'docker inspect*',\n 'docker-compose ps*',\n 'docker-compose logs*',\n 'docker build*',\n 'docker compose build*',\n 'docker compose up*',\n\n // === Directory Navigation ===\n 'cd *',\n 'pushd *',\n 'popd',\n];\n"]}
|
package/dist/src/lib/handlers.js
CHANGED
|
@@ -6,7 +6,7 @@ import { createTwoFilesPatch } from 'diff';
|
|
|
6
6
|
import { logToFile } from '../utils/debug.js';
|
|
7
7
|
import { sendSessionUpdate } from '../utils/session.js';
|
|
8
8
|
import ui from '../utils/ui.js';
|
|
9
|
-
import { SAFE_BASH_PATTERNS } from './constants.js';
|
|
9
|
+
import { MCP_TOOL_PREFIX, SAFE_BASH_PATTERNS } from './constants.js';
|
|
10
10
|
// ============================================================================
|
|
11
11
|
// Session-wide Approval Tracking
|
|
12
12
|
// ============================================================================
|
|
@@ -301,13 +301,14 @@ 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__';
|
|
306
304
|
/**
|
|
307
305
|
* Tools that are automatically approved without user confirmation.
|
|
308
306
|
* MCP tools (name starts with mcp__) are approved via wildcard in PreToolUse.
|
|
309
307
|
*/
|
|
310
|
-
const AUTO_APPROVED_TOOLS = new Set([
|
|
308
|
+
const AUTO_APPROVED_TOOLS = new Set([
|
|
309
|
+
'EnterPlanMode',
|
|
310
|
+
'WebFetch',
|
|
311
|
+
]);
|
|
311
312
|
/**
|
|
312
313
|
* Patterns indicating a file path or glob likely targets secret/credential files.
|
|
313
314
|
* Used to auto-deny Read/Glob/Grep operations on sensitive files.
|
|
@@ -409,7 +410,22 @@ export function createPreToolUseHook(sessionInfo) {
|
|
|
409
410
|
},
|
|
410
411
|
};
|
|
411
412
|
}
|
|
412
|
-
// Auto-approve
|
|
413
|
+
// Auto-approve WebSearch with domain restriction applied via updatedInput.
|
|
414
|
+
// Keep this before the generic AUTO_APPROVED_TOOLS branch so WebSearch
|
|
415
|
+
// still receives input hardening.
|
|
416
|
+
if (tool_name === 'WebSearch') {
|
|
417
|
+
return {
|
|
418
|
+
hookSpecificOutput: {
|
|
419
|
+
hookEventName: 'PreToolUse',
|
|
420
|
+
permissionDecision: 'allow',
|
|
421
|
+
updatedInput: {
|
|
422
|
+
...inp,
|
|
423
|
+
allowed_domains: ['raindrop.ai/docs', 'ai-sdk.dev/docs/'],
|
|
424
|
+
},
|
|
425
|
+
},
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
// Auto-approve all MCP tools (mcp__*) and core auto-approved tools — no approval UI
|
|
413
429
|
if (tool_name.startsWith(MCP_TOOL_PREFIX) ||
|
|
414
430
|
AUTO_APPROVED_TOOLS.has(tool_name)) {
|
|
415
431
|
return {
|
|
@@ -441,19 +457,6 @@ export function createPreToolUseHook(sessionInfo) {
|
|
|
441
457
|
};
|
|
442
458
|
}
|
|
443
459
|
}
|
|
444
|
-
// Auto-approve WebSearch with domain restriction applied via updatedInput
|
|
445
|
-
if (tool_name === 'WebSearch') {
|
|
446
|
-
return {
|
|
447
|
-
hookSpecificOutput: {
|
|
448
|
-
hookEventName: 'PreToolUse',
|
|
449
|
-
permissionDecision: 'allow',
|
|
450
|
-
updatedInput: {
|
|
451
|
-
...inp,
|
|
452
|
-
allowed_domains: ['raindrop.ai/docs', 'ai-sdk.dev/docs/'],
|
|
453
|
-
},
|
|
454
|
-
},
|
|
455
|
-
};
|
|
456
|
-
}
|
|
457
460
|
// Auto-approve ExitPlanMode and fire session update
|
|
458
461
|
if (tool_name === 'ExitPlanMode') {
|
|
459
462
|
const planContent = typeof inp.plan === 'string' ? inp.plan : '';
|