Skip to content

Commit ae32a1b

Browse files
mvanhornclaude
andauthored
feat: filter session history by workspace directory (#11813)
* feat: filter session history by workspace directory Add optional workspaceDirectory field to ListHistoryOptions so callers can scope session lists to a specific workspace. Filtering is case-insensitive and applied before pagination. Omitting the field preserves the existing behavior of returning all sessions. Fixes #9936 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address bot review - typeof guard and test coverage - Use typeof check instead of truthiness for workspaceDirectory to handle malformed session metadata safely - Rename test to match actual coverage (limit only) - Add separate test for combined limit+offset with workspace filter --------- Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 79b8910 commit ae32a1b

3 files changed

Lines changed: 92 additions & 0 deletions

File tree

‎core/protocol/core.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ export enum OnboardingModes {
6363
export interface ListHistoryOptions {
6464
offset?: number;
6565
limit?: number;
66+
workspaceDirectory?: string;
6667
}
6768

6869
export type ToCoreFromIdeOrWebviewProtocol = {

‎core/util/history.test.ts‎

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,87 @@ describe("Full session lifecycle", () => {
7474
});
7575
});
7676

77+
describe("Workspace directory filtering", () => {
78+
beforeAll(() => {
79+
historyManager.clearAll();
80+
historyManager.save({
81+
history: [],
82+
title: "Project A session 1",
83+
workspaceDirectory: "/home/user/project-a",
84+
sessionId: "ws-a-1",
85+
});
86+
historyManager.save({
87+
history: [],
88+
title: "Project B session 1",
89+
workspaceDirectory: "/home/user/project-b",
90+
sessionId: "ws-b-1",
91+
});
92+
historyManager.save({
93+
history: [],
94+
title: "Project A session 2",
95+
workspaceDirectory: "/home/user/project-a",
96+
sessionId: "ws-a-2",
97+
});
98+
historyManager.save({
99+
history: [],
100+
title: "No workspace",
101+
workspaceDirectory: "",
102+
sessionId: "ws-none",
103+
});
104+
});
105+
106+
afterAll(() => {
107+
historyManager.clearAll();
108+
});
109+
110+
test("Filter sessions by workspace directory", () => {
111+
const sessions = historyManager.list({
112+
workspaceDirectory: "/home/user/project-a",
113+
});
114+
expect(sessions.length).toBe(2);
115+
expect(
116+
sessions.every((s) => s.workspaceDirectory === "/home/user/project-a"),
117+
).toBe(true);
118+
});
119+
120+
test("Omitting workspace returns all sessions", () => {
121+
const sessions = historyManager.list({});
122+
expect(sessions.length).toBe(4);
123+
});
124+
125+
test("Workspace filter is case-insensitive", () => {
126+
const sessions = historyManager.list({
127+
workspaceDirectory: "/HOME/USER/PROJECT-A",
128+
});
129+
expect(sessions.length).toBe(2);
130+
});
131+
132+
test("Non-matching workspace returns empty list", () => {
133+
const sessions = historyManager.list({
134+
workspaceDirectory: "/home/user/nonexistent",
135+
});
136+
expect(sessions.length).toBe(0);
137+
});
138+
139+
test("Workspace filter works with limit", () => {
140+
const sessions = historyManager.list({
141+
workspaceDirectory: "/home/user/project-a",
142+
limit: 1,
143+
});
144+
expect(sessions.length).toBe(1);
145+
});
146+
147+
test("Workspace filter works with limit and offset", () => {
148+
const sessions = historyManager.list({
149+
workspaceDirectory: "/home/user/project-a",
150+
limit: 1,
151+
offset: 1,
152+
});
153+
expect(sessions.length).toBe(1);
154+
expect(sessions[0].sessionId).toBe("ws-a-1");
155+
});
156+
});
157+
77158
describe("Many sessions created", () => {
78159
test("Create 100 sessions and list all", () => {
79160
for (let i = 0; i < 100; i++) {

‎core/util/history.ts‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ export class HistoryManager {
3838
})
3939
.reverse();
4040

41+
// Filter by workspace directory if provided
42+
if (options.workspaceDirectory) {
43+
const target = options.workspaceDirectory.toLowerCase();
44+
sessions = sessions.filter(
45+
(session) =>
46+
typeof session.workspaceDirectory === "string" &&
47+
session.workspaceDirectory.toLowerCase() === target,
48+
);
49+
}
50+
4151
// Apply limit and offset
4252
if (options.limit) {
4353
const offset = options.offset || 0;

0 commit comments

Comments
 (0)