mirror of
https://github.com/andrepimenta/claude-code-chat.git
synced 2025-12-13 13:49:47 +00:00
plan first and thinking mode initial implementation
This commit is contained in:
@@ -181,7 +181,7 @@ class ClaudeChatProvider {
|
||||
message => {
|
||||
switch (message.type) {
|
||||
case 'sendMessage':
|
||||
this._sendMessageToClaude(message.text);
|
||||
this._sendMessageToClaude(message.text, message.planMode, message.thinkingMode);
|
||||
return;
|
||||
case 'newSession':
|
||||
this._newSession();
|
||||
@@ -259,11 +259,20 @@ class ClaudeChatProvider {
|
||||
}, 100);
|
||||
}
|
||||
|
||||
private async _sendMessageToClaude(message: string) {
|
||||
private async _sendMessageToClaude(message: string, planMode?: boolean, thinkingMode?: boolean) {
|
||||
const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
|
||||
const cwd = workspaceFolder ? workspaceFolder.uri.fsPath : process.cwd();
|
||||
|
||||
// Show user input in chat and save to conversation
|
||||
// Prepend mode instructions if enabled
|
||||
let actualMessage = message;
|
||||
if (planMode && !message.toLowerCase().includes('plan first')) {
|
||||
actualMessage = 'PLAN FIRST BEFORE MAKING ANY CHANGES, SHOW ME IN DETAIL WHAT YOU WILL CHANGE. DONT PROCEED BEFORE I ACCEPT IN A DIFFERENT MESSAGE: \n' + message;
|
||||
}
|
||||
if (thinkingMode && !actualMessage.toLowerCase().includes('think through')) {
|
||||
actualMessage = 'THINK THROUGH THIS STEP BY STEP: \n' + actualMessage;
|
||||
}
|
||||
|
||||
// Show original user input in chat and save to conversation (without mode prefixes)
|
||||
this._sendAndSaveMessage({
|
||||
type: 'userInput',
|
||||
data: message
|
||||
@@ -353,9 +362,9 @@ class ClaudeChatProvider {
|
||||
// Store process reference for potential termination
|
||||
this._currentClaudeProcess = claudeProcess;
|
||||
|
||||
// Send the message to Claude's stdin
|
||||
// Send the message to Claude's stdin (with mode prefixes if enabled)
|
||||
if (claudeProcess.stdin) {
|
||||
claudeProcess.stdin.write(message + '\n');
|
||||
claudeProcess.stdin.write(actualMessage + '\n');
|
||||
claudeProcess.stdin.end();
|
||||
}
|
||||
|
||||
|
||||
@@ -433,10 +433,67 @@ const styles = `
|
||||
padding: 10px;
|
||||
border-top: 1px solid var(--vscode-panel-border);
|
||||
background-color: var(--vscode-panel-background);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.input-modes {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
padding-bottom: 5px;
|
||||
font-size: 9.5px;
|
||||
}
|
||||
|
||||
.mode-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
color: var(--vscode-foreground);
|
||||
opacity: 0.8;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.mode-toggle:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.mode-switch {
|
||||
position: relative;
|
||||
width: 28px;
|
||||
height: 16px;
|
||||
background-color: var(--vscode-panel-border);
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.mode-switch.active {
|
||||
background-color: var(--vscode-button-background);
|
||||
}
|
||||
|
||||
.mode-switch::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background-color: var(--vscode-foreground);
|
||||
border-radius: 50%;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.mode-switch.active::after {
|
||||
transform: translateX(12px);
|
||||
background-color: var(--vscode-button-foreground);
|
||||
}
|
||||
|
||||
.textarea-container {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: flex-end;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.textarea-wrapper {
|
||||
|
||||
132
src/ui.ts
132
src/ui.ts
@@ -38,54 +38,66 @@ const html = `<!DOCTYPE html>
|
||||
<div class="chat-container" id="chatContainer">
|
||||
<div class="messages" id="messages"></div>
|
||||
<div class="input-container" id="inputContainer">
|
||||
<div class="textarea-wrapper">
|
||||
<textarea class="input-field" id="messageInput" placeholder="Type your message to Claude Code..." rows="1"></textarea>
|
||||
<div class="input-controls">
|
||||
<div class="left-controls">
|
||||
<button class="model-selector" id="modelSelector" onclick="showModelSelector()" title="Select model">
|
||||
<span id="selectedModel">Opus</span>
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="currentColor">
|
||||
<path d="M1 2.5l3 3 3-3"></path>
|
||||
<div class="input-modes">
|
||||
<div class="mode-toggle">
|
||||
<span>Plan First</span>
|
||||
<div class="mode-switch" id="planModeSwitch" onclick="togglePlanMode()"></div>
|
||||
</div>
|
||||
<div class="mode-toggle">
|
||||
<span>Thinking Mode</span>
|
||||
<div class="mode-switch" id="thinkingModeSwitch" onclick="toggleThinkingMode()"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="textarea-container">
|
||||
<div class="textarea-wrapper">
|
||||
<textarea class="input-field" id="messageInput" placeholder="Type your message to Claude Code..." rows="1"></textarea>
|
||||
<div class="input-controls">
|
||||
<div class="left-controls">
|
||||
<button class="model-selector" id="modelSelector" onclick="showModelSelector()" title="Select model">
|
||||
<span id="selectedModel">Opus</span>
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="currentColor">
|
||||
<path d="M1 2.5l3 3 3-3"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="tools-btn" onclick="showToolsModal()" title="Configure tools">
|
||||
Tools: All
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="currentColor">
|
||||
<path d="M1 2.5l3 3 3-3"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="right-controls">
|
||||
<button class="at-btn" onclick="showFilePicker()" title="Reference files">@</button>
|
||||
<button class="image-btn" id="imageBtn" onclick="selectImage()" title="Attach images">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="14"
|
||||
height="16"
|
||||
>
|
||||
<g fill="currentColor">
|
||||
<path d="M6.002 5.5a1.5 1.5 0 1 1-3 0a1.5 1.5 0 0 1 3 0"></path>
|
||||
<path d="M1.5 2A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h13a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 14.5 2zm13 1a.5.5 0 0 1 .5.5v6l-3.775-1.947a.5.5 0 0 0-.577.093l-3.71 3.71l-2.66-1.772a.5.5 0 0 0-.63.062L1.002 12v.54L1 12.5v-9a.5.5 0 0 1 .5-.5z"></path>
|
||||
</g>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="tools-btn" onclick="showToolsModal()" title="Configure tools">
|
||||
Tools: All
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="currentColor">
|
||||
<path d="M1 2.5l3 3 3-3"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="right-controls">
|
||||
<button class="at-btn" onclick="showFilePicker()" title="Reference files">@</button>
|
||||
<button class="image-btn" id="imageBtn" onclick="selectImage()" title="Attach images">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="14"
|
||||
height="16"
|
||||
>
|
||||
<g fill="currentColor">
|
||||
<path d="M6.002 5.5a1.5 1.5 0 1 1-3 0a1.5 1.5 0 0 1 3 0"></path>
|
||||
<path d="M1.5 2A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h13a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 14.5 2zm13 1a.5.5 0 0 1 .5.5v6l-3.775-1.947a.5.5 0 0 0-.577.093l-3.71 3.71l-2.66-1.772a.5.5 0 0 0-.63.062L1.002 12v.54L1 12.5v-9a.5.5 0 0 1 .5-.5z"></path>
|
||||
</g>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="send-btn" id="sendBtn" onclick="sendMessage()">
|
||||
<div>
|
||||
<span>Send </span>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width="11"
|
||||
height="11"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M20 4v9a4 4 0 0 1-4 4H6.914l2.5 2.5L8 20.914L3.086 16L8 11.086L9.414 12.5l-2.5 2.5H16a2 2 0 0 0 2-2V4z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
</button>
|
||||
</button>
|
||||
<button class="send-btn" id="sendBtn" onclick="sendMessage()">
|
||||
<div>
|
||||
<span>Send </span>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width="11"
|
||||
height="11"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M20 4v9a4 4 0 0 1-4 4H6.914l2.5 2.5L8 20.914L3.086 16L8 11.086L9.414 12.5l-2.5 2.5H16a2 2 0 0 0 2-2V4z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -299,6 +311,8 @@ const html = `<!DOCTYPE html>
|
||||
let isProcessRunning = false;
|
||||
let filteredFiles = [];
|
||||
let selectedFileIndex = -1;
|
||||
let planModeEnabled = false;
|
||||
let thinkingModeEnabled = false;
|
||||
|
||||
function addMessage(content, type = 'claude') {
|
||||
const messageDiv = document.createElement('div');
|
||||
@@ -560,13 +574,35 @@ const html = `<!DOCTYPE html>
|
||||
if (text) {
|
||||
vscode.postMessage({
|
||||
type: 'sendMessage',
|
||||
text: text
|
||||
text: text,
|
||||
planMode: planModeEnabled,
|
||||
thinkingMode: thinkingModeEnabled
|
||||
});
|
||||
|
||||
messageInput.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
function togglePlanMode() {
|
||||
planModeEnabled = !planModeEnabled;
|
||||
const switchElement = document.getElementById('planModeSwitch');
|
||||
if (planModeEnabled) {
|
||||
switchElement.classList.add('active');
|
||||
} else {
|
||||
switchElement.classList.remove('active');
|
||||
}
|
||||
}
|
||||
|
||||
function toggleThinkingMode() {
|
||||
thinkingModeEnabled = !thinkingModeEnabled;
|
||||
const switchElement = document.getElementById('thinkingModeSwitch');
|
||||
if (thinkingModeEnabled) {
|
||||
switchElement.classList.add('active');
|
||||
} else {
|
||||
switchElement.classList.remove('active');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let totalCost = 0;
|
||||
let totalTokensInput = 0;
|
||||
|
||||
Reference in New Issue
Block a user