feat(core): expose session location

This commit is contained in:
Dax Raad
2026-06-02 00:12:42 -04:00
parent bbec00fbd5
commit c1c02f80dd
3 changed files with 25 additions and 24 deletions
+8 -4
View File
@@ -16,6 +16,7 @@ import { SessionProjector } from "./session/projector"
import { SessionMessageTable, SessionTable } from "./session/sql" import { SessionMessageTable, SessionTable } from "./session/sql"
import { SessionSchema } from "./session/schema" import { SessionSchema } from "./session/schema"
import { AbsolutePath, RelativePath } from "./schema" import { AbsolutePath, RelativePath } from "./schema"
import { AgentV2 } from "./agent"
// get project -> project.locations // get project -> project.locations
// //
@@ -141,14 +142,12 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Session") {} export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Session") {}
function fromRow(row: typeof SessionTable.$inferSelect): SessionSchema.Info { function fromRow(row: typeof SessionTable.$inferSelect): SessionSchema.Info {
return new SessionSchema.Info({ return SessionSchema.Info.make({
id: SessionSchema.ID.make(row.id), id: SessionSchema.ID.make(row.id),
projectID: ProjectV2.ID.make(row.project_id), projectID: ProjectV2.ID.make(row.project_id),
workspaceID: row.workspace_id ? WorkspaceV2.ID.make(row.workspace_id) : undefined,
title: row.title, title: row.title,
parentID: row.parent_id ? SessionSchema.ID.make(row.parent_id) : undefined, parentID: row.parent_id ? SessionSchema.ID.make(row.parent_id) : undefined,
path: row.path ?? "", agent: row.agent ? AgentV2.ID.make(row.agent) : undefined,
agent: row.agent ?? undefined,
model: row.model model: row.model
? { ? {
id: ModelV2.ID.make(row.model.id), id: ModelV2.ID.make(row.model.id),
@@ -166,6 +165,11 @@ function fromRow(row: typeof SessionTable.$inferSelect): SessionSchema.Info {
write: row.tokens_cache_write, write: row.tokens_cache_write,
}, },
}, },
location: Location.Ref.make({
directory: AbsolutePath.make(row.directory),
workspaceID: row.workspace_id ? WorkspaceV2.ID.make(row.workspace_id) : undefined,
}),
subpath: row.path ? RelativePath.make(row.path) : undefined,
time: { time: {
created: DateTime.makeUnsafe(row.time_created), created: DateTime.makeUnsafe(row.time_created),
updated: DateTime.makeUnsafe(row.time_updated), updated: DateTime.makeUnsafe(row.time_updated),
+8 -16
View File
@@ -5,9 +5,9 @@ import { Location } from "../location"
import { ModelV2 } from "../model" import { ModelV2 } from "../model"
import { ProjectV2 } from "../project" import { ProjectV2 } from "../project"
import { RelativePath, optionalOmitUndefined, withStatics } from "../schema" import { RelativePath, optionalOmitUndefined, withStatics } from "../schema"
import { WorkspaceV2 } from "../workspace"
import { Identifier } from "../util/identifier" import { Identifier } from "../util/identifier"
import { V2Schema } from "../v2-schema" import { V2Schema } from "../v2-schema"
import { AgentV2 } from "../agent"
export const Delivery = Schema.Literals(["immediate", "deferred"]).annotate({ export const Delivery = Schema.Literals(["immediate", "deferred"]).annotate({
identifier: "Session.Delivery", identifier: "Session.Delivery",
@@ -24,22 +24,12 @@ export const ID = Schema.String.check(Schema.isStartsWith("ses")).pipe(
) )
export type ID = typeof ID.Type export type ID = typeof ID.Type
export const LegacyInfo = Schema.Struct({ export class Info extends Schema.Class<Info>("SessionV2.Info")({
id: ID, id: ID,
location: Location.Ref, parentID: ID.pipe(optionalOmitUndefined),
subpath: RelativePath, // derived from location
project: ProjectV2.ID, // derived from location
})
export type LegacyInfo = typeof LegacyInfo.Type
export class Info extends Schema.Class<Info>("Session.Info")({
id: ID,
parentID: optionalOmitUndefined(ID),
projectID: ProjectV2.ID, projectID: ProjectV2.ID,
workspaceID: optionalOmitUndefined(WorkspaceV2.ID), agent: AgentV2.ID.pipe(Schema.optional),
path: optionalOmitUndefined(Schema.String), model: ModelV2.Ref.pipe(Schema.optional),
agent: optionalOmitUndefined(Schema.String),
model: ModelV2.Ref.pipe(optionalOmitUndefined),
cost: Schema.Finite, cost: Schema.Finite,
tokens: Schema.Struct({ tokens: Schema.Struct({
input: Schema.Finite, input: Schema.Finite,
@@ -53,7 +43,9 @@ export class Info extends Schema.Class<Info>("Session.Info")({
time: Schema.Struct({ time: Schema.Struct({
created: V2Schema.DateTimeUtcFromMillis, created: V2Schema.DateTimeUtcFromMillis,
updated: V2Schema.DateTimeUtcFromMillis, updated: V2Schema.DateTimeUtcFromMillis,
archived: optionalOmitUndefined(V2Schema.DateTimeUtcFromMillis), archived: V2Schema.DateTimeUtcFromMillis.pipe(Schema.optional),
}), }),
title: Schema.String, title: Schema.String,
location: Location.Ref,
subpath: RelativePath.pipe(Schema.optional),
}) {} }) {}
+9 -4
View File
@@ -2494,7 +2494,7 @@ export type SessionBusyError = {
} }
export type V2SessionsResponse = { export type V2SessionsResponse = {
items: Array<SessionInfo> items: Array<SessionV2Info>
cursor: { cursor: {
previous?: string previous?: string
next?: string next?: string
@@ -3369,12 +3369,15 @@ export type ConfigV2ExperimentalPolicy = {
resource: string resource: string
} }
export type SessionInfo = { export type LocationRef = {
directory: string
workspaceID?: string
}
export type SessionV2Info = {
id: string id: string
parentID?: string parentID?: string
projectID: string projectID: string
workspaceID?: string
path?: string
agent?: string agent?: string
model?: { model?: {
id: string id: string
@@ -3397,6 +3400,8 @@ export type SessionInfo = {
archived?: number archived?: number
} }
title: string title: string
location: LocationRef
subpath?: string
} }
export type SessionDelivery = "immediate" | "deferred" export type SessionDelivery = "immediate" | "deferred"