/** * Session card model (PR1) — pure projection of `SessionRow` (the shape served * by `/api/sessions` and emitted by worker-pool publishers) into list-card and * detail-card DTOs. * * Zero runtime IO. The only outside type touched is `SessionRow`, brought in * as a TYPE-ONLY import so the runtime imports in `dashboard-rows.ts:11-13` * (`terminal-url` / `bot-registry` / `lark-hosts`) never bleed into this * module. */ import type { SessionRow } from '../core/dashboard-rows.js'; import type { ButtonState, PaginationMeta, StatusDot } from './card-model-types.js'; /** Concrete status values a SessionRow can carry (mirrors `StreamStatus | 'closed' | 'dormant'`). */ export type SessionStatus = 'working' | 'idle' | 'analyzing' | 'stalled' | 'limited' | 'starting' | 'dormant' | 'closed'; /** Status-chip filter value — all StreamStatus + 'closed' + 'all'. */ export type StatusChip = SessionStatus | 'all'; /** A single row projected for the sessions list card. Keeps `raw` for downstream renderers. */ export interface SessionRowDto { sessionId: string; /** Display dot — color tone + pulse + i18n-free label key. */ dot: StatusDot; /** Primary text: `title || sessionId`. */ primary: string; /** Secondary text: `cliId · workingDir · relativeTime` joined by ' · '. */ secondary: string; cliId: string; status: string; lastMessageAt: number; webPort: number | null; scope?: 'thread' | 'chat'; /** * Raw row preserved for downstream card-builder use. */ raw: SessionRow; } /** Locate-button mode — chat-scope sessions open the chat directly; thread-scope opens the topic. */ export type LocateMode = 'openTopic' | 'openChat'; /** Action availability for the 4 primary detail buttons + locate sub-mode. */ export interface SessionActionMatrix { resume: ButtonState; close: ButtonState; openTerminal: ButtonState; locate: ButtonState; locateMode: LocateMode; } /** Detail-card DTO. Action matrix encodes every visibility rule. */ export interface SessionDetailDto { sessionId: string; status: string; dot: StatusDot; title: string; chatId: string; cliId: string; workingDir?: string; webPort: number | null; scope?: 'thread' | 'chat'; actions: SessionActionMatrix; raw: SessionRow; } /** Map a SessionRow's status into a UI status dot (tone + pulse + i18n label key). Pure. */ export declare function statusToDot(status: string): StatusDot; /** Build a SessionRowDto from a raw SessionRow, including dot + primary/secondary text. */ export declare function composeEntries(rows: ReadonlyArray, nowMs?: number): SessionRowDto[]; /** * Filter entries by status chip. `all` short-circuits with a shallow copy * (same content + order, but a fresh array so downstream pipelines can rely * on a non-aliased reference). */ export declare function filterByStatus(entries: ReadonlyArray, chip: StatusChip): SessionRowDto[]; /** Filter entries by case-insensitive substring against sessionId / title / chatId / workingDir. */ export declare function filterBySearch(entries: ReadonlyArray, query: string | undefined): SessionRowDto[]; /** Filter entries by CLI id. `undefined` / empty string returns input unchanged. */ export declare function filterByCli(entries: ReadonlyArray, cliId: string | undefined): SessionRowDto[]; /** Sort entries by (status rank ascending, lastMessageAt descending). Returns a new array. */ export declare function sortByStatus(entries: ReadonlyArray): SessionRowDto[]; /** Slice a list into the requested page. Clamps invalid page/pageSize to safe values. */ export declare function paginate(items: ReadonlyArray, page: number | undefined, pageSize: number | undefined): { items: T[]; meta: PaginationMeta; }; /** Build the detail-card DTO with the full action matrix. */ export declare function composeDetail(row: SessionRow, _nowMs?: number): SessionDetailDto; //# sourceMappingURL=session-card-model.d.ts.map