diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/chat/question-dock-multi-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/chat/question-dock-multi-chromium-linux.png
index 45711758e1c..42623d20283 100644
--- a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/chat/question-dock-multi-chromium-linux.png
+++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/chat/question-dock-multi-chromium-linux.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:550464711e0d3aab99fa514d6de9501be19e49b65d5643b7762fb7b5ca47464c
-size 19715
+oid sha256:b8b1ba56d6632bfcbd0e4c5b0c1514cd80832339dde0c86568572ada656ca33d
+size 24134
diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/chat/question-dock-single-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/chat/question-dock-single-chromium-linux.png
index 5f33984b45c..21f6afd99c2 100644
--- a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/chat/question-dock-single-chromium-linux.png
+++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/chat/question-dock-single-chromium-linux.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:2cdb43fe23e17f32dd96b36eb3b2f97b4b84c29983996f26406db6ead2f41785
-size 25707
+oid sha256:278855516fe11d95b9de942d9690531c114b0a0b9ac0239c2ef31f82b420bd7e
+size 32467
diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/inline-question-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/inline-question-chromium-linux.png
index 78ab5e57fcb..d25eccfaf9e 100644
--- a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/inline-question-chromium-linux.png
+++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/inline-question-chromium-linux.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:18bd63c206b2afc5d8d05e06a8a1113c7dfa1019e85eebe570be40419dbe35fd
-size 28187
+oid sha256:f6193ba79b4d5dda29bf39d1127dacd7e332755d1f6f42dd67ff667088975659
+size 35678
diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/question-dismissed-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/question-dismissed-chromium-linux.png
new file mode 100644
index 00000000000..f7e30521e5a
--- /dev/null
+++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/question-dismissed-chromium-linux.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:607707e2201d1e50369a5897266136387b2444570b61ac2062c658335a0cdcc7
+size 5055
diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/QuestionDock.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/QuestionDock.tsx
index a03a77c1eb6..ee97a5dcb10 100644
--- a/packages/kilo-vscode/webview-ui/src/components/chat/QuestionDock.tsx
+++ b/packages/kilo-vscode/webview-ui/src/components/chat/QuestionDock.tsx
@@ -1,12 +1,13 @@
/**
* QuestionDock component
* Displays question requests from the AI assistant inline above the prompt input.
- * Uses kilo-ui's data-component/data-slot CSS pattern for styling.
+ * Uses kilo-ui's DockPrompt component for proper surface styling.
*/
import { Component, For, Show, createMemo, createEffect } from "solid-js"
import { createStore } from "solid-js/store"
import { Button } from "@kilocode/kilo-ui/button"
+import { DockPrompt } from "@kilocode/kilo-ui/dock-prompt"
import { Icon } from "@kilocode/kilo-ui/icon"
import { useSession } from "../../context/session"
import { useLanguage } from "../../context/language"
@@ -148,10 +149,11 @@ export const QuestionDock: Component<{ request: QuestionRequest }> = (props) =>
}
return (
-
e.stopPropagation()}>
-
-
-
+
e.stopPropagation()}>
+
{summary()}
@@ -177,62 +179,65 @@ export const QuestionDock: Component<{ request: QuestionRequest }> = (props) =>
-
-
-
-
-
{question()?.question}
-
{language.t("ui.question.singleHint")} }
- >
- {language.t("ui.question.multiHint")}
+ >
+ }
+ footer={
+ <>
+
+
+
0}>
+
-
-
- {(opt, i) => {
- const picked = () => store.answers[store.tab]?.includes(opt.label) ?? false
- return (
-
- )
- }}
-
-
+ selectTab(store.tab + 1)}
+ disabled={store.sending || (!confirm() && (store.answers[store.tab]?.length ?? 0) === 0)}
+ >
+ {last() && single()
+ ? language.t("ui.common.submit")
+ : last()
+ ? language.t("common.review")
+ : language.t("ui.common.next")}
+
+ }
+ >
+
+
+
+ >
+ }
+ >
+
+ {question()?.question}
+ {language.t("ui.question.singleHint")} }>
+ {language.t("ui.question.multiHint")}
+
+
+
+ {(opt, i) => {
+ const picked = () => store.answers[store.tab]?.includes(opt.label) ?? false
+ return (
-
-
-
-
-
-
-
-
-
-
-
{language.t("ui.messagePart.review.title")}
-
- {(q, index) => {
- const value = () => store.answers[index()]?.join(", ") ?? ""
- const answered = () => Boolean(value())
- return (
-
- {q.question}
-
- {answered() ? value() : language.t("ui.question.review.notAnswered")}
-
-
- )
- }}
-
-
-
-
-
-
-
-
- 0}>
-
-
- selectTab(store.tab + 1)}
- disabled={store.sending || (!confirm() && (store.answers[store.tab]?.length ?? 0) === 0)}
- >
- {last() && single()
- ? language.t("ui.common.submit")
- : last()
- ? language.t("common.review")
- : language.t("ui.common.next")}
-
- }
- >
-
+ )
+ }}
+
+
+
+
+
+
+ {language.t("ui.messagePart.option.typeOwnAnswer")}
+
+ {input() || language.t("ui.question.custom.placeholder")}
+
+
+
+
+
+
-
-
+
+
+
+
+
{language.t("ui.messagePart.review.title")}
+
+ {(q, index) => {
+ const value = () => store.answers[index()]?.join(", ") ?? ""
+ const answered = () => Boolean(value())
+ return (
+
+ {q.question}
+
+ {answered() ? value() : language.t("ui.question.review.notAnswered")}
+
+
+ )
+ }}
+
+
+
+
)
}
diff --git a/packages/kilo-vscode/webview-ui/src/stories/composite.stories.tsx b/packages/kilo-vscode/webview-ui/src/stories/composite.stories.tsx
index 9b7c98aec81..aab5bac37ff 100644
--- a/packages/kilo-vscode/webview-ui/src/stories/composite.stories.tsx
+++ b/packages/kilo-vscode/webview-ui/src/stories/composite.stories.tsx
@@ -231,6 +231,23 @@ const questionToolPart: ToolPart = {
},
}
+const questionDismissedPart: ToolPart = {
+ id: "part-question-dismissed-001",
+ sessionID: SESSION_ID,
+ messageID: ASST_MSG_ID,
+ type: "tool",
+ callID: "call-question-dismissed-001",
+ tool: "question",
+ state: {
+ status: "error",
+ input: { question: "Which testing framework?", options: [] },
+ error: "Error: User dismissed this question",
+ title: "Question dismissed",
+ metadata: {},
+ time: { start: now - 2000, end: now - 1500 },
+ },
+}
+
// ---------------------------------------------------------------------------
// Data helpers
// ---------------------------------------------------------------------------
@@ -457,3 +474,19 @@ export const InlineQuestion: Story = {
)
},
}
+
+// ---------------------------------------------------------------------------
+// 9. Dismissed question (right-aligned "Questions dismissed" text)
+// ---------------------------------------------------------------------------
+
+export const QuestionDismissed: Story = {
+ name: "Question Dismissed",
+ render: () => {
+ const data = dataWith([textPart, questionDismissedPart])
+ return (
+
+
+
+ )
+ },
+}
diff --git a/packages/kilo-vscode/webview-ui/src/styles/chat.css b/packages/kilo-vscode/webview-ui/src/styles/chat.css
index 90c9774b067..ee9dca5d81e 100644
--- a/packages/kilo-vscode/webview-ui/src/styles/chat.css
+++ b/packages/kilo-vscode/webview-ui/src/styles/chat.css
@@ -912,6 +912,10 @@
padding: 0 4px;
}
+.vscode-session-turn + .vscode-session-turn {
+ margin-top: 12px;
+}
+
.vscode-session-turn-user {
width: 100%;
}
@@ -937,14 +941,10 @@
}
/* ============================================
- Question Prompt
+ Question Prompt (VS Code overrides)
============================================ */
-[data-component="question-prompt"] {
- [data-slot="question-header"] {
- padding: 0;
- }
-
+[data-component="dock-prompt"][data-kind="question"] {
[data-slot="question-progress-nav"] {
display: inline-flex;
align-items: center;
@@ -972,12 +972,6 @@
}
}
- [data-slot="question-footer"] {
- padding: 8px;
- padding-top: 8px;
- margin-top: 0;
- }
-
[data-slot="question-footer"] > [data-component="button"][data-variant="ghost"] {
border: none;
box-shadow: none;
@@ -997,155 +991,11 @@
color: var(--text-weaker);
}
- [data-slot="question-text"] {
- font-size: var(--font-size-base);
- padding: 0 2px;
- }
-
- [data-slot="question-hint"] {
- font-size: var(--font-size-small);
- padding: 0 2px;
- }
-
- [data-slot="question-options"] {
- margin-top: 8px;
- gap: 4px;
- padding: 1px 1px 4px;
- }
-
- [data-slot="question-option"] {
- display: flex;
- align-items: flex-start;
- gap: 8px;
- padding: 6px 8px;
- background-color: var(--surface-raised-stronger-non-alpha);
- border: 1px solid var(--border-weak-base);
- border-radius: var(--radius-lg);
- box-shadow: none;
- text-align: left;
- width: 100%;
- cursor: pointer;
- transition:
- background-color 0.15s ease,
- border-color 0.15s ease,
- box-shadow 0.15s ease;
-
- &:hover:not([data-picked="true"]) {
- background-color: var(--background-base);
- }
-
- &[data-picked="true"] {
- background-color: var(--surface-interactive-weak);
- border-color: transparent;
- box-shadow: var(--shadow-xs-border-hover);
- }
-
- &:disabled {
- cursor: not-allowed;
- opacity: 0.6;
- }
- }
-
- [data-slot="question-option-check"] {
- display: inline-flex;
- transform: translateY(2px);
- }
-
- [data-slot="question-option-box"] {
- width: 16px;
- height: 16px;
- padding: 2px;
- border-radius: var(--radius-sm);
- border: 1px solid var(--border-weak-base);
- display: inline-flex;
- align-items: center;
- justify-content: center;
- flex-shrink: 0;
- background-color: transparent;
- transition:
- background-color 0.15s ease,
- border-color 0.15s ease;
-
- [data-component="icon"] {
- opacity: 0;
- color: var(--icon-base);
- }
-
- &[data-type="radio"] {
- border-radius: 999px;
- }
-
- [data-slot="question-option-radio-dot"] {
- width: 6px;
- height: 6px;
- border-radius: 999px;
- background-color: var(--background-stronger);
- opacity: 0;
- }
-
- &[data-picked="true"] {
- border-color: var(--icon-interactive-base);
-
- [data-component="icon"] {
- opacity: 1;
- color: var(--icon-invert-base);
- }
-
- &[data-type="checkbox"] {
- background-color: var(--icon-interactive-base);
- }
-
- &[data-type="radio"] {
- background-color: var(--icon-interactive-base);
- [data-slot="question-option-radio-dot"] {
- opacity: 1;
- }
- }
- }
- }
-
- [data-slot="question-option-main"] {
- display: flex;
- flex-direction: column;
- gap: 2px;
- min-width: 0;
- flex: 1;
- }
-
- [data-slot="option-label"] {
- font-family: var(--font-family-sans);
- font-size: var(--font-size-base);
- font-weight: var(--font-weight-medium);
- line-height: var(--line-height-large);
- color: var(--text-strong);
- }
-
- [data-slot="option-description"] {
- font-family: var(--font-family-sans);
- font-size: var(--font-size-small);
- font-weight: var(--font-weight-regular);
- line-height: var(--line-height-large);
- color: var(--text-base);
- min-width: 0;
- white-space: normal;
- overflow: visible;
- text-overflow: clip;
- }
-
- [data-slot="question-option"][data-custom="true"] {
- [data-slot="option-description"] {
- overflow: visible;
- text-overflow: clip;
- white-space: normal;
- overflow-wrap: anywhere;
- }
- }
-
[data-slot="question-review"] {
display: flex;
flex-direction: column;
gap: 8px;
- padding: 4px 2px;
+ padding: 4px 10px;
}
[data-slot="review-title"] {
diff --git a/packages/ui/src/components/message-part.tsx b/packages/ui/src/components/message-part.tsx
index 84dbc83c1a8..a56362d1825 100644
--- a/packages/ui/src/components/message-part.tsx
+++ b/packages/ui/src/components/message-part.tsx
@@ -964,22 +964,29 @@ PART_MAPPING["tool"] = function ToolPartDisplay(props) {
const render = ToolRegistry.render(part.tool) ?? GenericTool
+ const dismissed = createMemo(
+ () =>
+ part.tool === "question" &&
+ part.state.status === "error" &&
+ typeof part.state.error === "string" &&
+ part.state.error.includes("dismissed this question"),
+ )
+
return (
+
+
+
+ {i18n.t("ui.tool.questions")} dismissed
+
+
+
+
{(error) => {
const cleaned = error().replace("Error: ", "")
- if (part.tool === "question" && cleaned.includes("dismissed this question")) {
- return (
-
-
- {i18n.t("ui.tool.questions")} dismissed
-
-
- )
- }
const [title, ...rest] = cleaned.split(": ")
return (
@@ -1016,6 +1023,7 @@ PART_MAPPING["tool"] = function ToolPartDisplay(props) {
+
)
}