feat: improve VS Code editor chat actions

Targets active editor chat before falling back to sidebar
Adds session open-in-editor action in the VS Code sidebar
Uses attachment badges for VS Code file and selection context
This commit is contained in:
Bohdan Triapitsyn
2026-05-19 15:53:54 +03:00
parent 25037ccab9
commit c81441ecfc
13 changed files with 389 additions and 30 deletions
+39 -21
View File
@@ -288,20 +288,24 @@ export async function activate(context: vscode.ExtensionContext) {
// Get file info for context
const filePath = vscode.workspace.asRelativePath(editor.document.uri);
const languageId = editor.document.languageId;
// Get line numbers (1-based for display)
const startLine = selection.start.line + 1;
const endLine = selection.end.line + 1;
const lineRange = startLine === endLine ? `${startLine}` : `${startLine}-${endLine}`;
// Format as file path with line numbers, followed by markdown code block
const contextText = `${filePath}:${lineRange}\n\`\`\`${languageId}\n${selectedText}\n\`\`\``;
const filename = `${editor.document.fileName.split(/[\\/]/).pop() || filePath}:${lineRange}`;
const contextSelection = {
filePath: editor.document.uri.fsPath,
filename,
text: selectedText,
};
if (!(await revealChatViewForPayload())) {
return;
if (!sessionEditorProvider?.addContextSelectionToActivePanel(contextSelection)) {
if (!(await revealChatViewForPayload())) {
return;
}
chatViewProvider?.addContextSelection(contextSelection);
}
chatViewProvider?.addTextToInput(contextText);
})
);
@@ -322,7 +326,7 @@ export async function activate(context: vscode.ExtensionContext) {
}
const uniqueUris = Array.from(new Map(uriCandidates.map((uri) => [uri.toString(), uri])).values());
const mentionPaths: string[] = [];
const attachedFiles: Array<{ filePath: string; fileName: string; fileSize: number | null }> = [];
const skippedEntries: string[] = [];
for (const uri of uniqueUris) {
@@ -342,23 +346,33 @@ export async function activate(context: vscode.ExtensionContext) {
continue;
}
const relativePath = vscode.workspace.asRelativePath(uri, false).replace(/\\/g, '/').trim();
if (!relativePath) {
const filePath = uri.fsPath.trim();
const fileName = uri.fsPath.replace(/\\/g, '/').split('/').pop() || vscode.workspace.asRelativePath(uri, false).replace(/\\/g, '/').trim();
if (!filePath || !fileName) {
skippedEntries.push(uri.fsPath || uri.toString());
continue;
}
mentionPaths.push(relativePath);
let fileSize: number | null = null;
try {
const stat = await vscode.workspace.fs.stat(uri);
fileSize = stat.size;
} catch {
fileSize = null;
}
attachedFiles.push({ filePath, fileName, fileSize });
}
if (mentionPaths.length === 0) {
if (attachedFiles.length === 0) {
vscode.window.showWarningMessage('OpenChamber: No file selected to mention');
return;
}
if (!(await revealChatViewForPayload())) {
return;
if (!sessionEditorProvider?.addFileAttachmentsToActivePanel(attachedFiles)) {
if (!(await revealChatViewForPayload())) {
return;
}
chatViewProvider?.addFileAttachments(attachedFiles);
}
chatViewProvider?.addFileMentions(mentionPaths);
if (skippedEntries.length > 0) {
vscode.window.showInformationMessage('OpenChamber: Some selected entries were skipped (folders or unsupported resources)');
@@ -392,10 +406,12 @@ export async function activate(context: vscode.ExtensionContext) {
prompt = `Explain the following Code / Text:\n\n${filePath}`;
}
if (!(await revealChatViewForPayload())) {
return;
if (!sessionEditorProvider?.createSessionWithPromptInActivePanel(prompt)) {
if (!(await revealChatViewForPayload())) {
return;
}
chatViewProvider?.createNewSessionWithPrompt(prompt);
}
chatViewProvider?.createNewSessionWithPrompt(prompt);
})
);
@@ -423,10 +439,12 @@ export async function activate(context: vscode.ExtensionContext) {
const prompt = `Improve the following Code:\n\n${filePath}:${lineRange}\n\`\`\`${languageId}\n${selectedText}\n\`\`\``;
if (!(await revealChatViewForPayload())) {
return;
if (!sessionEditorProvider?.createSessionWithPromptInActivePanel(prompt)) {
if (!(await revealChatViewForPayload())) {
return;
}
chatViewProvider?.createNewSessionWithPrompt(prompt);
}
chatViewProvider?.createNewSessionWithPrompt(prompt);
})
);