-
{(diff) => }
+ {/* Everything above the buttons scrolls: a long command or a large diff must never
+ push Allow/Deny out of the clipped chat view. */}
+
+ {/* Pierre's virtualizer uses the scroll root's first child as its content
+ container, so keep all variable-height permission content in one wrapper. */}
+
+
0}
+ fallback={
+ <>
+ {(desc) => {desc()}
}
+
+ {(cmd) => }
+
+
+ {(() => {
+ const desc = description()
+ if (!desc)
+ return !command() && toolDescription() ? (
+ {toolDescription()}
+ ) : null
+ if (desc.kind === "single")
+ return (
+
+ {desc.text}
+
+ )
+ return (
+
+ {desc.title}
+ {(path) => {path}}
+
+ )
+ })()}
+ >
+ }
+ >
+ {/* Verbatim commands (args.commands), control-char/bidi-escaped so the displayed command matches execution. */}
+ {(cmd) => }
+
+
+
0}>
+
+
-
+
[data-component="permission-shortcuts"]) {
+ display: flex;
+ flex-direction: column;
+ flex-shrink: 1;
+ min-height: 0;
+}
+
+.chat-input:has(> [data-component="permission-shortcuts"]) > * {
+ flex-shrink: 0;
+}
+
+/* Margins don't collapse in a flex column, so drop the halves that used to
+ overlap and keep the spacing around the card identical. */
+.chat-input:has(> [data-component="permission-shortcuts"]) > .startup-error-banner {
+ margin-bottom: 0;
+}
+
+.chat-input:has(> [data-component="permission-shortcuts"]) > .prompt-input-container {
+ margin-top: 0;
+}
+
+.chat-input > [data-component="permission-shortcuts"] {
+ display: flex;
+ flex-direction: column;
+ flex-shrink: 1;
+ /* Shrinks down to the card's own floor plus its 12px vertical margins, so the
+ card is never laid out over the prompt input below it. */
+ min-height: calc(var(--permission-card-min-height, 11em) + 24px);
+}
+
.vscode-session-turn-diffs-trigger {
display: inline-flex;
align-items: center;
diff --git a/packages/kilo-vscode/webview-ui/src/styles/permission-dock.css b/packages/kilo-vscode/webview-ui/src/styles/permission-dock.css
index 686a14cacc0..f588a969134 100644
--- a/packages/kilo-vscode/webview-ui/src/styles/permission-dock.css
+++ b/packages/kilo-vscode/webview-ui/src/styles/permission-dock.css
@@ -2,9 +2,20 @@
Permission Dock (VS Code overrides)
============================================ */
+[data-component="permission-shortcuts"] {
+ /* Title row + Allow/Deny row + tray. The card never shrinks below this, and
+ the composer column reserves the same space (see chat-layout.css) so a
+ shrinking card can never overlap the prompt input below. */
+ --permission-card-min-height: 11em;
+}
+
[data-component="dock-prompt"][data-kind="permission"] {
animation: permission-slide-in 0.3s ease-out;
margin: 12px;
+ /* The card shrinks with the chat view, but never below its minimum: the
+ scroll area collapses first, so the buttons stay reachable even in a very
+ short panel. */
+ min-height: var(--permission-card-min-height, 11em);
border: 1px solid
color-mix(in srgb, var(--vscode-editorWarning-foreground, #cca700) 40%, var(--vscode-panel-border, transparent));
border-radius: 0.25rem;
@@ -43,6 +54,15 @@
color: var(--text-weak, var(--vscode-descriptionForeground));
}
+ /* Both keep their full height inside [data-slot="permission-scroll"]: they have
+ their own clipped or hidden-scrollbar boxes, so shrinking them would cut text
+ off instead of letting the scroll area scroll. */
+ [data-slot="permission-command"],
+ [data-slot="permission-patterns"] {
+ flex: 0 0 auto;
+ overflow: visible;
+ }
+
[data-slot="permission-command"] {
position: relative;
min-width: 0;
@@ -135,16 +155,45 @@
word-break: break-all;
}
+ /* The only scroll region of the card. It shrinks before anything else, so the
+ description, command and diffs stay reachable by scrolling while the header
+ and the Allow/Deny row keep their space no matter how tall the diff is or
+ how little room the chat view has left. */
+ [data-slot="permission-scroll"] {
+ display: flex;
+ flex-direction: column;
+ flex: 1 1 auto;
+ min-height: 0;
+ max-height: 420px;
+ overflow-y: auto;
+ overscroll-behavior: contain;
+ }
+
+ /* Pierre's virtualizer treats the scroll root's first child as its content
+ container. Keep the variable-height permission content together so nested
+ descriptions do not become the virtualizer's content root. */
+ [data-slot="permission-scroll-content"] {
+ display: flex;
+ flex: 0 0 auto;
+ flex-direction: column;
+ gap: 4px;
+ min-height: min-content;
+ }
+
[data-slot="permission-diffs"] {
display: flex;
flex-direction: column;
gap: 8px;
margin: 8px 0;
- max-height: 420px;
- overflow: auto;
+ flex-shrink: 0;
+ min-height: 0;
}
+ /* Keeps its own height when the card shrinks. The file card clips its content
+ (overflow: hidden), so shrinking it would hide the diff instead of scrolling
+ [data-slot="permission-scroll"]. */
[data-slot="permission-diff"] {
+ flex-shrink: 0;
margin: 8px 0;
border: 1px solid var(--border-weak-base);
border-radius: 4px;
@@ -212,7 +261,10 @@
flex-shrink: 0;
}
- [data-slot="permission-diff-content"] {
+ /* With a single file the card scrolls as part of [data-slot="permission-scroll"],
+ so there is only one scrollbar. With several files each one keeps its own cap,
+ otherwise the last file sits thousands of pixels down the list. */
+ [data-slot="permission-diffs"]:not([data-count="1"]) [data-slot="permission-diff-content"] {
max-height: 300px;
overflow: auto;
}
@@ -399,6 +451,8 @@
gap: 8px;
justify-content: flex-start;
padding: 4px 0 8px;
+ /* Never shrink or scroll away: this row is the only way to answer the ask. */
+ flex-shrink: 0;
}
[data-slot="permission-actions"] > [data-component="button"][data-variant="primary"] {