fix(vscode): render active questions only in the bottom dock (#6983)

* fix duplicate question dock rendering in VS Code chat

* chore: update kilo-vscode visual regression baselines

* fix readonly question dock fallback in subagent viewer

* chore: update kilo-vscode visual regression baselines

* revert question story rename snapshot churn

* remove question snapshot rename churn

* chore: update kilo-vscode visual regression baselines

* remove obsolete inline question visual story

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Marius
2026-03-12 13:21:35 +01:00
committed by GitHub
co-authored by github-actions[bot]
parent 5787dd59fd
commit 652647b2ed
4 changed files with 7 additions and 36 deletions
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8c4c2ba388cdfc687b14343aa672b22badd1164b2dbab6e99a99c983b0179f13
size 34924
@@ -4,8 +4,7 @@
* Unlike the upstream AssistantParts, this renders each read/glob/grep/list tool
* individually for maximum verbosity in the VS Code sidebar context.
*
* Questions with a tool context are rendered inline with their tool call.
* Permissions are rendered in the bottom dock (PermissionDock).
* Active questions and permissions are rendered in the bottom dock.
*/
import { Component, For, Show, createMemo } from "solid-js"
@@ -18,8 +17,6 @@ import type {
ToolPart,
} from "@kilocode/sdk/v2"
import { useData } from "@kilocode/kilo-ui/context/data"
import { useSession } from "../../context/session"
import { QuestionDock } from "./QuestionDock"
// Tools that the upstream message-part renderer suppresses (returns null for).
// We render these ourselves via ToolRegistry when they complete,
@@ -70,9 +67,6 @@ function TodoToolCard(props: { part: ToolPart }) {
export const AssistantMessage: Component<AssistantMessageProps> = (props) => {
const data = useData()
const session = useSession()
const questions = () => session.questions().filter((q) => q.sessionID === session.currentSessionID() && q.tool)
const parts = createMemo(() => {
const stored = data.store.part?.[props.message.id]
@@ -80,9 +74,6 @@ export const AssistantMessage: Component<AssistantMessageProps> = (props) => {
return (stored as SDKPart[]).filter((part) => isRenderable(part))
})
// Questions linked to this message (rendered after the last part)
const questionForMessage = () => questions().find((q) => q.tool!.messageID === props.message.id)
return (
<>
<For each={parts()}>
@@ -112,9 +103,6 @@ export const AssistantMessage: Component<AssistantMessageProps> = (props) => {
)
}}
</For>
<Show when={questionForMessage()} keyed>
{(req) => <QuestionDock request={req} />}
</Show>
</>
)
}
@@ -76,6 +76,7 @@ export const ChatView: Component<ChatViewProps> = (props) => {
scopedQuestions()[0]
const permissionRequest = () => scopedPermissions().find((p) => p.sessionID === id()) ?? scopedPermissions()[0]
const blocked = () => scopedPermissions().length > 0 || scopedQuestions().length > 0
const dock = () => !props.readonly || !!questionRequest() || !!permissionRequest()
// When a bottom-dock permission/question disappears while the session is busy,
// the scroll container grows taller. Dispatch a custom event so MessageList can
@@ -115,7 +116,7 @@ export const ChatView: Component<ChatViewProps> = (props) => {
</div>
</div>
<Show when={!props.readonly}>
<Show when={dock()}>
<div class="chat-input">
<Show when={questionRequest()} keyed>
{(req) => <QuestionDock request={req} />}
@@ -129,7 +130,7 @@ export const ChatView: Component<ChatViewProps> = (props) => {
/>
)}
</Show>
<Show when={hasMessages() && idle() && !blocked()}>
<Show when={!props.readonly && hasMessages() && idle() && !blocked()}>
<div class="new-task-button-wrapper">
<Button
variant="secondary"
@@ -154,7 +155,9 @@ export const ChatView: Component<ChatViewProps> = (props) => {
</Show>
</div>
</Show>
<PromptInput />
<Show when={!props.readonly}>
<PromptInput />
</Show>
</div>
</Show>
</div>
@@ -545,23 +545,6 @@ export const MultipleToolCalls: Story = {
},
}
// ---------------------------------------------------------------------------
// 8. Inline question (tool-linked question rendered in message flow)
// ---------------------------------------------------------------------------
export const InlineQuestion: Story = {
name: "Inline Question",
render: () => {
const qs = [questionRequest]
const data = dataWith([textPart, questionToolPart])
return (
<StoryProviders data={data} questions={qs} sessionID={SESSION_ID}>
<AssistantMessage message={baseAssistantMessage} />
</StoryProviders>
)
},
}
// ---------------------------------------------------------------------------
// 9. Dismissed question (right-aligned "Questions dismissed" text)
// ---------------------------------------------------------------------------