fix: keep session titles and lists in sync

Update sidebar titles from session events
Load all session pages instead of partial lists
Refresh sessions only for newly added project directories
This commit is contained in:
Bohdan Triapitsyn
2026-06-03 18:43:13 +03:00
parent 874dc15263
commit 837a47b6a3
5 changed files with 284 additions and 23 deletions
+40 -1
View File
@@ -37,6 +37,41 @@ const readResponseHeader = (response: unknown, header: string): string | null =>
return typeof direct === "string" ? direct : null;
};
const formatSdkError = (error: unknown): string => {
if (error instanceof Error) return error.message;
if (typeof error === "string") return error;
if (error && typeof error === "object" && "message" in error && typeof (error as { message?: unknown }).message === "string") {
return (error as { message: string }).message;
}
try {
return JSON.stringify(error);
} catch {
return String(error);
}
};
const unwrapSessionList = (
result: { data?: Session[]; error?: unknown; response?: { status?: number } },
operation: string,
): GlobalSessionRecord[] => {
if (result.error) {
const status = result.response?.status;
const error = new Error(`${operation} failed${status ? ` (${status})` : ""}: ${formatSdkError(result.error)}`);
if (status !== undefined) {
(error as Error & { status?: number }).status = status;
}
throw error;
}
if (!Array.isArray(result.data)) {
const error = new Error(`${operation} returned no data`);
(error as Error & { status?: number }).status = 503;
throw error;
}
return result.data as GlobalSessionRecord[];
};
export const readNextCursor = (response: unknown): number | null => {
return toNumber(readResponseHeader(response, "x-next-cursor"));
};
@@ -63,7 +98,9 @@ export const isMissingGlobalSessionsEndpointError = (error: unknown): boolean =>
export async function listGlobalSessionPages(
apiClient: OpencodeClient,
options: {
directory?: string;
archived: boolean;
roots?: boolean;
pageSize: number;
onPage?: (sessions: GlobalSessionRecord[]) => void;
},
@@ -75,14 +112,16 @@ export async function listGlobalSessionPages(
while (true) {
const response = await retry(
() => apiClient.experimental.session.list({
...(options.directory ? { directory: options.directory } : {}),
archived: options.archived,
...(options.roots !== undefined ? { roots: options.roots } : {}),
limit: options.pageSize,
...(cursor !== undefined ? { cursor } : {}),
}),
{ attempts: 3, delay: 500, retryIf: () => true },
);
const payload = Array.isArray(response.data) ? (response.data as GlobalSessionRecord[]) : [];
const payload = unwrapSessionList(response, "experimental.session.list");
if (payload.length === 0) break;
let appended = 0;