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
+1 -1
View File
@@ -29,7 +29,7 @@
"@fontsource/ibm-plex-sans": "^5.1.1",
"@ibm/plex": "^6.4.1",
"@octokit/rest": "^22.0.1",
"@opencode-ai/sdk": "^1.2.27",
"@opencode-ai/sdk": "^1.3.0",
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
+15
View File
@@ -12021,6 +12021,17 @@ async function main(options = {}) {
app.get('/api/git/status', async (req, res) => {
const { getStatus, isGitRepository } = await getGitLibraries();
const extractGitErrorText = (error) => {
const message = typeof error?.message === 'string' ? error.message : '';
const stderr = typeof error?.stderr === 'string' ? error.stderr : '';
const stdout = typeof error?.stdout === 'string' ? error.stdout : '';
return [message, stderr, stdout]
.map((value) => String(value || '').trim())
.filter(Boolean)
.join('\n');
};
try {
const directory = req.query.directory;
if (!directory) {
@@ -12035,6 +12046,10 @@ async function main(options = {}) {
const status = await getStatus(directory);
res.json(status);
} catch (error) {
const errorText = extractGitErrorText(error);
if (/not a git repository/i.test(errorText)) {
return res.json({ isGitRepository: false, files: [], branch: null, ahead: 0, behind: 0 });
}
console.error('Failed to get git status:', error);
res.status(500).json({ error: error.message || 'Failed to get git status' });
}
+10 -3
View File
@@ -563,6 +563,11 @@ const parseGitErrorText = (error) => {
.trim();
};
const isNotGitRepositoryError = (error) => {
const text = parseGitErrorText(error);
return /not a git repository/i.test(text);
};
const runGitCommand = async (cwd, args) => {
try {
const { stdout, stderr } = await execFileAsync(getGitBinary(), args, {
@@ -1065,8 +1070,8 @@ export async function isGitRepository(directory) {
return false;
}
const gitDir = path.join(directoryPath, '.git');
return fs.existsSync(gitDir);
const result = await runGitCommand(directoryPath, ['rev-parse', '--git-dir']);
return result.success;
}
export async function getGlobalIdentity() {
@@ -1411,7 +1416,9 @@ export async function getStatus(directory) {
rebaseInProgress,
};
} catch (error) {
console.error('Failed to get Git status:', error);
if (!isNotGitRepositoryError(error)) {
console.error('Failed to get Git status:', error);
}
throw error;
}
}