From 3f8cfea6c8a0ff3c07933485ba7890adfafb1676 Mon Sep 17 00:00:00 2001 From: Marius Date: Thu, 19 Feb 2026 20:25:27 +0100 Subject: [PATCH] feat(vscode): show loading spinner when closing a worktree in agent manager (#487) * feat(vscode): show loading spinner when closing a worktree in agent manager Replace the close button with a small spinner while the worktree is being removed from disk, so the UI feels responsive during the async operation. * Update README with Kilo Code content and demo gif * Update README.md Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com> * fix: add .vscode-test/ to kilo-vscode gitignore The @vscode/test-cli downloads VS Code Electron binaries into .vscode-test/ when running extension tests. This directory was not gitignored, causing 1000+ test artifacts to appear in diffs. --------- Co-authored-by: Mark IJbema Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com> --- .../agent-manager/AgentManagerApp.tsx | 26 +++++++++++++------ .../agent-manager/agent-manager.css | 6 +++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx b/packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx index 4df7951e754..1ca56ea2b3f 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx +++ b/packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx @@ -59,6 +59,7 @@ const AgentManagerContent: Component = () => { const [managedSessions, setManagedSessions] = createSignal([]) const [selection, setSelection] = createSignal(LOCAL) const [repoBranch, setRepoBranch] = createSignal() + const [deletingWorktrees, setDeletingWorktrees] = createSignal>(new Set()) // Recover persisted local session IDs from webview state const persisted = vscode.getState<{ localSessionIDs?: string[] }>() @@ -342,6 +343,12 @@ const AgentManagerContent: Component = () => { const ms = state.sessions.find((s) => s.id === current) if (ms?.worktreeId) setSelection(ms.worktreeId) } + // Clear deleting state for worktrees that have been removed + const ids = new Set(state.worktrees.map((wt) => wt.id)) + setDeletingWorktrees((prev) => { + const next = new Set([...prev].filter((id) => ids.has(id))) + return next.size === prev.size ? prev : next + }) } }) @@ -371,6 +378,7 @@ const AgentManagerContent: Component = () => { const wt = worktrees().find((w) => w.id === worktreeId) if (!wt) return const doDelete = () => { + setDeletingWorktrees((prev) => new Set([...prev, wt.id])) vscode.postMessage({ type: "agentManager.deleteWorktree", worktreeId: wt.id }) if (selection() === wt.id) { const next = nextSelectionAfterDelete( @@ -548,14 +556,16 @@ const AgentManagerContent: Component = () => { {worktreeLabel(wt)} - handleDeleteWorktree(wt.id, e)} - /> + }> + handleDeleteWorktree(wt.id, e)} + /> + )} diff --git a/packages/kilo-vscode/webview-ui/agent-manager/agent-manager.css b/packages/kilo-vscode/webview-ui/agent-manager/agent-manager.css index aa6eb9805c9..7695575a26f 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/agent-manager.css +++ b/packages/kilo-vscode/webview-ui/agent-manager/agent-manager.css @@ -167,6 +167,12 @@ opacity: 1; } +.am-worktree-spinner { + width: 16px; + height: 16px; + flex-shrink: 0; +} + /* Session list */ .am-list {