Merge pull request #6884 from Kilo-Org/mark/fix-agent-manager-permission-scope

fix(vscode): scope permissions/questions to current session family in Agent Manager
This commit is contained in:
Mark IJbema
2026-03-10 18:58:36 +01:00
committed by GitHub
@@ -3,7 +3,7 @@
* Main chat container that combines all chat components
*/
import { Component, Show, createEffect, on, onCleanup, onMount } from "solid-js"
import { Component, Show, createEffect, createMemo, on, onCleanup, onMount } from "solid-js"
import { Button } from "@kilocode/kilo-ui/button"
import { Icon } from "@kilocode/kilo-ui/icon"
import { TaskHeader } from "./TaskHeader"
@@ -32,21 +32,50 @@ export const ChatView: Component<ChatViewProps> = (props) => {
const id = () => session.currentSessionID()
const hasMessages = () => session.messages().length > 0
const idle = () => session.status() !== "busy"
// Include ALL pending permissions/questions -- both from the current session
// and from child sessions (subagents). The extension host already filters
// SSE events to only tracked sessions, so everything in these lists is
// relevant to the current workspace.
const allPermissions = () => session.permissions()
const allQuestions = () => session.questions()
// Bottom-dock permission: prefer current-session permissions,
// then fall back to any pending permission (including child sessions).
// Collect child session IDs spawned by task tools in the current session
// (recursive: subagents can spawn their own subagents).
const sessionFamily = createMemo<Set<string>>(() => {
const root = id()
if (!root) return new Set()
const family = new Set([root])
const parts = session.allParts()
const messages = session.allMessages()
const queue = [root]
while (queue.length > 0) {
const sid = queue.pop()!
const msgs = messages[sid]
if (!msgs) continue
for (const msg of msgs) {
const msgParts = parts[msg.id]
if (!msgParts) continue
for (const p of msgParts) {
if (p.type !== "tool") continue
const child = (p as { metadata?: { sessionId?: string } }).metadata?.sessionId
if (child && !family.has(child)) {
family.add(child)
queue.push(child)
}
}
}
}
return family
})
// Filter permissions/questions to the current session + its child sessions
// (subagents). In the Agent Manager all worktree sessions share one provider,
// so without this filter prompts from unrelated sessions would leak through.
const scopedPermissions = () => session.permissions().filter((p) => sessionFamily().has(p.sessionID))
const scopedQuestions = () => session.questions().filter((q) => sessionFamily().has(q.sessionID))
// Bottom-dock permission: prefer current-session non-tool permissions,
// then fall back to any scoped pending permission (including child sessions).
const questionRequest = () =>
allQuestions().find((q) => q.sessionID === id() && !q.tool) ??
allQuestions().find((q) => !q.tool) ??
allQuestions()[0]
const permissionRequest = () => allPermissions().find((p) => p.sessionID === id()) ?? allPermissions()[0]
const blocked = () => allPermissions().length > 0 || allQuestions().length > 0
scopedQuestions().find((q) => q.sessionID === id() && !q.tool) ??
scopedQuestions().find((q) => !q.tool) ??
scopedQuestions()[0]
const permissionRequest = () => scopedPermissions().find((p) => p.sessionID === id()) ?? scopedPermissions()[0]
const blocked = () => scopedPermissions().length > 0 || scopedQuestions().length > 0
// When a bottom-dock permission/question disappears while the session is busy,
// the scroll container grows taller. Dispatch a custom event so MessageList can