@@ -135,8 +135,27 @@ export class SessionStore {
135135 await writeFile ( statePath , `${ JSON . stringify ( next , null , 2 ) } \n` , 'utf-8' ) ;
136136 }
137137
138- async list ( options : ListSessionsPayload ) : Promise < readonly SessionSummary [ ] > {
139- const workDir = normalizeWorkDir ( options . workDir ) ;
138+ async list ( options : ListSessionsPayload = { } ) : Promise < readonly SessionSummary [ ] > {
139+ const workDir =
140+ options . workDir === undefined ? undefined : normalizeRequiredWorkDir ( options . workDir ) ;
141+ const sessionId = normalizeOptionalSessionId ( options . sessionId ) ;
142+
143+ if ( workDir !== undefined ) {
144+ if ( sessionId !== undefined ) {
145+ const local = await this . summaryFromWorkDirSession ( sessionId , workDir ) ;
146+ if ( local !== undefined ) return [ local ] ;
147+ return this . listSessionId ( sessionId ) ;
148+ }
149+ return this . listWorkDir ( workDir ) ;
150+ }
151+
152+ if ( sessionId !== undefined ) {
153+ return this . listSessionId ( sessionId ) ;
154+ }
155+ return this . listAll ( ) ;
156+ }
157+
158+ private async listWorkDir ( workDir : string ) : Promise < readonly SessionSummary [ ] > {
140159 const bucketDir = join ( this . sessionsDir , encodeWorkDirKey ( workDir ) ) ;
141160 let entries ;
142161 try {
@@ -157,6 +176,38 @@ export class SessionStore {
157176 return sessions ;
158177 }
159178
179+ private async listSessionId ( sessionId : string ) : Promise < readonly SessionSummary [ ] > {
180+ try {
181+ return [ await this . get ( sessionId ) ] ;
182+ } catch ( error ) {
183+ if ( error instanceof KimiError && error . code === ErrorCodes . SESSION_NOT_FOUND ) {
184+ return [ ] ;
185+ }
186+ throw error ;
187+ }
188+ }
189+
190+ private async listAll ( ) : Promise < readonly SessionSummary [ ] > {
191+ const index = await readSessionIndex ( this . homeDir , this . sessionsDir ) ;
192+ const sessions : SessionSummary [ ] = [ ] ;
193+ for ( const entry of index . values ( ) ) {
194+ if ( ! ( await isDirectory ( entry . sessionDir ) ) ) continue ;
195+ sessions . push ( await this . summaryFromDir ( entry . sessionId , entry . sessionDir , entry . workDir ) ) ;
196+ }
197+ sessions . sort ( compareSessionSummary ) ;
198+ return sessions ;
199+ }
200+
201+ private async summaryFromWorkDirSession (
202+ sessionId : string ,
203+ workDir : string ,
204+ ) : Promise < SessionSummary | undefined > {
205+ if ( ! isSafeSessionId ( sessionId ) ) return undefined ;
206+ const sessionDir = this . sessionDirFor ( { id : sessionId , workDir } ) ;
207+ if ( ! ( await isDirectory ( sessionDir ) ) ) return undefined ;
208+ return this . summaryFromDir ( sessionId , sessionDir , workDir ) ;
209+ }
210+
160211 async assertDirectory ( id : string ) : Promise < string > {
161212 return ( await this . findExistingSessionEntry ( id ) ) . sessionDir ;
162213 }
@@ -287,6 +338,17 @@ async function readOptionalState(sessionDir: string): Promise<SessionSummaryStat
287338 }
288339}
289340
341+ function normalizeRequiredWorkDir ( workDir : string ) : string {
342+ if ( workDir . trim ( ) === '' ) {
343+ throw new KimiError ( ErrorCodes . REQUEST_WORK_DIR_REQUIRED , 'listSessions requires workDir' ) ;
344+ }
345+ return normalizeWorkDir ( workDir ) ;
346+ }
347+
348+ function normalizeOptionalSessionId ( sessionId : string | undefined ) : string | undefined {
349+ return sessionId === undefined ? undefined : sessionId . trim ( ) ;
350+ }
351+
290352function normalizeForkTitle ( title : string | undefined , fallback : unknown ) : string {
291353 if ( title !== undefined ) {
292354 const normalized = title . trim ( ) ;
0 commit comments