Files
openchamber/packages/ui/src/lib/sessionReviewMetadata.ts
T

83 lines
2.6 KiB
TypeScript
Raw Normal View History

2026-06-07 01:22:40 +03:00
import type { Session } from '@opencode-ai/sdk/v2';
export type SessionMetadataRecord = Record<string, unknown>;
type OpenChamberMetadata = {
kind?: 'review';
originalSessionID?: string;
reviewSessionID?: string;
};
const isRecord = (value: unknown): value is Record<string, unknown> =>
Boolean(value && typeof value === 'object' && !Array.isArray(value));
export const getSessionMetadata = (session: Session | null | undefined): SessionMetadataRecord => {
const metadata = (session as (Session & { metadata?: unknown }) | null | undefined)?.metadata;
return isRecord(metadata) ? metadata : {};
};
const getOpenChamberMetadata = (metadata: SessionMetadataRecord): OpenChamberMetadata => {
const value = metadata.openchamber;
return isRecord(value) ? value as OpenChamberMetadata : {};
};
export const getReviewSessionID = (session: Session | null | undefined): string | null => {
const value = getOpenChamberMetadata(getSessionMetadata(session)).reviewSessionID;
return typeof value === 'string' && value.trim().length > 0 ? value : null;
};
export const getOriginalSessionID = (session: Session | null | undefined): string | null => {
const value = getOpenChamberMetadata(getSessionMetadata(session)).originalSessionID;
return typeof value === 'string' && value.trim().length > 0 ? value : null;
};
export const isReviewSession = (session: Session | null | undefined): boolean =>
getOpenChamberMetadata(getSessionMetadata(session)).kind === 'review' && Boolean(getOriginalSessionID(session));
export const withReviewSessionLink = (
metadata: SessionMetadataRecord,
reviewSessionID: string,
): SessionMetadataRecord => {
const current = getOpenChamberMetadata(metadata);
return {
...metadata,
openchamber: {
...current,
reviewSessionID,
},
};
};
export const withReviewSessionMarker = (
metadata: SessionMetadataRecord,
originalSessionID: string,
): SessionMetadataRecord => {
const current = getOpenChamberMetadata(metadata);
return {
...metadata,
openchamber: {
...current,
kind: 'review' as const,
originalSessionID,
},
};
};
export const withoutReviewSessionLink = (
metadata: SessionMetadataRecord,
reviewSessionID: string,
): SessionMetadataRecord => {
const current = getOpenChamberMetadata(metadata);
if (current.reviewSessionID !== reviewSessionID) return metadata;
const restOpenChamber = { ...current };
delete restOpenChamber.reviewSessionID;
const next: SessionMetadataRecord = { ...metadata };
if (Object.keys(restOpenChamber).length > 0) {
next.openchamber = restOpenChamber;
} else {
delete next.openchamber;
}
return next;
};