diff --git a/packages/kilo-docs/pages/kiloclaw/control-ui/exec-approvals.md b/packages/kilo-docs/pages/kiloclaw/control-ui/exec-approvals.md index 1188f545c43..08555b1f953 100644 --- a/packages/kilo-docs/pages/kiloclaw/control-ui/exec-approvals.md +++ b/packages/kilo-docs/pages/kiloclaw/control-ui/exec-approvals.md @@ -23,6 +23,16 @@ Approvals are enforced locally on the execution host and sit on top of tool poli | `allowlist` | Allow only commands matching the allowlist | | `full` | Allow everything (equivalent to elevated mode) | +## Allow Everything from Settings + +If you want to skip per-command approvals entirely, you can set the security policy to **Allow Everything** directly from the [KiloClaw Settings dashboard](https://app.kilo.ai/claw/settings). This applies the `full` policy globally, allowing your agent to execute any host command without prompts — equivalent to elevated mode. + +{% callout type="warning" %} +Enabling **Allow Everything** removes all exec safety checks. Only use this in trusted environments where you are comfortable with your agent running arbitrary commands. +{% /callout %} + +{% image src="/docs/img/kiloclaw/allow-everything-settings.png" alt="Allow Everything setting in KiloClaw Settings Dashboard" width="800" caption="The Allow Everything toggle in KiloClaw Settings" /%} + ## Ask Behavior The `ask` setting controls when the user is prompted for approval: diff --git a/packages/kilo-docs/public/img/kiloclaw/allow-everything-settings.png b/packages/kilo-docs/public/img/kiloclaw/allow-everything-settings.png new file mode 100644 index 00000000000..58ecac341cd Binary files /dev/null and b/packages/kilo-docs/public/img/kiloclaw/allow-everything-settings.png differ diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/diff-summary-collapsed-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/diff-summary-collapsed-chromium-linux.png new file mode 100644 index 00000000000..e65ee419805 --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/diff-summary-collapsed-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b57a543bd799f92b35d2c6037a4ffc932a37f59790213006a021bebef9e94b38 +size 6897 diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/VscodeSessionTurn.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/VscodeSessionTurn.tsx index 7c19bb7c911..517efcff34d 100644 --- a/packages/kilo-vscode/webview-ui/src/components/chat/VscodeSessionTurn.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/chat/VscodeSessionTurn.tsx @@ -196,7 +196,7 @@ export const VscodeSessionTurn: Component = (props) => {
- {i18n.t("ui.sessionReview.change.modified")} + {i18n.t("ui.sessionReview.change.modified")}{" "} {diffs().length} {i18n.t(diffs().length === 1 ? "ui.common.file.one" : "ui.common.file.other")} 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 a9f897e6c35..334b9cbea98 100644 --- a/packages/kilo-vscode/webview-ui/src/stories/composite.stories.tsx +++ b/packages/kilo-vscode/webview-ui/src/stories/composite.stories.tsx @@ -11,10 +11,12 @@ import type { Meta, StoryObj } from "storybook-solidjs-vite" import type { AssistantMessage as SDKAssistantMessage, TextPart, ToolPart } from "@kilocode/sdk/v2" import { StoryProviders, defaultMockData, mockSessionValue } from "./StoryProviders" import { AssistantMessage } from "../components/chat/AssistantMessage" +import { VscodeSessionTurn } from "../components/chat/VscodeSessionTurn" import { ChatView } from "../components/chat/ChatView" import { Part } from "@kilocode/kilo-ui/message-part" import { registerVscodeToolOverrides } from "../components/chat/VscodeToolOverrides" import { SessionContext } from "../context/session" +import { ServerContext } from "../context/server" import type { PermissionRequest, QuestionRequest } from "../types/messages" // Register VS Code tool overrides (bash expanded by default, etc.) @@ -977,3 +979,72 @@ export const McpToolExpanded: Story = { ) }, } + +// --------------------------------------------------------------------------- +// 19. Diff summary — "Modified N files" collapsed header +// --------------------------------------------------------------------------- + +const USER_MSG_ID = "user-msg-diff-001" + +const mockDiffs = [ + { file: "src/components/App.tsx", before: "", after: "", additions: 12, deletions: 3, status: "modified" as const }, + { file: "src/utils/helpers.ts", before: "", after: "", additions: 5, deletions: 8, status: "modified" as const }, + { file: "src/styles/main.css", before: "", after: "", additions: 20, deletions: 0, status: "added" as const }, +] + +export const DiffSummaryCollapsed: Story = { + name: "Diff Summary — Modified N files (collapsed)", + render: () => { + const data = { + ...defaultMockData, + message: { + [SESSION_ID]: [ + { + id: USER_MSG_ID, + sessionID: SESSION_ID, + role: "user", + time: { created: now - 10000 }, + summary: { diffs: mockDiffs }, + }, + { ...baseAssistantMessage, parentID: USER_MSG_ID }, + ], + }, + part: { + [USER_MSG_ID]: [ + { id: "part-user-text", sessionID: SESSION_ID, messageID: USER_MSG_ID, type: "text", text: "Fix the bug" }, + ], + [ASST_MSG_ID]: [textPart], + }, + } + const session = { + ...mockSessionValue({ id: SESSION_ID, status: "idle" }), + messages: () => data.message[SESSION_ID], + } + const server = { + connectionState: () => "connected" as const, + serverInfo: () => undefined, + extensionVersion: () => "1.0.0", + errorMessage: () => undefined, + errorDetails: () => undefined, + isConnected: () => true, + profileData: () => null, + deviceAuth: () => ({ status: "idle" as const }), + startLogin: () => {}, + vscodeLanguage: () => "en", + languageOverride: () => undefined, + workspaceDirectory: () => "/project", + gitInstalled: () => true, + } + return ( + + + +
+ +
+
+
+
+ ) + }, +} diff --git a/packages/kilo-vscode/webview-ui/src/styles/chat-layout.css b/packages/kilo-vscode/webview-ui/src/styles/chat-layout.css index cf74d06fefd..ba6545819a0 100644 --- a/packages/kilo-vscode/webview-ui/src/styles/chat-layout.css +++ b/packages/kilo-vscode/webview-ui/src/styles/chat-layout.css @@ -176,3 +176,9 @@ .vscode-session-turn-diffs { width: 100%; } + +.vscode-session-turn-diffs [data-slot="session-turn-diffs-title"] { + display: flex; + align-items: baseline; + gap: 6px; +} diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index 0507c6f0240..8362d3bdd9c 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -63,6 +63,7 @@ import { TuiConfigProvider, useTuiConfig } from "./context/tui-config" import { TuiConfig } from "@/config/tui" import { createTuiApi, TuiPluginRuntime, type RouteMap } from "./plugin" import { FormatError, FormatUnknownError } from "@/cli/error" +import { resetTerminalState } from "@tui/util/terminal" // kilocode_change async function getTerminalBackgroundColor(): Promise<"dark" | "light"> { // can't set raw mode if not a TTY @@ -197,6 +198,9 @@ export function tui(input: { await TuiPluginRuntime.dispose() } + // kilocode_change - safety net: ensure mouse tracking is disabled regardless of exit path + process.on("exit", resetTerminalState) // kilocode_change + const renderer = await createCliRenderer(rendererConfig(input.config)) await render(() => { @@ -1010,6 +1014,8 @@ function ErrorComponent(props: { renderer?.setTerminalTitle("") renderer?.destroy() win32FlushInputBuffer() + // kilocode_change - reset terminal state to disable mouse tracking on exit + resetTerminalState() await props.onExit() } diff --git a/packages/opencode/src/cli/cmd/tui/context/exit.tsx b/packages/opencode/src/cli/cmd/tui/context/exit.tsx index 205025f867d..4f0c5eae0b2 100644 --- a/packages/opencode/src/cli/cmd/tui/context/exit.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/exit.tsx @@ -2,6 +2,7 @@ import { useRenderer } from "@opentui/solid" import { createSimpleContext } from "./helper" import { FormatError, FormatUnknownError } from "@/cli/error" import { win32FlushInputBuffer } from "../win32" +import { resetTerminalState } from "@tui/util/terminal" // kilocode_change type Exit = ((reason?: unknown) => Promise) & { message: { set: (value?: string) => () => void @@ -38,6 +39,7 @@ export const { use: useExit, provider: ExitProvider } = createSimpleContext({ renderer.setTerminalTitle("") renderer.destroy() win32FlushInputBuffer() + resetTerminalState() // kilocode_change if (reason) { const formatted = FormatError(reason) ?? FormatUnknownError(reason) if (formatted) { diff --git a/packages/opencode/src/cli/cmd/tui/util/terminal.ts b/packages/opencode/src/cli/cmd/tui/util/terminal.ts index 2b81068b3f9..a2e289b3e64 100644 --- a/packages/opencode/src/cli/cmd/tui/util/terminal.ts +++ b/packages/opencode/src/cli/cmd/tui/util/terminal.ts @@ -1,5 +1,29 @@ import { RGBA } from "@opentui/core" +// kilocode_change start +/** + * Write escape sequences to disable all mouse tracking modes and reset terminal state. + * This is a safety net to ensure the terminal is clean after exit, even if the renderer's + * cleanup didn't flush properly (e.g. on Windows). + */ +export function resetTerminalState() { + const sequences = [ + "\x1b[?1000l", // disable normal mouse tracking + "\x1b[?1002l", // disable button-event mouse tracking + "\x1b[?1003l", // disable any-event mouse tracking (all movement) + "\x1b[?1006l", // disable SGR extended mouse mode + "\x1b[?1015l", // disable RXVT mouse mode + "\x1b[> /**