mirror of
https://github.com/andrepimenta/claude-code-chat.git
synced 2026-05-30 00:05:44 +08:00
Improve plan mode display and permission prompt
- Render ExitPlanMode as formatted markdown plan with proper headings, lists, and code blocks instead of raw key-value dump - Show allowed prompts as clickable action buttons below the plan - Use 📋 Plan header instead of 🔧 ExitPlanMode - Permission prompt says "Approve the plan above?" with Approve button - Hide "Always allow" for plan approvals - Full height plan content without scroll constraint Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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}..."
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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 += '<div class="plan-content">' + parseSimpleMarkdown(input.plan) + '</div>';
|
||||
}
|
||||
|
||||
// Render allowed prompts as action buttons
|
||||
if (input.allowedPrompts && input.allowedPrompts.length > 0) {
|
||||
html += '<div class="plan-actions">';
|
||||
html += '<div class="plan-actions-label">Suggested actions:</div>';
|
||||
input.allowedPrompts.forEach(function(p) {
|
||||
var label = p.prompt || (p.tool + ' command');
|
||||
var escapedPrompt = escapeHtml(label).replace(/'/g, ''');
|
||||
html += '<button class="plan-action-btn" onclick="sendPlanAction('' + escapedPrompt + '')" title="' + escapeHtml(p.tool) + '">' + escapeHtml(label) + '</button>';
|
||||
});
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
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
|
||||
</div>
|
||||
</div>
|
||||
<div class="permission-content">
|
||||
<p>Allow <strong>\${toolName}</strong> to execute the tool call above?</p>
|
||||
<p>\${data.tool === 'ExitPlanMode' ? 'Approve the plan above?' : 'Allow <strong>' + toolName + '</strong> to execute the tool call above?'}</p>
|
||||
<div class="permission-buttons">
|
||||
<button class="btn deny" onclick="respondToPermission('\${data.id}', false)">Deny</button>
|
||||
<button class="btn always-allow" onclick="respondToPermission('\${data.id}', true, true)" \${alwaysAllowTooltip}>\${alwaysAllowText}</button>
|
||||
<button class="btn allow" onclick="respondToPermission('\${data.id}', true)">Allow</button>
|
||||
\${data.tool === 'ExitPlanMode' ? '' : '<button class="btn always-allow" onclick="respondToPermission(\\'' + data.id + '\\', true, true)" ' + alwaysAllowTooltip + '>' + alwaysAllowText + '</button>'}
|
||||
<button class="btn allow" onclick="respondToPermission('\${data.id}', true)">\${data.tool === 'ExitPlanMode' ? 'Approve' : 'Allow'}</button>
|
||||
</div>
|
||||
</div>
|
||||
\`;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user