diff --git a/packages/kilo-ui/src/components/message-part.css b/packages/kilo-ui/src/components/message-part.css
index 49d8d9d5998..5494f7c0c71 100644
--- a/packages/kilo-ui/src/components/message-part.css
+++ b/packages/kilo-ui/src/components/message-part.css
@@ -251,7 +251,7 @@ html[data-theme="kilo-vscode"] [data-component="bash-output"] {
[data-component="shell-expanded-output"] .shiki code {
font-family: var(--font-family-mono);
font-feature-settings: var(--font-family-mono--font-feature-settings);
- font-size: 13px;
+ font-size: var(--font-size-small);
line-height: var(--line-height-large);
white-space: pre-wrap;
overflow-wrap: anywhere;
diff --git a/packages/kilo-ui/src/components/message-part.tsx b/packages/kilo-ui/src/components/message-part.tsx
index 1178f04d6b8..232899c63e5 100644
--- a/packages/kilo-ui/src/components/message-part.tsx
+++ b/packages/kilo-ui/src/components/message-part.tsx
@@ -2053,13 +2053,14 @@ function BashCopyButton(props: { value: () => string; label: string }) {
)
}
-function BashHighlightedOutput(props: { cmd: string; output: string; outputPath?: string }) {
+function BashHighlightedOutput(props: { cmd: string; output: string; outputPath?: string; active?: boolean }) {
const data = useData()
const i18n = useI18n()
let cmdRef: HTMLDivElement | undefined
let outRef: HTMLDivElement | undefined
createEffect(() => {
+ if (!props.active) return
const cmd = props.cmd
if (!cmdRef || !cmd) return
cmdRef.innerHTML = `
${escapeHtml(cmd)}
`
@@ -2067,6 +2068,7 @@ function BashHighlightedOutput(props: { cmd: string; output: string; outputPath?
})
createEffect(() => {
+ if (!props.active) return
const out = props.output
if (!outRef || !out) return
outRef.innerHTML = `${escapeHtml(out)}
`
@@ -2128,6 +2130,7 @@ ToolRegistry.register({
const pending = () => busy(props.status)
const reveal = useToolReveal(pending, () => props.reveal !== false)
const subtitle = () => props.input.description ?? props.metadata.description
+ const [open, setOpen] = createSignal(props.defaultOpen ?? true)
// also apply processCarriageReturns for Windows CLI tools
const cmd = createMemo(() => {
@@ -2148,6 +2151,7 @@ ToolRegistry.register({
icon="console"
animated
defaultOpen={props.defaultOpen ?? true}
+ onOpenChange={setOpen}
allowPendingToggle
trigger={
@@ -2160,7 +2164,7 @@ ToolRegistry.register({
}
>
-
+
)
},
diff --git a/packages/kilo-ui/src/components/shell-rolling-results.tsx b/packages/kilo-ui/src/components/shell-rolling-results.tsx
index 83112d6a785..381e9230bfc 100644
--- a/packages/kilo-ui/src/components/shell-rolling-results.tsx
+++ b/packages/kilo-ui/src/components/shell-rolling-results.tsx
@@ -59,10 +59,11 @@ function ShellRollingCommand(props: { text: string; animate?: boolean }) {
)
}
-function ShellOutputHighlight(props: { code: string }) {
+function ShellOutputHighlight(props: { code: string; active?: boolean }) {
let ref: HTMLDivElement | undefined
createEffect(() => {
+ if (!props.active) return
const code = props.code
if (!ref || !code) return
ref.innerHTML = `${escapeHtml(code)}
`
@@ -171,7 +172,7 @@ function ShellExpanded(props: { cmd: string; out: string; open: boolean }) {
onScroll={updateMask}
style={{ "max-height": `${cap()}px` }}
>
-
+
>
diff --git a/packages/kilo-vscode/src/KiloProvider.ts b/packages/kilo-vscode/src/KiloProvider.ts
index 2e466d76e8a..0aa9c66aba8 100644
--- a/packages/kilo-vscode/src/KiloProvider.ts
+++ b/packages/kilo-vscode/src/KiloProvider.ts
@@ -607,6 +607,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
await routeSuggestionWebviewMessage(this.questionCtx, message)
if (await ModelState.handleMessage(message.type, message, this.client, (msg) => this.postMessage(msg))) return
if (await routeAutocompleteMessage(message, (msg) => this.postMessage(msg))) return
+ if (this.handleEditorOpenMessage(message)) return
if (
await handleSidebarWorktreeMessage(message, {
post: (msg) => this.postMessage(msg),
@@ -771,16 +772,6 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
break
case "saveImage":
return saveImage(this.getWorkspaceDirectory(this.currentSession?.id), message)
- case "openFile":
- if (message.filePath) {
- this.handleOpenFile(message.filePath, message.line, message.column)
- }
- break
- case "openContent":
- if (message.content) {
- this.handleOpenContent(message.content, message.language)
- }
- break
case "requestProviders":
this.fetchAndSendProviders().catch((e) => console.error("[Kilo New] fetchAndSendProviders failed:", e))
break
@@ -2902,8 +2893,27 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
.then(open, (err) => console.error("[Kilo New] KiloProvider: Failed to preview image:", err))
}
+ private handleEditorOpenMessage(message: {
+ type?: string
+ filePath?: string
+ line?: number
+ column?: number
+ content?: string
+ language?: string
+ }): boolean {
+ if (message.type === "openFile") {
+ if (message.filePath) this.handleOpenFile(message.filePath, message.line, message.column)
+ return true
+ }
+ if (message.type === "openContent") {
+ if (message.content) this.handleOpenContent(message.content, message.language)
+ return true
+ }
+ return false
+ }
+
/**
- * Handle openContent request — open arbitrary text in an untitled VS Code editor tab.
+ * Handle openContent request - open arbitrary text in an untitled VS Code editor tab.
*/
private handleOpenContent(content: string, language?: string): void {
vscode.workspace.openTextDocument({ content, language: language || "log" }).then(
diff --git a/packages/ui/src/components/basic-tool.tsx b/packages/ui/src/components/basic-tool.tsx
index e1527387f9c..fc09a91294e 100644
--- a/packages/ui/src/components/basic-tool.tsx
+++ b/packages/ui/src/components/basic-tool.tsx
@@ -35,6 +35,7 @@ export interface BasicToolProps {
animated?: boolean
allowPendingToggle?: boolean // kilocode_change
onSubtitleClick?: () => void
+ onOpenChange?: (open: boolean) => void // kilocode_change
onTriggerClick?: JSX.EventHandlerUnion
triggerHref?: string
clickable?: boolean
@@ -124,6 +125,7 @@ export function BasicTool(props: BasicToolProps) {
if (props.hideDetails) return // kilocode_change
if (props.locked && !value) return
setState("open", value)
+ props.onOpenChange?.(value) // kilocode_change
}
const trigger = () => (