mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-08-28 19:11:03 +08:00
test(agent-manager): cover multi-project setup terminals
This commit is contained in:
@@ -197,6 +197,45 @@ describe("Agent Manager terminal state", () => {
|
||||
})
|
||||
})
|
||||
|
||||
it("hydrates script terminals into independent project contexts", () => {
|
||||
createRoot((dispose) => {
|
||||
const item = scene()
|
||||
item.dispatch({
|
||||
type: "agentManager.scriptTerminals",
|
||||
terminals: [
|
||||
{
|
||||
terminalId: "script:setup-a",
|
||||
projectId: "prj-a",
|
||||
worktreeId: "wt-1",
|
||||
kind: "setup",
|
||||
title: "Setup",
|
||||
wsUrl: "ws://script:setup-a",
|
||||
state: "running",
|
||||
font,
|
||||
},
|
||||
{
|
||||
terminalId: "script:setup-b",
|
||||
projectId: "prj-b",
|
||||
worktreeId: "wt-1",
|
||||
kind: "setup",
|
||||
title: "Setup",
|
||||
wsUrl: "ws://script:setup-b",
|
||||
state: "running",
|
||||
font,
|
||||
},
|
||||
],
|
||||
} satisfies ExtensionMessage)
|
||||
|
||||
expect(item.state.sidesForContext("prj-a:wt-1").map((term) => term.id)).toEqual(["script:setup-a"])
|
||||
expect(item.state.sidesForContext("prj-b:wt-1").map((term) => term.id)).toEqual(["script:setup-b"])
|
||||
expect(item.events.running).toEqual([
|
||||
{ contextKey: "prj-a:wt-1", terminalId: "script:setup-a" },
|
||||
{ contextKey: "prj-b:wt-1", terminalId: "script:setup-b" },
|
||||
])
|
||||
dispose()
|
||||
})
|
||||
})
|
||||
|
||||
it("activates a Setup terminal that hydrates before its worktree is selected", () => {
|
||||
createRoot((dispose) => {
|
||||
const item = scene(LOCAL)
|
||||
|
||||
@@ -156,6 +156,32 @@ describe("ScriptTerminalManager", () => {
|
||||
expect(ctx.snapshots.at(-1)?.[0]?.worktreeId).toBeNull()
|
||||
})
|
||||
|
||||
it("keeps identical worktree script terminals independent across projects", async () => {
|
||||
let id = 0
|
||||
const ctx = harness({
|
||||
create: async () => ({
|
||||
data: { location: { directory: config.cwd }, data: { ...info(), id: `pty-${++id}` } },
|
||||
}),
|
||||
get: async () => ({
|
||||
data: { location: { directory: config.cwd }, data: { ...info(), id: `pty-${id}` } },
|
||||
}),
|
||||
})
|
||||
|
||||
await ctx.manager.start("setup", { ...config, projectId: "prj-a" }, () => undefined)
|
||||
await ctx.manager.start("setup", { ...config, projectId: "prj-b" }, () => undefined)
|
||||
|
||||
expect(ctx.snapshots.at(-1)).toEqual([
|
||||
expect.objectContaining({ projectId: "prj-a", worktreeId: "wt-1", kind: "setup" }),
|
||||
expect.objectContaining({ projectId: "prj-b", worktreeId: "wt-1", kind: "setup" }),
|
||||
])
|
||||
expect(ctx.manager.active("setup", "wt-1", "prj-a")).toBe(true)
|
||||
expect(ctx.manager.active("setup", "wt-1", "prj-b")).toBe(true)
|
||||
|
||||
await ctx.manager.clear("setup", "wt-1", "prj-a")
|
||||
expect(ctx.manager.active("setup", "wt-1", "prj-a")).toBe(false)
|
||||
expect(ctx.manager.active("setup", "wt-1", "prj-b")).toBe(true)
|
||||
})
|
||||
|
||||
it("builds canonical authenticated replay URLs", () => {
|
||||
const value = buildScriptTerminalWsUrl(
|
||||
{ baseUrl: "http://127.0.0.1:4096", password: "secret" },
|
||||
|
||||
@@ -312,7 +312,10 @@ describe("runWorktreeSetupScript", () => {
|
||||
return dir
|
||||
}
|
||||
|
||||
function flow(script: boolean, opts?: { destination?: "vscode" | "agentManager"; code?: number }) {
|
||||
function flow(
|
||||
script: boolean,
|
||||
opts?: { destination?: "vscode" | "agentManager"; code?: number; projectId?: string },
|
||||
) {
|
||||
const posted: AgentManagerOutMessage[] = []
|
||||
const runs: string[] = []
|
||||
const ctx = harness()
|
||||
@@ -323,6 +326,7 @@ describe("runWorktreeSetupScript", () => {
|
||||
const input = {
|
||||
service: new SetupScriptService(root(script)),
|
||||
destination: opts?.destination ?? ("vscode" as const),
|
||||
projectId: opts?.projectId,
|
||||
worktreeId: "wt-1",
|
||||
trusted: () => true,
|
||||
manager: ctx.manager,
|
||||
@@ -349,6 +353,17 @@ describe("runWorktreeSetupScript", () => {
|
||||
expect(scene.runs).toEqual(["/repo/worktree"])
|
||||
})
|
||||
|
||||
it("stamps progress and embedded terminals with the owning project", async () => {
|
||||
const scene = flow(true, { destination: "agentManager", projectId: "prj-a" })
|
||||
const result = runWorktreeSetupScript(scene.input, { worktreePath: "/repo/worktree", repoPath: "/repo" })
|
||||
await new Promise((resolve) => setTimeout(resolve, 0))
|
||||
|
||||
expect(scene.posted[0]).toMatchObject({ projectId: "prj-a", worktreeId: "wt-1" })
|
||||
expect(scene.ctx.starts[0]?.config).toMatchObject({ projectId: "prj-a", worktreeId: "wt-1" })
|
||||
scene.ctx.starts[0]?.done({ exitCode: 0 })
|
||||
await result
|
||||
})
|
||||
|
||||
it("stays silent when no setup script is configured", async () => {
|
||||
const scene = flow(false)
|
||||
await runWorktreeSetupScript(scene.input, { worktreePath: "/repo/worktree", repoPath: "/repo" })
|
||||
|
||||
@@ -2358,10 +2358,10 @@ const AgentManagerContent: Component = () => {
|
||||
terminalDestination={sideCtl.destination}
|
||||
terminalDestinationActive={() => sidePanel() === "terminal"}
|
||||
terminalKeybind={() => kb().showTerminal ?? ""}
|
||||
onTerminalDestinationOpen={() => {
|
||||
cancelAmbientSetup()
|
||||
sideCtl.openPreferred("tab_toolbar")
|
||||
}}
|
||||
onTerminalDestinationOpen={() => {
|
||||
cancelAmbientSetup()
|
||||
sideCtl.openPreferred("tab_toolbar")
|
||||
}}
|
||||
onTerminalDestinationChoose={sideCtl.choose}
|
||||
track={metrics.click}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user