mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-19 01:51:21 +08:00
Merge pull request #421 from Githubguy132010/fix/vscode-permission-prompt-408
fix(vscode): stop duplicate permission prompts (#408)
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import { describe, expect, it } from "bun:test"
|
||||
import { removeSessionPermissions, upsertPermission } from "../../webview-ui/src/context/permission-queue"
|
||||
import type { PermissionRequest } from "../../webview-ui/src/types/messages"
|
||||
|
||||
const permission = (input: Partial<PermissionRequest> = {}): PermissionRequest => ({
|
||||
id: input.id ?? "perm-1",
|
||||
sessionID: input.sessionID ?? "session-1",
|
||||
toolName: input.toolName ?? "read",
|
||||
patterns: input.patterns ?? ["/tmp/*"],
|
||||
args: input.args ?? {},
|
||||
message: input.message,
|
||||
tool: input.tool,
|
||||
})
|
||||
|
||||
describe("permission queue", () => {
|
||||
it("appends a new permission id", () => {
|
||||
const result = upsertPermission([], permission({ id: "perm-1" }))
|
||||
expect(result).toHaveLength(1)
|
||||
expect(result[0].id).toBe("perm-1")
|
||||
})
|
||||
|
||||
it("updates an existing permission id instead of duplicating", () => {
|
||||
const existing = permission({ id: "perm-1", toolName: "read", patterns: ["a"] })
|
||||
const incoming = permission({ id: "perm-1", toolName: "write", patterns: ["b"] })
|
||||
|
||||
const result = upsertPermission([existing], incoming)
|
||||
|
||||
expect(result).toHaveLength(1)
|
||||
expect(result[0]).toEqual(incoming)
|
||||
})
|
||||
|
||||
it("keeps other permission entries when updating one id", () => {
|
||||
const first = permission({ id: "perm-1", sessionID: "session-1" })
|
||||
const second = permission({ id: "perm-2", sessionID: "session-2" })
|
||||
const incoming = permission({ id: "perm-1", toolName: "edit" })
|
||||
|
||||
const result = upsertPermission([first, second], incoming)
|
||||
|
||||
expect(result).toHaveLength(2)
|
||||
expect(result.find((item) => item.id === "perm-1")).toEqual(incoming)
|
||||
expect(result.find((item) => item.id === "perm-2")).toEqual(second)
|
||||
})
|
||||
|
||||
it("removes only permissions from the deleted session", () => {
|
||||
const first = permission({ id: "perm-1", sessionID: "session-1" })
|
||||
const second = permission({ id: "perm-2", sessionID: "session-2" })
|
||||
const third = permission({ id: "perm-3", sessionID: "session-1" })
|
||||
|
||||
const result = removeSessionPermissions([first, second, third], "session-1")
|
||||
|
||||
expect(result).toEqual([second])
|
||||
})
|
||||
})
|
||||
@@ -50,15 +50,21 @@ export const DataBridge: Component<{ children: any }> = (props) => {
|
||||
|
||||
const data = createMemo(() => {
|
||||
const id = session.currentSessionID()
|
||||
const msgs = session.allMessages()
|
||||
const parts = session.allParts()
|
||||
const perms = id ? session.permissions().filter((p) => p.sessionID === id) : []
|
||||
return {
|
||||
session: session.sessions().map((s) => ({ ...s, id: s.id, role: "user" as const })) as unknown as any[],
|
||||
session_status: {} as Record<string, any>,
|
||||
session_diff: {} as Record<string, any[]>,
|
||||
message: msgs as unknown as Record<string, SDKMessage[]>,
|
||||
part: parts as unknown as Record<string, SDKPart[]>,
|
||||
permission: id ? { [id]: session.permissions() as unknown as any[] } : {},
|
||||
message: id ? { [id]: session.messages() as unknown as SDKMessage[] } : {},
|
||||
part: id
|
||||
? Object.fromEntries(
|
||||
session
|
||||
.messages()
|
||||
.map((msg) => [msg.id, session.getParts(msg.id) as unknown as SDKPart[]])
|
||||
.filter(([, parts]) => (parts as SDKPart[]).length > 0),
|
||||
)
|
||||
: {},
|
||||
permission: id ? { [id]: perms as unknown as any[] } : {},
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ export const ChatView: Component<ChatViewProps> = (props) => {
|
||||
const sessionPermissions = () => session.permissions().filter((p) => p.sessionID === id())
|
||||
|
||||
const questionRequest = () => sessionQuestions()[0]
|
||||
const permissionRequest = () => sessionPermissions()[0]
|
||||
const permissionRequest = () => sessionPermissions().find((p) => !p.tool)
|
||||
const blocked = () => sessionPermissions().length > 0 || sessionQuestions().length > 0
|
||||
|
||||
const [responding, setResponding] = createSignal(false)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import type { PermissionRequest } from "../types/messages"
|
||||
|
||||
export function upsertPermission(list: PermissionRequest[], permission: PermissionRequest) {
|
||||
const idx = list.findIndex((item) => item.id === permission.id)
|
||||
if (idx === -1) return [...list, permission]
|
||||
const next = list.slice()
|
||||
next[idx] = permission
|
||||
return next
|
||||
}
|
||||
|
||||
export function removeSessionPermissions(list: PermissionRequest[], sessionID: string) {
|
||||
return list.filter((item) => item.sessionID !== sessionID)
|
||||
}
|
||||
@@ -37,6 +37,7 @@ import type {
|
||||
ExtensionMessage,
|
||||
FileAttachment,
|
||||
} from "../types/messages"
|
||||
import { removeSessionPermissions, upsertPermission } from "./permission-queue"
|
||||
|
||||
// Derive human-readable status from the last streaming part
|
||||
function computeStatus(
|
||||
@@ -508,7 +509,7 @@ export const SessionProvider: ParentComponent = (props) => {
|
||||
}
|
||||
|
||||
function handlePermissionRequest(permission: PermissionRequest) {
|
||||
setPermissions((prev) => [...prev, permission])
|
||||
setPermissions((prev) => upsertPermission(prev, permission))
|
||||
}
|
||||
|
||||
function handleQuestionRequest(question: QuestionRequest) {
|
||||
@@ -603,6 +604,7 @@ export const SessionProvider: ParentComponent = (props) => {
|
||||
return next
|
||||
})
|
||||
}
|
||||
setPermissions((prev) => removeSessionPermissions(prev, sessionID))
|
||||
setStatusMap(
|
||||
produce((map) => {
|
||||
delete map[sessionID]
|
||||
|
||||
Reference in New Issue
Block a user