import type { Component, Focusable } from "@earendil-works/pi-tui"; import type { AgentSessionEvent, CompactionReason } from "../../../core/agent-session.js"; import type { SessionStore } from "../../../core/storage/session/types.js"; import type { AgentSnapshotMessage, ChatSessionHostEntry, ChatSessionHostOpts, ChatSessionSubmitMode } from "./chat-session-host-types.ts"; import type { ChatTranscriptEntryLike } from "./chat-transcript.js"; export type { ChatSessionHostBashRequest, ChatSessionHostCommands, ChatSessionHostEntry, ChatSessionHostOpts, ChatSessionHostStyle, ChatSessionSubmitMode, } from "./chat-session-host-types.ts"; export declare class ChatSessionHost implements Component, Focusable { focused: boolean; private readonly state; private taskStore?; private readonly taskRowsInChat; private unsubscribeTasks?; private taskSession?; private unsubscribeTaskBinding?; private taskInspector?; private historyHydrated; constructor(opts: ChatSessionHostOpts); openTasks(id?: string): boolean; get hasTaskInspector(): boolean; get taskInspectorFullscreen(): boolean; closeTasks(): void; handleTaskInput(data: string): boolean; appendMessages(messages: readonly AgentSnapshotMessage[]): void; /** * Adopt the assistant message a live session is part-way through streaming. * * A host mounted mid-turn missed the `message_start` and every delta that * came before it, and delta-only updates never restate them, so the session's * in-flight message is the only place that text still exists. Ignored once * this host is already following a stream of its own. */ hydrateStreamingAssistantMessage(message: AgentSnapshotMessage | undefined): void; loadSession(store: SessionStore, sessionId: string | undefined): Promise; appendExtraEntry(entry: TExtraEntry): void; entries(): readonly ChatSessionHostEntry[]; /** Tasks outlive tools and turns; only host/session binding grants this read projection. */ refreshTaskStore(): void; applyAgentEvent(event: AgentSessionEvent): boolean; /** * Restore the factual compaction indicator on a host mounted after the * `compaction_start` it never saw. The label resolves through the same * mapping the live event path uses, so the two cannot drift. * * Branch summaries deliberately do not paint here: their label belongs to * a retry lifecycle this re-attached host is not inside, and no event exists * to clear it after the summary finishes. An absent paintable reason is a * no-op unless this host is actively showing a compaction label, so unrelated * workflow delivery busy state is preserved. */ hydrateCompactionStatus(reason: CompactionReason | undefined): void; render(width: number): string[]; invalidate(): void; renderBody(width: number, budget: number): string[]; /** * Rows the body occupies at `width`, whether or not they are on screen. * * Pair with `renderBodyRows` to read the whole transcript, not only the * window the reader is parked on. Both measure the component stack the last * `renderBody` installed, so call them after at least one body render. */ bodyRowCount(width: number): number; /** Body rows `startRow` (inclusive) to `endRow` (exclusive), unscrolled. */ renderBodyRows(width: number, startRow: number, endRow: number): string[]; /** * Render a live assistant entry whole, or only its tail (the default). * * The tail window keeps a fast-streaming turn cheap for a reader following * the bottom of the body; it also drops everything above the last 240 lines * from what `bodyRowCount` and `renderBodyRows` report. Returns whether the * setting changed, so the caller can invalidate the rows that were rendered * under the old rule. */ setStreamingTailWindowEnabled(enabled: boolean): boolean; renderPendingMessages(width: number): string[]; renderWorkingStatus(width: number): string[]; renderUsage(width: number): string[]; renderEditor(width: number): string[]; renderTaskFooter(width: number): string[]; renderFooter(width: number): string[]; handleScrollInput(data: string): boolean; handleInput(data: string): boolean; interrupt(options?: { restoreQueuedMessages?: boolean; }): Promise; submit(mode?: ChatSessionSubmitMode, submittedText?: string): Promise; isStreaming(): boolean; isBashRunning(): boolean; isEditingBashCommand(): boolean; isCompacting(): boolean; hasInputText(): boolean; hasAnimationTick(): boolean; bodyScrollFromBottom(): number; bodyMaxScroll(): number; inputText(): string; setInputText(text: string): void; statusText(): string; showWarning(message: string): void; scrollToBottom(): void; /** * Park the body with absolute row `row` at the top of its window, clamped * to the last rendered layout. Used to reveal a search match the reader * cannot currently see. */ scrollBodyTo(row: number): void; syncAnimationTick(): void; clearBusyForTerminalWorkflowStage(): void; /** * Start Working for an accepted prompt delivered outside this host — a * workflow definition auto-sending to its own retained stage. Returns the * lifecycle token to hand back to `settleExternalPromptLifecycle`. */ beginExternalPromptLifecycle(): number | undefined; /** * Reopen Working for a delivery still active after a temporary overlay — a * pre-turn compaction — cleared it. Preserves factual status text. */ reassertExternalPromptLifecycle(): number | undefined; /** Settle a lifecycle from `beginExternalPromptLifecycle`. Stale tokens no-op. */ settleExternalPromptLifecycle(generation: number | undefined): void; dispose(): void; restoreQueuedMessagesToEditor(): boolean; private editorCallbacks; } //# sourceMappingURL=chat-session-host.d.ts.map