Skip to content

fix(agent-manager): restore focus to question options and prompt on session switch - #12795

Merged
marius-kilocode merged 4 commits into
mainfrom
fix-agent-manager-focus-on-switch
Aug 3, 2026
Merged

fix(agent-manager): restore focus to question options and prompt on session switch#12795
marius-kilocode merged 4 commits into
mainfrom
fix-agent-manager-focus-on-switch

Conversation

@marius-kilocode

Copy link
Copy Markdown
Collaborator

Problem

When switching between Agent Manager sessions using keyboard shortcuts (Meta+Alt+ArrowLeft/Right), focus would be lost and remain on the webview body instead of being restored to the appropriate UI element:

  • Question options in sessions with pending questions
  • Prompt textarea in sessions without questions

This made keyboard-only navigation impossible when switching to a session with a question, requiring users to click with the mouse.

Root Causes

Two focus race conditions:

  1. Keyboard tab switching bypassed focus restoration: The Meta+Alt+ArrowLeft/Right shortcut used focusTab() which changed the active session but did not invoke the focus restoration logic.

  2. VS Code focus transition timing: During keyboard command execution, document.hasFocus() was temporarily false, causing the focus restoration code to return early without scheduling a retry. The previous focused element was removed during the session switch, leaving focus on the webview <body>.

  3. Question mount timing: Question UI mounted slightly after the session switch. The prompt input could autofocus while the question was still rendering, and nothing reliably moved focus to the question option once it appeared.

Solution

  • Route keyboard tab switching through the coordinated focus restoration path
  • Retry focus across the render lifecycle using queueMicrotask and multiple requestAnimationFrame calls to handle VS Code focus transitions
  • Add a createEffect that focuses the first enabled question option after the question dock mounts
  • Focus prompt textarea for sessions without pending questions
  • Preserve focus when terminal, history, or review surfaces are active
  • Add focusQuestionOption helper with unit tests covering enabled/disabled states and inert containers

Testing

Verified in isolated VS Code:

  • Session A with pending question → Session B (prompt) → Session A: question option receives focus
  • Session B (prompt) → Session A (question) → Session B: prompt receives focus
  • Arrow key navigation through question options after keyboard switch

All regression tests pass (38 tests across focus and question dock suites).

Files Changed

  • AgentManagerApp.tsx: Added requestChatFocus coordinator and question mount effect
  • PromptInput.tsx: Skip prompt autofocus when question is present
  • focus.ts: New focusQuestionOption helper
  • agent-manager-focus.test.ts: Unit tests for focus helper
  • fix-agent-manager-focus.md: Changeset for patch release

…ession switch

- Route keyboard tab switching (Meta+Alt+ArrowLeft/Right) through coordinated focus path
- Retry focus across render lifecycle to handle VS Code focus transitions
- Focus first enabled question option after question dock mounts
- Focus prompt textarea for sessions without pending questions
- Preserve focus when terminal, history, or review surfaces are active
- Add focusQuestionOption helper with unit tests
- Add changeset for patch release

Fixes race conditions where keyboard navigation would leave focus on webview body instead of the intended question option or prompt input.
@marius-kilocode
marius-kilocode enabled auto-merge (squash) August 3, 2026 09:36
Comment thread packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx Outdated
Comment thread packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx Outdated
Comment thread packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx Outdated
Comment thread packages/kilo-vscode/webview-ui/agent-manager/focus.ts Outdated
Comment thread packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx Outdated
@kilo-code-bot

kilo-code-bot Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 1
Issue Details (click to expand)

WARNING

File Line Issue
packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx 388 The new scopedQuestions().length > 0 bail-out suppresses the prompt fallback even when no focusable question option exists in the DOM (subagent tool question, review/confirm step, collapsed inert dock, reply in flight, virtualized/loading transcript), leaving focus on <body>

SUGGESTION

File Line Issue
packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx 419 The question effect body is now a verbatim copy of requestChatFocus's inner focus(); calling requestChatFocus() would drop the duplicated guards and give a late-mounting dock more frames
Files Reviewed (3 files)
  • packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx - 2 issues
  • packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx - no issues (prop rename pass-through only)
  • packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx - no issues (the defer() guard is re-evaluated per retry, so it correctly cancels late restore attempts)

Resolved since the previous review: the question effect regained the hasFocus / terminal / history / review guards; the restore retry chain (out to +50ms) now re-checks deferFocusToQuestion on every attempt, so it no longer steals focus back from a just-focused question option; focusOnSwitch was renamed to deferFocusToQuestion, which matches its behavior.

Incremental review scope: only the three files changed since 61467b8. No new listeners, timers, or subscriptions were added, so no new leaks; the focusPrompt listener is still cleaned up in onCleanup. No shared opencode files touched, so fork-merge hygiene is unaffected.

Fix these issues in Kilo Cloud

Previous Review Summaries (2 snapshots, latest commit 61467b8)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 61467b8)

