import type { Logger } from './types.js';
export interface UserTitleEntry {
    title: string;
    renamedAt: string;
}
export type ValidateResult = {
    ok: true;
    title: string;
} | {
    ok: false;
    reason: 'empty' | 'too-long' | 'control-chars';
};
/** Single source of truth for user-title validation. Mirrored in
 *  Sidebar.tsx + SessionMetadataPane.tsx as length-only client-side checks;
 *  the control-char rejection is server-only. */
export declare function validateUserTitle(raw: unknown): ValidateResult;
export declare class UserTitleStore {
    private readonly bySessionId;
    private readonly filePath;
    private readonly logger;
    private loaded;
    constructor(filePath: string, logger: Logger);
    /** Read the persisted file into the in-memory map. Boot-resilient: any
     *  failure (missing file, malformed JSON, permission denied) is logged
     *  and the store starts empty. Never throws. */
    loadFromDisk(): void;
    get(sessionId: string): UserTitleEntry | undefined;
    /** Persist `title` for `sessionId`. Caller is responsible for validating
     *  via `validateUserTitle` first; the store stores whatever it's given. */
    set(sessionId: string, title: string): UserTitleEntry;
    /** Remove the entry for `sessionId` if present. Called on session
     *  purge/delete cascade so the file doesn't accrete orphans.
     *  Returns true when an entry was removed. */
    remove(sessionId: string): boolean;
    /** Current in-memory snapshot — diagnostic only. */
    size(): number;
    private persistAtomic;
}
//# sourceMappingURL=user-title-store.d.ts.map