refactor(vscode): share worktree reference and background child helpers

This commit is contained in:
marius-kilocode
2026-09-14 10:44:42 +02:00
parent b666fb64ef
commit 0e0b709966
4 changed files with 58 additions and 19 deletions
@@ -1,6 +1,6 @@
import { describe, expect, it } from "bun:test"
import { createRoot } from "solid-js"
import { worktreeReferences } from "../../webview-ui/agent-manager/worktree-references"
import { worktreeDropReference, worktreeReferences } from "../../webview-ui/agent-manager/worktree-references"
import { createProjectStore } from "../../webview-ui/agent-manager/project/store"
import {
buildMentionResults,
@@ -68,6 +68,30 @@ function reply(scope: ReturnType<typeof harness>, paths: string[] = []) {
}
describe("Agent Manager worktree references", () => {
it("drops a worktree card as the same reference shape the picker builds", () => {
const ref = worktreeDropReference(
tree("drop", {
label: "Feature",
branch: "feature/drop",
path: "/repo/.kilo/worktrees/drop",
parentBranch: "develop",
}),
"Feature",
[{ id: "ses_drop", title: "Fix login" }],
true,
)
expect(ref).toEqual({
id: "drop",
name: "Feature",
branch: "feature/drop",
path: "/repo/.kilo/worktrees/drop",
base: "develop",
sessions: [{ id: "ses_drop", title: "Fix login" }],
disabled: true,
})
})
it("uses sidebar names and includes all sessions without selecting a transcript", () => {
const state = createProjectStore("project")
state.setWorktrees([tree("named", { label: "Custom name" }), tree("ordered"), tree("empty")])
@@ -3,6 +3,7 @@ import {
backgroundAgents,
backgroundChildren,
backgroundJobAgents,
children,
fitBackgroundAgents,
showBackgroundAgent,
} from "../../webview-ui/src/components/chat/background-agents"
@@ -101,6 +102,24 @@ describe("backgroundChildren", () => {
})
})
describe("children", () => {
it("keeps background children while listing each task child once in spawn order", () => {
const tools = [
taskPart({ id: "part_1", child: "ses_a" }),
taskPart({ id: "part_2", child: "ses_b", background: true }),
taskPart({ id: "part_3", child: "ses_a" }),
]
expect(children(tools)).toEqual(["ses_a", "ses_b"])
})
it("ignores non-task tools and parts without a child session", () => {
const bash = { id: "part_3", type: "tool", tool: "bash", state: { status: "running", input: {} } } as ToolPart
expect(children([bash, taskPart({ id: "part_4", background: true })])).toEqual([])
})
})
describe("backgroundAgents", () => {
it("lists a running background agent from tool state metadata", () => {
const tools = [taskPart({ child: "ses_child", background: true, description: "Audit deps", agent: "explore" })]
@@ -34,15 +34,12 @@ export function worktreeReferences(
worktree.path,
Math.max(Date.parse(worktree.createdAt) || 0, ...sessions.map((session) => updated.get(session.id) ?? 0)),
)
return {
id: worktree.id,
name: worktree.label || firstOrderedTitle(sessions, state.tabOrder()[worktree.id], basename || worktree.branch),
branch: worktree.branch,
path: worktree.path,
base: worktree.parentBranch,
return worktreeDropReference(
worktree,
worktree.label || firstOrderedTitle(sessions, state.tabOrder()[worktree.id], basename || worktree.branch),
sessions,
disabled: worktree.id === current || state.staleWorktreeIds().has(worktree.id) || state.busy().has(worktree.id),
}
worktree.id === current || state.staleWorktreeIds().has(worktree.id) || state.busy().has(worktree.id),
)
})
.sort(
(a, b) =>
@@ -66,11 +66,12 @@ function meta(part: ToolPart, key: string): unknown {
return (part.state as { metadata?: Record<string, unknown> }).metadata?.[key]
}
/** Child session IDs of every Task tool part, in spawn order, without duplicates. */
export function children(tools: ToolPart[]): string[] {
/** Child session IDs of Task tool parts, optionally restricted to background jobs. */
function taskChildren(tools: ToolPart[], background?: boolean): string[] {
const ids: string[] = []
for (const part of tools) {
if (part.tool !== "task") continue
if (background !== undefined && meta(part, "background") !== background) continue
const id = text(meta(part, "sessionId"))
if (!id || ids.includes(id)) continue
ids.push(id)
@@ -78,16 +79,14 @@ export function children(tools: ToolPart[]): string[] {
return ids
}
/** Child session IDs of every Task tool part, in spawn order, without duplicates. */
export function children(tools: ToolPart[]): string[] {
return taskChildren(tools)
}
/** Child session IDs spawned as background jobs, which show a capped reasoning preview. */
export function backgroundChildren(tools: ToolPart[]): Set<string> {
const ids = new Set<string>()
for (const part of tools) {
if (part.tool !== "task") continue
if (meta(part, "background") !== true) continue
const id = text(meta(part, "sessionId"))
if (id) ids.add(id)
}
return ids
return new Set(taskChildren(tools, true))
}
function working(status: SessionStatusInfo | undefined): boolean {