Status: 3 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 1
Issue Details (click to expand)

WARNING

File Line Issue
packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx 410 The rewritten question effect dropped the document.hasFocus() / terms.activeId() / history() / reviewActive() guards; a question arriving for the current session can now pull focus out of a VS Code editor or off an active terminal/history/review surface, and it disagrees with requestChatFocus, which still honors them
packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx 928 requestChatFocus(true) falls back to focusPrompt with restore, whose retries run out to +50ms in PromptInput; if question data loads asynchronously after the switch, the late retry steals focus back from the just-focused question option

SUGGESTION

File Line Issue
packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx 112 focusOnSwitch reads as the opposite of its behavior (it suppresses prompt autofocus) and is absent exactly where the prompt does focus on switch
Files Reviewed (4 files)
  • packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx - 2 issues
  • packages/kilo-vscode/webview-ui/agent-manager/focus.ts - no issues (scoped selector + closest("[inert]") is equivalent to the removed ancestor walk and still satisfies the existing happy-dom tests)
  • packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx - no issues (prop pass-through only)
  • packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx - 1 issue

Resolved since the previous review: the forced refocus was removed from focusTab/selectSessionTab so tab-strip roving focus is no longer fought; focusInput is back on the forced path; the question effect is now keyed via on(...) and guards the custom-answer input; focus.ts uses a scoped selector; PromptInput no longer sniffs the agent-manager: boxId prefix.

No new memory or resource leaks: the added requestAnimationFrame chains are one-shot and the effect is owned by the component scope. No shared opencode files touched, so fork-merge hygiene is unaffected.

Fix these issues in Kilo Cloud

Previous review (commit 21cc7b4)

Status: 5 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 2
Issue Details (click to expand)

WARNING

File Line Issue
packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx 2149 requestChatFocus(true) inside focusTab also runs on the tab strip's roving-focus path (onTabKey -> handleTabKey -> focusTabElement), stealing focus off the role="tab" element one frame later and breaking sequential arrow navigation
packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx 398 New effect tracks the global questions() signal via scopedQuestions, so unrelated question changes re-run it; focusQuestionOption does not honor the dock's editing/confirm guards, so focus can be pulled out of the custom-answer input
packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx 1144 Host-initiated focusInput (focusChatInput command, panel reveal) now goes through the non-forced path gated on document.hasFocus(), which the PR itself documents as transiently false during VS Code command execution

SUGGESTION

File Line Issue
packages/kilo-vscode/webview-ui/agent-manager/focus.ts 3 Document-wide button scan plus manual ancestor walk; a scoped selector + closest("[inert]") matches QuestionDock's existing selector and removes three lets
packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx 384 Shared component branches on the agent-manager: boxId prefix; skipping the dispatch has no fallback when focusQuestionOption() cannot focus anything (collapsed dock, confirm step, event-driven selectSession paths)
Files Reviewed (5 files)
  • .changeset/fix-agent-manager-focus.md - no issues (user-facing wording reads well)
  • packages/kilo-vscode/tests/unit/agent-manager-focus.test.ts - no issues (real DOM via happy-dom, no mocks); note it covers only the helper, not the new effect/coordinator behavior
  • packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx - 3 issues
  • packages/kilo-vscode/webview-ui/agent-manager/focus.ts - 1 issue
  • packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx - 1 issue

No new memory/resource leaks found: the added requestAnimationFrame chains are one-shot and the existing focus listener keeps its onCleanup. No changes to shared opencode files, so fork-merge hygiene is unaffected.

Fix these issues in Kilo Cloud


Reviewed by claude-opus-5 · Input: 54 · Output: 15.1K · Cached: 2.1M

Review guidance: REVIEW.md from base branch main

Comment thread packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx Outdated
Comment thread packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx
Comment thread packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx Outdated
Comment thread packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx Outdated
Comment thread packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx Outdated
@marius-kilocode
marius-kilocode merged commit 37559f8 into main Aug 3, 2026
23 checks passed
@marius-kilocode
marius-kilocode deleted the fix-agent-manager-focus-on-switch branch August 3, 2026 15:08
t7tran pushed a commit to t7tran/kilocode that referenced this pull request Aug 14, 2026
…ession switch (Kilo-Org#12795)

* fix(agent-manager): restore focus to question options and prompt on session switch

- Route keyboard tab switching (Meta+Alt+ArrowLeft/Right) through coordinated focus path
- Retry focus across render lifecycle to handle VS Code focus transitions
- Focus first enabled question option after question dock mounts
- Focus prompt textarea for sessions without pending questions
- Preserve focus when terminal, history, or review surfaces are active
- Add focusQuestionOption helper with unit tests
- Add changeset for patch release

Fixes race conditions where keyboard navigation would leave focus on webview body instead of the intended question option or prompt input.

* fix(agent-manager): preserve tab and question focus ownership

* fix(agent-manager): guard deferred focus during async questions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants