diff --git a/packages/kilo-vscode/tests/unit/project-session-filter.test.ts b/packages/kilo-vscode/tests/unit/project-session-filter.test.ts index 4289e99a22..910dd84450 100644 --- a/packages/kilo-vscode/tests/unit/project-session-filter.test.ts +++ b/packages/kilo-vscode/tests/unit/project-session-filter.test.ts @@ -1,5 +1,9 @@ import { describe, expect, it } from "bun:test" -import { rootSessions } from "../../webview-ui/agent-manager/project/session-filter" +import { + rootSessions, + worktreeSessionIds, + worktreeSessions, +} from "../../webview-ui/agent-manager/project/session-filter" import type { ProjectSessionInfo } from "../../webview-ui/src/types/messages" const session = (id: string, worktreeId: string | null, parentID: string | null): ProjectSessionInfo => ({ @@ -23,4 +27,19 @@ describe("rootSessions", () => { expect(rootSessions(sessions, null).map((item) => item.id)).toEqual(["root"]) }) + + it("preserves managed membership, chronological fallback, and custom tab order", () => { + const rows = [ + { ...session("new", "wt-1", null), createdAt: "2026-01-02T00:00:00.000Z" }, + session("old", "wt-1", null), + session("child", "wt-1", "old"), + session("other", "wt-2", null), + ] + const managed = rows.map((item) => ({ id: item.id, worktreeId: item.worktreeId, createdAt: item.createdAt })) + expect([...worktreeSessionIds("wt-1", managed)]).toEqual(["new", "old", "child"]) + expect(worktreeSessions("wt-1", managed, rows, undefined).map((item) => item.id)).toEqual(["old", "new"]) + expect(worktreeSessions("wt-1", managed, rows, ["missing", "new"]).map((item) => item.id)).toEqual(["new", "old"]) + expect(rows.map((item) => item.id)).toEqual(["new", "old", "child", "other"]) + expect(worktreeSessions("missing", managed, rows, undefined)).toEqual([]) + }) }) diff --git a/packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx b/packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx index 1d0041f542..fbe8ac8478 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx +++ b/packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx @@ -85,6 +85,7 @@ import { SidebarBody } from "./SidebarBody" import { TabBar } from "./TabBar" import { createProjectLive } from "./project/live" import { createProjectSessionsLive } from "./project/sessions-live" +import { worktreeSessionIds as worktreeMembership, worktreeSessions } from "./project/session-filter" import { applyProjectSelection, createTargetRememberer } from "./project/selection" import { createLocalSessions, persistLocalTabs, projectLocalIds, projectLocalSessions } from "./project/local-tabs" import { createProjectRegistry, type PersistedProjectTabs } from "./project/registry" @@ -778,20 +779,8 @@ const AgentManagerContent: Component = () => { title: () => t("agentManager.session.newSession"), }) - const sessionsForWorktree = (worktreeId: string): SessionInfo[] => { - const ids = new Set( - managedSessions() - .filter((ms) => ms.worktreeId === worktreeId) - .map((ms) => ms.id), - ) - return applyTabOrder( - session - .sessions() - .filter((s) => isKnownRootSession(s) && ids.has(s.id)) - .sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()), - worktreeTabOrder()[worktreeId], - ) - } + const sessionsForWorktree = (id: string) => + worktreeSessions(id, managedSessions(), session.sessions(), worktreeTabOrder()[id]) const activeWorktreeSessions = createMemo((): SessionInfo[] => { const sel = selection() @@ -802,11 +791,7 @@ const AgentManagerContent: Component = () => { const activeWorktreeSessionIds = createMemo | undefined>(() => { const sel = selection() if (!sel || sel === LOCAL) return undefined - return new Set( - managedSessions() - .filter((item) => item.worktreeId === sel) - .map((item) => item.id), - ) + return worktreeMembership(sel, managedSessions()) }) const activeTabs = createMemo((): SessionInfo[] => { diff --git a/packages/kilo-vscode/webview-ui/agent-manager/project/session-filter.ts b/packages/kilo-vscode/webview-ui/agent-manager/project/session-filter.ts index 776244e3be..cc19c5e41c 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/project/session-filter.ts +++ b/packages/kilo-vscode/webview-ui/agent-manager/project/session-filter.ts @@ -1,6 +1,26 @@ -import type { ProjectSessionInfo } from "../../src/types/messages" +import type { ManagedSessionState, ProjectSessionInfo, SessionInfo } from "../../src/types/messages" import { isKnownRootSession } from "../navigate" +import { applyTabOrder } from "../tab-order" export function rootSessions(sessions: ProjectSessionInfo[], worktreeId: string | null): ProjectSessionInfo[] { return sessions.filter((session) => session.worktreeId === worktreeId && isKnownRootSession(session)) } + +export function worktreeSessionIds(id: string, sessions: ManagedSessionState[]) { + return new Set(sessions.filter((session) => session.worktreeId === id).map((session) => session.id)) +} + +export function worktreeSessions( + id: string, + managed: ManagedSessionState[], + sessions: SessionInfo[], + order: string[] | undefined, +) { + const ids = worktreeSessionIds(id, managed) + return applyTabOrder( + sessions + .filter((session) => isKnownRootSession(session) && ids.has(session.id)) + .sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()), + order, + ) +}