import type { ChatMessage } from '../types.js';
export declare const DEFAULT_FINAL_SUMMARY_MAX_CHARS = 16000;
export declare function extractFinalSummaryFromMessages(messages: ChatMessage[] | null | undefined, maxChars?: number): string;
export declare function readChatMessageTimestampMs(message: ChatMessage | null | undefined): number | undefined;
/**
 * Turn-scoped variant of extractFinalSummaryFromMessages. Selects the last
 * user-facing assistant/model bubble whose own timestamp is at/after the
 * producing turn's start (`minTimestampMs`). This is the NOTIF Defect-B fix:
 * a completion event's finalSummary must describe the turn THAT completed, not
 * the prior task's last bubble. For native-source providers (claude-cli) the
 * external transcript holds the ENTIRE session history filtered only by session
 * start, so a completion debounce that fires before the producing turn's final
 * assistant bubble has landed would otherwise echo the previous task's tail.
 * A message whose timestamp predates the turn start is skipped; if no in-turn
 * assistant bubble exists yet, returns '' (weak/empty) — never the stale tail.
 *
 * Mirrors the reconcile path's transcriptAfterDispatch guard (mesh-events-stale):
 * a bubble only counts if its timestamp proves it was produced after the turn began.
 * When `minTimestampMs` is undefined the behaviour is identical to the unscoped
 * extractor (no turn boundary known → no filtering).
 */
export declare function extractFinalSummaryFromMessagesAfter(messages: ChatMessage[] | null | undefined, minTimestampMs: number | undefined, maxChars?: number): string;
/**
 * Like extractFinalSummaryFromMessages but also returns the ISO timestamp of the
 * selected final assistant/model message. Completion reconciliation needs the
 * timestamp to prove the transcript was produced AFTER the dispatch — without it
 * reconcileDirectDispatchCompletionFromTranscript rejects non-JSON summaries as
 * "transcript_not_proven_after_dispatch". The summary selection is identical so the
 * timestamp always belongs to the message whose text became the summary.
 */
export declare function extractFinalAssistantSummaryEvidence(messages: ChatMessage[] | null | undefined, maxChars?: number): {
    finalSummary: string;
    transcriptMessageAt?: string;
};
/**
 * EARLYNOTIFY-GATEBYPASS (a)/(b) — the shared turn-finality selector for the completion
 * final-assistant judgement, so the ~duplicated "which bubble is the turn's final answer"
 * logic is decided ONE way (UNIFY A-6).
 *
 * Returns the message that qualifies as the turn's FINAL assistant bubble, or null when the
 * transcript does not (yet) prove a turn end. The rule is a NON-EMPTY LATEST user-facing
 * assistant/model bubble:
 *   - Scanning from the end, the FIRST user-facing assistant/model bubble encountered IS the
 *     turn-end candidate. If it is EMPTY (a streaming placeholder / mid-turn narration whose
 *     text has not landed), the turn is still in flight → return null. Crucially we do NOT walk
 *     back past that empty bubble to promote an EARLIER assistant narration to "final" (the
 *     Defect-B walk-back).
 *   - Trailing activity/internal bubbles (tool/thought/status) are skipped — they are not the
 *     assistant's user-facing answer.
 *   - A trailing user-facing USER message (a freshly dispatched task with no reply yet) means the
 *     assistant did not have the last word — no earlier bubble is promoted here; callers that must
 *     still reach a prior turn's tail use the timestamp-scoped extractor instead.
 *
 * A bare snapshot-idle with an arbitrary non-empty tail therefore does NOT qualify as a turn end;
 * only a genuine latest-assistant bubble does. Turn-finality signals that live OUTSIDE the
 * transcript (a committed generating→idle FSM transition, a self-attributing final_summary_json,
 * or a continuous-idle streak) are enforced by the callers (the CLI completion gate, the reconcile
 * grace gate) on top of this structural check.
 */
