Skip to content

Commit eddde7c

Browse files
committed
feat: Implement file creation confirmation and handling in chat responses
1 parent ac85547 commit eddde7c

2 files changed

Lines changed: 69 additions & 33 deletions

File tree

vscode-extension/src/extension.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,28 @@ async function handleChatMessage(message: any) {
228228
const isCode = response.completion_type === 'code';
229229
console.log('Sending message to webview:', isCode ? 'codeResponse' : 'chatResponse', response.completion);
230230

231+
// Detect file creation intent (e.g., response starts with 'Filename: ...')
232+
const fileMatch = response.completion.match(/^Filename:\s*(\S+)\s*\n([\s\S]*)/);
233+
if (fileMatch) {
234+
const filename = fileMatch[1];
235+
const fileContent = fileMatch[2].trim();
236+
// Ask user to confirm file creation
237+
const confirm = await vscode.window.showInformationMessage(
238+
`AI wants to create file: ${filename}. Proceed?`,
239+
'Create', 'Cancel'
240+
);
241+
if (confirm === 'Create') {
242+
await createFileInWorkspace(filename, fileContent);
243+
vscode.window.showInformationMessage(`File '${filename}' created!`);
244+
}
245+
currentPanel?.webview.postMessage({
246+
type: 'chatResponse',
247+
content: `File creation: ${filename}\n\n${fileContent}`,
248+
loading: false
249+
});
250+
return;
251+
}
252+
231253
if (isCode) {
232254
currentPanel?.webview.postMessage({
233255
type: 'codeResponse',
@@ -243,6 +265,21 @@ async function handleChatMessage(message: any) {
243265
loading: false
244266
});
245267
}
268+
// Create a new file in the workspace
269+
async function createFileInWorkspace(filename: string, content: string) {
270+
const folders = vscode.workspace.workspaceFolders;
271+
if (!folders || folders.length === 0) {
272+
vscode.window.showErrorMessage('No workspace folder open.');
273+
return;
274+
}
275+
const folderUri = folders[0].uri;
276+
const fileUri = vscode.Uri.joinPath(folderUri, filename);
277+
try {
278+
await vscode.workspace.fs.writeFile(fileUri, Buffer.from(content, 'utf8'));
279+
} catch (e) {
280+
vscode.window.showErrorMessage(`Failed to create file: ${e}`);
281+
}
282+
}
246283

247284
} catch (err: any) {
248285
console.error('Exception in handleChatMessage:', err);

vscode-extension/src/webview.js

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,44 +14,43 @@ alert('Webview loaded!');
1414
messageDiv.className = `message ${type}`;
1515

1616
if (isCode) {
17+
// Detect file creation pattern
18+
const fileMatch = content.match(/^Filename:\s*(\S+)\s*\n([\s\S]*)/);
1719
const pre = document.createElement('pre');
1820
const code = document.createElement('code');
1921
code.textContent = content;
2022
pre.appendChild(code);
2123
messageDiv.appendChild(pre);
22-
23-
// Add action buttons for code
24-
const actionsDiv = document.createElement('div');
25-
actionsDiv.className = 'code-actions';
26-
27-
const insertBtn = document.createElement('button');
28-
insertBtn.textContent = 'Insert at Cursor';
29-
insertBtn.onclick = () => {
30-
vscode.postMessage({
31-
type: 'insertCode',
32-
code: content
33-
});
34-
};
35-
36-
const replaceBtn = document.createElement('button');
37-
replaceBtn.textContent = 'Replace Selection';
38-
replaceBtn.onclick = () => {
39-
vscode.postMessage({
40-
type: 'replaceCode',
41-
code: content
42-
});
43-
};
44-
45-
const copyBtn = document.createElement('button');
46-
copyBtn.textContent = 'Copy';
47-
copyBtn.onclick = () => {
48-
navigator.clipboard.writeText(content);
49-
};
50-
51-
actionsDiv.appendChild(insertBtn);
52-
actionsDiv.appendChild(replaceBtn);
53-
actionsDiv.appendChild(copyBtn);
54-
messageDiv.appendChild(actionsDiv);
24+
if (!fileMatch) {
25+
// Add action buttons for code (not for file creation)
26+
const actionsDiv = document.createElement('div');
27+
actionsDiv.className = 'code-actions';
28+
const insertBtn = document.createElement('button');
29+
insertBtn.textContent = 'Insert at Cursor';
30+
insertBtn.onclick = () => {
31+
vscode.postMessage({
32+
type: 'insertCode',
33+
code: content
34+
});
35+
};
36+
const replaceBtn = document.createElement('button');
37+
replaceBtn.textContent = 'Replace Selection';
38+
replaceBtn.onclick = () => {
39+
vscode.postMessage({
40+
type: 'replaceCode',
41+
code: content
42+
});
43+
};
44+
const copyBtn = document.createElement('button');
45+
copyBtn.textContent = 'Copy';
46+
copyBtn.onclick = () => {
47+
navigator.clipboard.writeText(content);
48+
};
49+
actionsDiv.appendChild(insertBtn);
50+
actionsDiv.appendChild(replaceBtn);
51+
actionsDiv.appendChild(copyBtn);
52+
messageDiv.appendChild(actionsDiv);
53+
}
5554
} else {
5655
// Format text with markdown-like support
5756
const formattedContent = formatText(content);

0 commit comments

Comments
 (0)