diff --git a/packages/core/src/session.ts b/packages/core/src/session.ts index 7454e0fa752..be300d47dd8 100644 --- a/packages/core/src/session.ts +++ b/packages/core/src/session.ts @@ -263,6 +263,8 @@ export const layer = Layer.effect( if ("directory" in input) conditions.push(eq(SessionTable.directory, input.directory)) if (input.workspaceID) conditions.push(eq(SessionTable.workspace_id, input.workspaceID)) if ("project" in input) conditions.push(eq(SessionTable.project_id, input.project)) + if ("subpath" in input && input.subpath) + conditions.push(or(eq(SessionTable.path, input.subpath), like(SessionTable.path, `${input.subpath}/%`))!) if (input.search) conditions.push(like(SessionTable.title, `%${input.search}%`)) if (input.anchor) { conditions.push( diff --git a/packages/core/test/session-create.test.ts b/packages/core/test/session-create.test.ts index 6fd80c60da1..3611935c69c 100644 --- a/packages/core/test/session-create.test.ts +++ b/packages/core/test/session-create.test.ts @@ -11,7 +11,7 @@ import { ModelV2 } from "@opencode-ai/core/model" import { ProjectV2 } from "@opencode-ai/core/project" import { ProjectTable } from "@opencode-ai/core/project/sql" import { ProviderV2 } from "@opencode-ai/core/provider" -import { AbsolutePath } from "@opencode-ai/core/schema" +import { AbsolutePath, RelativePath } from "@opencode-ai/core/schema" import { SessionV2 } from "@opencode-ai/core/session" import { SessionV1 } from "@opencode-ai/core/v1/session" import { Prompt } from "@opencode-ai/core/session/prompt" @@ -426,3 +426,28 @@ describe("SessionV2.create", () => { }), ) }) + +describe("SessionV2.list", () => { + it.effect("limits project sessions to the requested subpath", () => + Effect.gen(function* () { + const session = yield* SessionV2.Service + const { db } = yield* Database.Service + const core = yield* session.create({ location }) + const nested = yield* session.create({ location }) + const web = yield* session.create({ location }) + + yield* Effect.all([ + db.update(SessionTable).set({ path: "packages/core" }).where(eq(SessionTable.id, core.id)).run(), + db.update(SessionTable).set({ path: "packages/core/test" }).where(eq(SessionTable.id, nested.id)).run(), + db.update(SessionTable).set({ path: "packages/web" }).where(eq(SessionTable.id, web.id)).run(), + ]).pipe(Effect.orDie) + + const listed = yield* session.list({ + project: ProjectV2.ID.global, + subpath: RelativePath.make("packages/core"), + }) + + expect(new Set(listed.map((item) => item.id))).toEqual(new Set([core.id, nested.id])) + }), + ) +})