export declare function selectFinalAssistantTurnEndMessage(messages: ChatMessage[] | null | undefined): ChatMessage | null;
export declare const BUILTIN_CHAT_MESSAGE_KINDS: readonly ["standard", "thought", "tool", "terminal", "system"];
export type BuiltinChatMessageKind = typeof BUILTIN_CHAT_MESSAGE_KINDS[number];
export type ChatMessageKind = BuiltinChatMessageKind | (string & {});
export declare const CHAT_MESSAGE_VISIBILITIES: readonly ["user", "debug", "internal", "hidden"];
export declare const CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES: readonly ["visible", "chat", "user", "debug", "internal", "hidden"];
export declare const CHAT_MESSAGE_AUDIENCES: readonly ["chat", "debug", "trace", "internal"];
export declare const CHAT_MESSAGE_SOURCES: readonly ["assistant_text", "tool_call", "terminal_command", "runtime_activity", "runtime_status", "provider_chrome", "control"];
export declare const CHAT_MESSAGE_ACTIVITY_SOURCES: readonly ["tool_call", "terminal_command", "runtime_activity"];
export declare const CHAT_MESSAGE_INTERNAL_SOURCES: readonly ["runtime_status", "provider_chrome", "control"];
export type ChatMessageVisibility = typeof CHAT_MESSAGE_VISIBILITIES[number] | (string & {});
export type ChatMessageTranscriptVisibility = typeof CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES[number] | (string & {});
export type ChatMessageAudience = typeof CHAT_MESSAGE_AUDIENCES[number] | (string & {});
export type ChatMessageSource = typeof CHAT_MESSAGE_SOURCES[number] | (string & {});
export type ChatMessageTranscriptSurface = 'chat' | 'activity' | 'internal';
export interface ChatMessageVisibilityClassification {
    surface: ChatMessageTranscriptSurface;
    isUserFacing: boolean;
    isActivityFacing: boolean;
    isInternal: boolean;
    explicitUserFacing: boolean;
    explicitHidden: boolean;
    role: string;
    kind: ChatMessageKind;
    visibility: string;
    transcriptVisibility: string;
    audience: string;
    source: string;
}
export declare function isBuiltinChatMessageKind(kind: unknown): kind is BuiltinChatMessageKind;
export declare function normalizeChatMessageKind(kind: unknown, role: unknown): ChatMessageKind;
export declare function resolveChatMessageKind<T extends ChatMessage>(message: T): ChatMessageKind;
export declare function buildChatMessage<T extends Omit<ChatMessage, 'kind'> & {
    kind?: ChatMessageKind;
}>(message: T): T & {
    kind: ChatMessageKind;
};
export declare function buildSystemChatMessage<T extends Omit<ChatMessage, 'role' | 'kind'> & {
    role?: 'system';
    kind?: ChatMessageKind;
}>(message: T): (T & {
    role: 'system';
    kind: ChatMessageKind;
});
export declare function buildRuntimeSystemChatMessage<T extends Omit<ChatMessage, 'role' | 'kind' | 'senderName'> & {
    role?: 'system';
    kind?: ChatMessageKind;
    senderName?: string;
}>(message: T): (T & {
    role: 'system';
    kind: ChatMessageKind;
    senderName: string;
});
export declare function buildAssistantChatMessage<T extends Omit<ChatMessage, 'role' | 'kind'> & {
    role?: 'assistant';
    kind?: ChatMessageKind;
}>(message: T): (T & {
    role: 'assistant';
    kind: ChatMessageKind;
});
export declare function buildThoughtChatMessage<T extends Omit<ChatMessage, 'role' | 'kind'> & {
    role?: 'assistant';
    kind?: ChatMessageKind;
}>(message: T): (T & {
    role: 'assistant';
    kind: ChatMessageKind;
});
export declare function buildToolChatMessage<T extends Omit<ChatMessage, 'role' | 'kind'> & {
    role?: 'assistant';
    kind?: ChatMessageKind;
}>(message: T): (T & {
    role: 'assistant';
    kind: ChatMessageKind;
});
export declare function buildTerminalChatMessage<T extends Omit<ChatMessage, 'role' | 'kind'> & {
    role?: 'assistant';
    kind?: ChatMessageKind;
}>(message: T): (T & {
    role: 'assistant';
    kind: ChatMessageKind;
});
export declare function buildUserChatMessage<T extends Omit<ChatMessage, 'role' | 'kind'> & {
    role?: 'user';
    kind?: ChatMessageKind;
}>(message: T): (T & {
    role: 'user';
    kind: ChatMessageKind;
});
export declare function normalizeChatMessage<T extends ChatMessage>(message: T): T;
export declare function normalizeChatMessages<T extends ChatMessage>(messages: T[] | null | undefined): T[];
/**
 * Shared transcript visibility protocol for all ADHDev provider chat messages.
 *
 * Producers can stamp visibility/audience/source/userFacing/internal/debug either
 * at the top level or under `meta`. Consumers should use this classifier instead
 * of matching command text, icons, provider names, or terminal UI fragments.
 */
export declare function classifyChatMessageVisibility(message: ChatMessage | null | undefined): ChatMessageVisibilityClassification;
export declare function isUserFacingChatMessage(message: ChatMessage | null | undefined): boolean;
export declare function isActivityChatMessage(message: ChatMessage | null | undefined): boolean;
export declare function isInternalChatMessage(message: ChatMessage | null | undefined): boolean;
export declare function filterUserFacingChatMessages<T extends ChatMessage>(messages: T[] | null | undefined): T[];
export declare function filterActivityChatMessages<T extends ChatMessage>(messages: T[] | null | undefined): T[];
export declare function filterInternalChatMessages<T extends ChatMessage>(messages: T[] | null | undefined): T[];
export declare function filterChatMessagesByVisibility<T extends ChatMessage>(messages: T[] | null | undefined, surface: ChatMessageTranscriptSurface): T[];
