fix(cli): worktree session list ignoring SDK-injected directory filter

The SDK rewrite interceptor injects directory=<cwd> into every GET request.
The experimental session list endpoint was passing this to listGlobal even
when worktrees=true, restricting results to only the current directory.
Skip the directory filter when worktrees is active so all worktree sessions
are returned. Add regression test that includes directory in query params.
This commit is contained in:
Alex Alecu
2026-04-15 13:54:49 +03:00
parent fb6beddffc
commit 74288ef0c2
2 changed files with 65 additions and 1 deletions
@@ -473,7 +473,7 @@ export const ExperimentalRoutes = lazy(() =>
const sessions: Session.GlobalInfo[] = []
for await (const session of Session.listGlobal({
projectID, // kilocode_change
directory: query.directory,
directory: query.worktrees ? undefined : query.directory, // kilocode_change - ignore SDK-injected directory when listing across worktrees
directories, // kilocode_change
roots: query.roots,
start: query.start,
@@ -89,4 +89,68 @@ describe("experimental.session.list", () => {
await $`git worktree remove ${worktree}`.cwd(first.path).quiet().nothrow()
}
})
test("worktrees=true ignores SDK-injected directory query param", async () => {
await using first = await tmpdir({ git: true })
await using second = await tmpdir({ git: true })
const worktree = path.join(first.path, "..", path.basename(first.path) + "-worktree")
try {
await $`git worktree add ${worktree} -b test-branch-sdk-${Date.now()}`.cwd(first.path).quiet()
const share = Config.get
Config.get = async () => ({ share: "manual" }) as Awaited<ReturnType<typeof Config.get>>
try {
const { Server } = await import("../../src/server/server")
const { Session } = await import("../../src/session/index")
const branch = await Instance.provide({
directory: worktree,
fn: async () => Session.create({ title: "worktree-session" }),
})
const root = await Instance.provide({
directory: first.path,
fn: async () => ({
app: Server.Default().app,
project: await Server.Default().app.request("/project/current", {
headers: { "x-kilo-directory": first.path },
}),
session: await Session.create({ title: "root-session" }),
}),
})
await Instance.provide({
directory: second.path,
fn: async () => Session.create({ title: "other-project-session" }),
})
const app = root.app
const project = await root.project.json()
// Include directory in query params — mimics what the SDK rewrite interceptor does.
// Without the server fix, this would restrict results to only first.path sessions.
const response = await app.request(
`/experimental/session?projectID=${encodeURIComponent(project.id)}&roots=true&worktrees=true&directory=${encodeURIComponent(first.path)}`,
{
headers: { "x-kilo-directory": first.path },
},
)
expect(response.status).toBe(200)
const body = await response.json()
const ids = body.map((item: { id: string }) => item.id)
// Both root and worktree sessions must be returned despite directory= in query
expect(ids).toContain(root.session.id)
expect(ids).toContain(branch.id)
expect(body.some((item: { title: string }) => item.title === "other-project-session")).toBe(false)
} finally {
Config.get = share
}
} finally {
await $`git worktree remove ${worktree}`.cwd(first.path).quiet().nothrow()
}
})
})