mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-19 10:02:04 +08:00
Merge pull request #11645 from Kilo-Org/like-drawer
fix(vscode): use native sandbox notifications
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"kilo-code": patch
|
||||
---
|
||||
|
||||
Show sandbox state changes as concise VS Code notifications.
|
||||
@@ -2597,6 +2597,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
|
||||
...data,
|
||||
requestID: input.requestID,
|
||||
})
|
||||
vscode.window.showInformationMessage(data.enabled ? "Sandbox enabled" : "Sandbox disabled")
|
||||
} catch (error) {
|
||||
if (this.connectionState === "connected" && this.connectionGeneration === generation && this.client === client) {
|
||||
this.postSandboxError(resolved.sid, error, revision, input.requestID)
|
||||
|
||||
@@ -79,6 +79,7 @@ const mockVscode = {
|
||||
visibleNotebookEditors: [],
|
||||
tabGroups: { all: [] },
|
||||
showTextDocument: async () => {},
|
||||
showInformationMessage: async () => undefined,
|
||||
showWarningMessage: async () => undefined,
|
||||
createTerminal: () => ({ show: noop, sendText: noop, dispose: noop }),
|
||||
createOutputChannel: () => ({
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { describe, it, expect, spyOn } from "bun:test"
|
||||
import * as vscode from "vscode"
|
||||
import type { PartUpdate } from "../../src/shared/stream-messages"
|
||||
|
||||
// vscode mock is provided by the shared preload (tests/setup/vscode-mock.ts)
|
||||
@@ -292,6 +293,7 @@ describe("KiloProvider sandbox status", () => {
|
||||
|
||||
describe("KiloProvider sandbox toggle", () => {
|
||||
it("creates a session before toggling from the empty composer", async () => {
|
||||
const notice = spyOn(vscode.window, "showInformationMessage").mockResolvedValue(undefined)
|
||||
const client = createClient()
|
||||
const { internal, sent } = makeProvider(client)
|
||||
|
||||
@@ -310,6 +312,25 @@ describe("KiloProvider sandbox toggle", () => {
|
||||
enabled: true,
|
||||
}),
|
||||
)
|
||||
expect(notice).toHaveBeenCalledTimes(1)
|
||||
expect(notice).toHaveBeenCalledWith("Sandbox enabled")
|
||||
notice.mockRestore()
|
||||
})
|
||||
|
||||
it("reports the disabled state in a native notification", async () => {
|
||||
const notice = spyOn(vscode.window, "showInformationMessage").mockResolvedValue(undefined)
|
||||
const sandbox = defer<{ data: unknown }>()
|
||||
const client = createClient({ sandboxDeferred: sandbox })
|
||||
const { internal } = makeProvider(client)
|
||||
internal.currentSession = mkSession()
|
||||
|
||||
const toggle = internal.handleToggleSandbox({ sessionID: "s1", requestID: "sandbox-1" })
|
||||
sandbox.resolve({ data: { directory: "/repo", enabled: false, available: true, version: 2 } })
|
||||
await toggle
|
||||
|
||||
expect(notice).toHaveBeenCalledTimes(1)
|
||||
expect(notice).toHaveBeenCalledWith("Sandbox disabled")
|
||||
notice.mockRestore()
|
||||
})
|
||||
|
||||
it("shares session creation and finishes the toggle before a prompt", async () => {
|
||||
@@ -341,6 +362,7 @@ describe("KiloProvider sandbox toggle", () => {
|
||||
|
||||
it("does not send a queued prompt when the sandbox toggle fails", async () => {
|
||||
const log = spyOn(console, "error").mockImplementation(() => {})
|
||||
const notice = spyOn(vscode.window, "showInformationMessage").mockResolvedValue(undefined)
|
||||
const sandbox = defer<{ data: unknown }>()
|
||||
const started = defer<void>()
|
||||
const client = createClient({ sandboxDeferred: sandbox, sandboxStarted: started })
|
||||
@@ -358,11 +380,14 @@ describe("KiloProvider sandbox toggle", () => {
|
||||
expect(sent).toContainEqual(
|
||||
expect.objectContaining({ type: "sendMessageFailed", sessionID: "s1", messageID: "message-1" }),
|
||||
)
|
||||
expect(notice).not.toHaveBeenCalled()
|
||||
notice.mockRestore()
|
||||
log.mockRestore()
|
||||
})
|
||||
|
||||
it("does not send a queued prompt when the sandbox backend is unavailable", async () => {
|
||||
const log = spyOn(console, "error").mockImplementation(() => {})
|
||||
const notice = spyOn(vscode.window, "showInformationMessage").mockResolvedValue(undefined)
|
||||
const sandbox = defer<{ data: unknown }>()
|
||||
const started = defer<void>()
|
||||
const client = createClient({ sandboxDeferred: sandbox, sandboxStarted: started })
|
||||
@@ -382,6 +407,8 @@ describe("KiloProvider sandbox toggle", () => {
|
||||
expect(sent).toContainEqual(
|
||||
expect.objectContaining({ type: "sendMessageFailed", sessionID: "s1", messageID: "message-1" }),
|
||||
)
|
||||
expect(notice).not.toHaveBeenCalled()
|
||||
notice.mockRestore()
|
||||
log.mockRestore()
|
||||
})
|
||||
|
||||
|
||||
@@ -36,6 +36,17 @@ describe("PromptInput sandbox toggle", () => {
|
||||
expect(toggle).not.toContain('type: "updateConfig"')
|
||||
})
|
||||
|
||||
it("keeps success feedback out of the webview toast region", () => {
|
||||
const start = src.indexOf("const handleSandboxMessage =")
|
||||
const end = src.indexOf("const unsubscribe =", start)
|
||||
const handler = src.slice(start, end)
|
||||
|
||||
expect(start).toBeGreaterThan(-1)
|
||||
expect(end).toBeGreaterThan(start)
|
||||
expect(handler).toContain('variant: "error"')
|
||||
expect(handler).not.toContain('variant: "success"')
|
||||
})
|
||||
|
||||
it("uses the internal flag for visibility and effective runtime state for the button", () => {
|
||||
expect(src).toContain("features().sandboxControls")
|
||||
expect(src).toContain("<Show when={sandboxVisible()}>")
|
||||
|
||||
@@ -464,19 +464,11 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
|
||||
sandboxAttempts = 0
|
||||
if (sandboxRetry) clearTimeout(sandboxRetry)
|
||||
sandboxRetry = undefined
|
||||
if (matching) {
|
||||
if (!state.available) {
|
||||
showToast({
|
||||
variant: "error",
|
||||
title: language.t("common.requestFailed"),
|
||||
description: state.reason,
|
||||
})
|
||||
return true
|
||||
}
|
||||
if (matching && !state.available) {
|
||||
showToast({
|
||||
variant: "success",
|
||||
title: language.t("settings.experimental.sandbox.title"),
|
||||
description: language.t(state.enabled ? "prompt.action.sandbox.enabled" : "prompt.action.sandbox.disabled"),
|
||||
variant: "error",
|
||||
title: language.t("common.requestFailed"),
|
||||
description: state.reason,
|
||||
})
|
||||
}
|
||||
return true
|
||||
|
||||
Reference in New Issue
Block a user