fix(permission): cover tui sandbox escalation prompt

This commit is contained in:
marius-kilocode
2026-08-17 15:42:47 +02:00
parent 86af8dd7c7
commit a066d0f983
5 changed files with 46 additions and 7 deletions
@@ -130,7 +130,7 @@ export const PermissionDock: Component<{
}
const title = () => {
if (sandboxEscalation()) return "Allow Git operation outside the sandbox?"
if (sandboxEscalation()) return language.t("notification.permission.titleSandboxEscalation")
const skill = props.request.args?.skill
if (skillShell() && typeof skill === "string" && skill.length > 0)
// Escape the untrusted skill name so bidi/control chars can't reorder the header text.
@@ -270,6 +270,7 @@ export const dict = {
"notification.permission.title": "Permission required",
"notification.permission.titleSubagent": "Permission required (subagent)",
"notification.permission.titleSkillShell": 'Run shell commands from skill "{{skill}}"?',
"notification.permission.titleSandboxEscalation": "Allow Git operation outside the sandbox?",
"ui.permission.manageAutoApprove": "Manage Auto-Approve Rules",
"ui.permission.doomLoop.prompt": "Potential loop detected for the {{tool}} tool. Continue running?",
"ui.permission.doomLoop.rule": "Continue {{tool}} calls",
@@ -102,7 +102,7 @@ export function permissionInfo(request: PermissionRequest): PermissionInfo {
const command = text(input.command)
return {
icon: "!",
title: "Allow Git operation outside the sandbox",
title: "Allow Git operation outside the sandbox", // kilocode_change
lines: command
? [`$ ${command}`, "This approval applies to this command only."]
: ["This approval applies to this command only."],
@@ -139,6 +139,22 @@ describe("run permission shared", () => {
expect(permissionOptions("permission", true)).toEqual(["once", "reject"])
expect(permissionOptions("permission")).toEqual(["once", "always", "reject"])
})
test("sandbox escalation shows the command and offers only one-shot approval", () => {
expect(
permissionInfo(
req({
permission: "sandbox_escalation",
metadata: { command: "git add file.txt && git commit -m test", sandboxEscalation: true },
}),
),
).toEqual({
icon: "!",
title: "Allow Git operation outside the sandbox",
lines: ["$ git add file.txt && git commit -m test", "This approval applies to this command only."],
})
expect(permissionOptions("permission", true)).toEqual(["once", "reject"])
})
// kilocode_change end
test("formats always-allow copy for wildcard and explicit patterns", () => {
+27 -5
View File
@@ -334,6 +334,27 @@ export function PermissionPrompt(props: { request: PermissionRequest; directory?
}
}
// kilocode_change start - show sandbox escalation details and keep approval one-shot
if (permission === "sandbox_escalation") {
const meta = props.request.metadata ?? {}
const command = normalizeUrls(
typeof data.command === "string" ? data.command : typeof meta.command === "string" ? meta.command : "",
)
return {
icon: "!",
title: "Allow Git operation outside the sandbox?",
body: (
<box paddingLeft={1} flexDirection="column">
<Show when={command}>
<text fg={theme.text}>{"$ " + command}</text>
</Show>
<text fg={theme.textMuted}>This approval applies to this command only.</text>
</box>
),
}
}
// kilocode_change end
if (permission === "task") {
const type = typeof data.subagent_type === "string" ? data.subagent_type : "Unknown"
const desc = typeof data.description === "string" ? data.description : ""
@@ -463,11 +484,12 @@ export function PermissionPrompt(props: { request: PermissionRequest; directory?
)
// kilocode_change start - skill shell batches are never persisted: only Allow / Reject
const options: Record<string, string> = props.request.metadata?.["skillShell"]
? { once: "Allow", reject: "Reject" }
: props.request.metadata?.[ConfigProtection.DISABLE_ALWAYS_KEY]
? { once: "Allow once", reject: "Reject" }
: { once: "Allow once", always: "Allow always", reject: "Reject" }
const options: Record<string, string> =
props.request.metadata?.["skillShell"] || props.request.metadata?.["sandboxEscalation"]
? { once: "Allow", reject: "Reject" }
: props.request.metadata?.[ConfigProtection.DISABLE_ALWAYS_KEY]
? { once: "Allow once", reject: "Reject" }
: { once: "Allow once", always: "Allow always", reject: "Reject" }
// kilocode_change end
const body = (