diff --git a/build/open-vsix/build.sh b/build/open-vsix/build.sh index 5c7dc74..e13123b 100755 --- a/build/open-vsix/build.sh +++ b/build/open-vsix/build.sh @@ -6,7 +6,7 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -VERSION="2.0.2" +VERSION="2.0.3" OUTPUT_NAME="vsix-claude-code-chat-${VERSION}.vsix" echo "Building Open VSIX version ${VERSION}..." diff --git a/package.json b/package.json index 491074e..c6ce3c1 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-code-chat", "displayName": "Chat for Claude Code", "description": "Beautiful Claude Code Chat Interface for VS Code", - "version": "2.0.2", + "version": "2.0.3", "publisher": "AndrePimenta", "author": "Andre Pimenta", "repository": { diff --git a/src/script.ts b/src/script.ts index 4357aa4..d51fad2 100644 --- a/src/script.ts +++ b/src/script.ts @@ -207,14 +207,15 @@ const getScript = (isTelemetryEnabled: boolean, opencreditsApiUrl: string = 'htt const iconDiv = document.createElement('div'); iconDiv.className = 'tool-icon'; - iconDiv.textContent = '🔧'; - + iconDiv.textContent = data.toolName === 'ExitPlanMode' ? '📋' : '🔧'; + const toolInfoElement = document.createElement('div'); toolInfoElement.className = 'tool-info'; let toolName = data.toolInfo.replace('🔧 Executing: ', ''); - // Replace TodoWrite with more user-friendly name if (toolName === 'TodoWrite') { toolName = 'Update Todos'; + } else if (toolName === 'ExitPlanMode') { + toolName = 'Plan'; } toolInfoElement.textContent = toolName; @@ -287,6 +288,8 @@ const getScript = (isTelemetryEnabled: boolean, opencreditsApiUrl: string = 'htt } else { contentDiv.innerHTML = formatWriteToolDiff(data.rawInput, data.fileContentBefore, showButton); } + } else if (data.toolName === 'ExitPlanMode' && data.rawInput) { + contentDiv.innerHTML = formatPlanOutput(data.rawInput); } else { contentDiv.innerHTML = formatToolInputUI(data.rawInput); } @@ -464,6 +467,34 @@ const getScript = (isTelemetryEnabled: boolean, opencreditsApiUrl: string = 'htt scrollToBottomIfNeeded(messagesDiv, shouldScroll); } + function formatPlanOutput(input) { + var html = ''; + + // Render plan markdown + if (input.plan) { + html += '
' + parseSimpleMarkdown(input.plan) + '
'; + } + + // Render allowed prompts as action buttons + if (input.allowedPrompts && input.allowedPrompts.length > 0) { + html += '
'; + html += '
Suggested actions:
'; + input.allowedPrompts.forEach(function(p) { + var label = p.prompt || (p.tool + ' command'); + var escapedPrompt = escapeHtml(label).replace(/'/g, '''); + html += ''; + }); + html += '
'; + } + + return html; + } + + function sendPlanAction(prompt) { + messageInput.value = prompt; + sendMessage(); + } + function formatToolInputUI(input) { if (!input || typeof input !== 'object') { const str = String(input); @@ -3796,7 +3827,8 @@ const getScript = (isTelemetryEnabled: boolean, opencreditsApiUrl: string = 'htt messageDiv.id = \`permission-\${data.id}\`; messageDiv.dataset.status = data.status || 'pending'; - const toolName = data.tool || 'Unknown Tool'; + let toolName = data.tool || 'Unknown Tool'; + if (toolName === 'ExitPlanMode') toolName = 'Approve Plan'; const status = data.status || 'pending'; // Create always allow button text with command styling for Bash @@ -3832,11 +3864,11 @@ const getScript = (isTelemetryEnabled: boolean, opencreditsApiUrl: string = 'htt
-

Allow \${toolName} to execute the tool call above?

+

\${data.tool === 'ExitPlanMode' ? 'Approve the plan above?' : 'Allow ' + toolName + ' to execute the tool call above?'}

- - + \${data.tool === 'ExitPlanMode' ? '' : ''} +
\`; diff --git a/src/ui-styles.ts b/src/ui-styles.ts index deb4cae..76bd766 100644 --- a/src/ui-styles.ts +++ b/src/ui-styles.ts @@ -1324,6 +1324,62 @@ const styles = ` opacity: 0.95; } + .plan-content { + font-size: 13px; + line-height: 1.6; + } + + .plan-content h1, .plan-content h2, .plan-content h3 { + margin: 12px 0 6px; + font-weight: 600; + } + + .plan-content h1 { font-size: 16px; } + .plan-content h2 { font-size: 14px; } + .plan-content h3 { font-size: 13px; } + + .plan-content ul, .plan-content ol { + padding-left: 20px; + margin: 4px 0; + } + + .plan-content code { + font-family: var(--vscode-editor-font-family); + font-size: 12px; + background: rgba(127, 127, 127, 0.15); + padding: 1px 4px; + border-radius: 3px; + } + + .plan-actions { + margin-top: 12px; + padding-top: 10px; + border-top: 1px solid var(--vscode-panel-border); + } + + .plan-actions-label { + font-size: 11px; + color: var(--vscode-descriptionForeground); + margin-bottom: 8px; + } + + .plan-action-btn { + display: inline-block; + background: var(--vscode-button-secondaryBackground, rgba(128, 128, 128, 0.2)); + color: var(--vscode-button-secondaryForeground, var(--vscode-foreground)); + border: 1px solid var(--vscode-panel-border); + padding: 5px 12px; + border-radius: 4px; + font-size: 12px; + cursor: pointer; + margin: 0 6px 6px 0; + } + + .plan-action-btn:hover { + background: var(--vscode-list-hoverBackground); + border-color: var(--vscode-focusBorder); + } + /* Diff display styles for Edit tool */ .diff-container { border: 1px solid var(--vscode-panel-border);