feat: improve VS Code dev flow and stabilize sidebar/chat behavior (#754)

* fix: improve session sidebar tooltip and truncation behavior

- Keep new-draft tooltip anchored to its trigger button
- Fix minimal-mode worktree/group header text truncation
- Tune minimal-mode right padding to reduce early label clipping

* fix: render reasoning through markdown pipeline

- Use Streamdown rendering for reasoning in live chat mode
- Remove italic styling from reasoning text
- Render expanded reasoning content with MarkdownRenderer

* chore: remove legacy electron dependencies

- Removed unused Electron packages from root and UI manifests
- Deleted obsolete Electron context menu type declaration
- Regenerated lockfile after dependency cleanup

* fix: handle non-repository folders in git status API

- Prevent 500 errors when status is requested outside a valid Git repo
- Improve repository detection using `git rev-parse --git-dir`
- Reduce noisy server logs for expected non-repo status checks

* fix unloaded session chat layout flicker

* fix: reduce noisy TTS status polling

Cache and dedupe TTS status requests, and only check provider availability when the related voice features are enabled so disabled voice setups stay quiet.

* perf: throttle background PR git status refreshes

* fix: improve VS Code Explorer file drop mentions in chat

- Add Explorer context action to insert selected files as @mentions.
- Handle Explorer drag-and-drop to prefill @file mentions instead of attachments.
- Prevent duplicate plain-path text when dropping multiple files.

* fix: deduplicate recent sessions in VS Code sidebar

- Hide sessions from main list when already shown in recent
- Apply dedup only in VS Code runtime
- Keep session search behavior unchanged

* feat: add true HMR dev flow for VS Code extension

- Load VS Code webview from Vite dev server with React refresh preamble
- Add `vscode:dev` runner that starts watchers and opens Extension Development Host
- Update VS Code dev docs and scripts to use the new HMR startup flow

* feat: polish VS Code session sidebar and attachment UX

- Add resizable sessions sidebar in VS Code layout
- Tighten session list spacing and hover behavior in VS Code
- Remove bulk file/image attach success toasts while keeping error toasts
This commit is contained in:
Bohdan Triapitsyn
2026-03-23 23:51:55 +02:00
committed by GitHub
parent ea6d4c4d43
commit 1231fd773e
39 changed files with 1441 additions and 791 deletions
+48 -15
View File
@@ -183,6 +183,50 @@ const guessMimeTypeFromExtension = (ext: string) => {
}
};
const hasUriScheme = (value: string): boolean => /^[A-Za-z][A-Za-z\d+.-]*:/.test(value);
const parseDroppedFileReference = (rawReference: string):
| { uri: vscode.Uri }
| { skipped: { name: string; reason: string } } => {
const trimmed = rawReference.trim().replace(/^['"]+|['"]+$/g, '');
if (!trimmed) {
return { skipped: { name: rawReference, reason: 'Empty drop reference' } };
}
if (hasUriScheme(trimmed)) {
try {
const parsed = vscode.Uri.parse(trimmed, true);
if (parsed.scheme !== 'file') {
return {
skipped: {
name: trimmed,
reason: `Unsupported URI scheme: ${parsed.scheme || 'unknown'}`,
},
};
}
return { uri: parsed };
} catch (error) {
return {
skipped: {
name: trimmed,
reason: error instanceof Error ? error.message : 'Invalid URI',
},
};
}
}
if (!path.isAbsolute(trimmed)) {
return {
skipped: {
name: trimmed,
reason: 'Drop reference is not an absolute file path',
},
};
}
return { uri: vscode.Uri.file(trimmed) };
};
const readUriAsAttachment = async (
uri: vscode.Uri,
fallbackName?: string,
@@ -1934,24 +1978,13 @@ export async function handleBridgeMessage(message: BridgeRequest, ctx?: BridgeCo
const dedupedUris = Array.from(new Set(uris.map((value) => value.trim())));
for (const rawUri of dedupedUris) {
let uri: vscode.Uri;
try {
uri = vscode.Uri.parse(rawUri, true);
} catch (error) {
skipped.push({
name: rawUri,
reason: error instanceof Error ? error.message : 'Invalid URI',
});
const parsed = parseDroppedFileReference(rawUri);
if ('skipped' in parsed) {
skipped.push(parsed.skipped);
continue;
}
if (uri.scheme !== 'file') {
skipped.push({
name: rawUri,
reason: `Unsupported URI scheme: ${uri.scheme}`,
});
continue;
}
const uri = parsed.uri;
const name = path.basename(uri.fsPath || uri.path || rawUri);