/** * Pure helpers behind the sidebar's project management: the create/rename * title rule (a client-side mirror of the Host's `project-admin` guard, so an * invalid title never leaves the panel) and the session-switcher projection — * the dsh session list folded into the small immutable view the panel renders. * DOM-free so both are unit-testable. * @module dsh-client-ui-mimir/client/project-form */ /** Title length cap of one project (mirrors the Host's project-admin rule). */ export declare const PROJECT_TITLE_MAX_LENGTH = 200; /** * Trim and validate one project title (create and rename share the rule). * @param title - the raw input. * @returns the cleaned title, or null when it is blank or over the cap. */ export declare function cleanProjectTitle(title: string): string | null; /** * The selection hand-off after a successful delete, decided against the * LATEST list and selection (the caller re-reads them after the await, never * its click-time closure): undefined leaves the selection alone (another * project was deleted), an id selects the first remaining project, null * deselects (nothing remains). * @param projects - the post-delete project list. * @param deletedId - the deleted project's id. * @param selectedProjectId - the current selection. * @returns the selection action to apply. */ export declare function nextSelectionAfterDelete(projects: readonly { readonly id: string; }[], deletedId: string, selectedProjectId: string | null): string | null | undefined; /** One session row of the switcher: the delivery target of "… with AI" verbs. */ export interface ResearchSessionEntry { readonly id: string; readonly title: string; readonly running: boolean; } /** The session switcher's immutable view: the list plus the current selection. */ export interface ResearchSessionListView { readonly current: string | null; readonly list: readonly ResearchSessionEntry[]; } /** The slice of the dsh session-list snapshot the projection reads. */ export interface SessionListSource { readonly ids: readonly string[]; readonly byId: Readonly>; } | undefined>>; } /** * The "current" session of the workbench: the row the main conversation view * holds through its `mainView` reference (the sessions service no longer * tracks a global selection; the view's retention IS the selection). * @param state - the sessions service's list snapshot. * @returns the retained session id, or null when no row is main-view retained. */ export declare function currentSessionIdOf(state: SessionListSource): string | null; /** * Project one dsh session-list snapshot into the switcher view. * @param state - the sessions service's list snapshot. * @returns the panel-facing view (current = null when nothing is selected). */ export declare function sessionListView(state: SessionListSource): ResearchSessionListView; /** * Value equality of two switcher views; the observable adapter keeps reference * identity while nothing moved, so the selector hook never re-renders on an * unrelated session-store bump. */ export declare function sameSessionListView(left: ResearchSessionListView, right: ResearchSessionListView): boolean; //# sourceMappingURL=project-form.d.ts.map