import type { ClientHistoryMessage } from '../session/client-history.js'; import type { SessionTimelineItem } from '../session/transcript-outline.js'; import type { ExportFormat } from '../session/types.js'; import type { ReviewContext } from '../review/review-git.js'; import type { SessionInfo, TuiEventSource } from './tui-types.js'; /** Options for sending a chat message. */ export interface ChatSendOptions { sessionKey: string; message: string; attachments?: TuiInboundAttachment[]; thinking?: string; } export interface TuiInboundAttachment { id?: string; type: string; mimeType?: string; data?: string; name?: string; size?: number; uri?: string; } /** Event from an agent run or gateway topic. */ export interface TuiEvent { event: string; data: unknown; source?: TuiEventSource; } export interface TuiComposerHistoryItem { id: number; text: string; createdAt: number; } /** Minimal session list item. */ export interface TuiSessionItem { key: string; updatedAt?: number | null; model?: string | null; totalTokens?: number | null; displayName?: string; messageCount?: number; forkedFromSessionKey?: string; cwd?: string; } export interface TuiAgentInfo { id: string; enabled: boolean; displayName?: string; } /** Model choice for the selector overlay. */ export interface TuiModelChoice { id: string; name: string; provider: string; contextWindow?: number; } export interface TuiSessionStats { totalMessages: number; userMessages: number; assistantMessages: number; toolCalls: number; toolResults: number; contextRows: number; tokens: { input: number; output: number; cacheRead: number; cacheWrite: number; total: number; }; } export interface TuiHistoryWindow { messages: HistoryMessage[]; startRowNumber: number; endRowNumber: number; totalRows: number; } export type TuiExportFormat = ExportFormat | 'html'; export interface TuiCompactionResult { compacted: boolean; summary?: string; tokensBefore?: number; tokensAfter?: number; transcriptSummary?: string; } export interface TuiBranchSummary { sourceSessionKey: string; targetSessionKey: string; rowCount: number; entryId?: string; restoredText?: string; } export type TuiShareAudience = 'friend' | 'colleague' | 'public'; export type TuiShareMode = 'auto' | 'force-file' | 'force-site' | 'force-zip'; export interface TuiShareRequest { path: string; audience?: TuiShareAudience; mode?: TuiShareMode; title?: string; description?: string; } export interface TuiShareResult { kind: string; shareUrl: string; title?: string; description?: string; thumbnailUrl?: string; reachability?: string; reachabilityHint?: string | null; expiresAt?: string; maxViews?: number | null; routingReason?: string; routingHint?: string; } export interface TuiStartupResources { context: string[]; skills: string[]; workflows: string[]; connectors: string[]; } export interface TuiChatInputState { sessionKey: string; revision: number; inputs: Array<{ id: string; status: string; }>; } export declare function countPendingChatInputs(inputs: readonly unknown[]): number; export interface TuiWorkspaceFileSearchEntry { name: string; path: string; isDirectory: boolean; } export interface TuiWorkflowRunStartRequest { sessionKey: string; definitionId: string; agentId?: string; goal?: string; input?: unknown; } export interface TuiWorkflowRunStartResult { runId: string; sessionKey: string; definitionId: string; } export interface TuiStartupProjectResult { project: { id: string; name: string; defaultAgentId?: string; workspaceRoot?: string; } | null; created?: boolean; reason?: 'exact' | 'contained' | 'auto_created'; } /** Read-only transcript tree row for current-session navigation/inspection. */ export interface TuiTranscriptTreeEntry { id: string; parentId?: string; depth: number; label: string; role?: string; userLabel?: string; labelTimestamp?: string; turn: number; preview?: string; contentText?: string; toolCallPreview?: string; createdAt?: string; isOnActivePath?: boolean; isCurrentLeaf?: boolean; } /** * Abstraction over the realtime gateway or embedded agent backend. * * Both implementations expose the same surface so the TUI core stays * transport-agnostic. */ export interface TuiBackend { /** Connection metadata (for header display). */ readonly connectionLabel: string; /** Lifecycle callbacks wired by the TUI. */ onEvent?: (evt: TuiEvent) => void; onConnected?: () => void; onDisconnected?: (reason: string) => void; /** Realtime sequence gap. */ onGap?: (info: { expected: number; received: number; }) => void; /** Start the backend connection or embedded agent service. */ start(): void; /** Stop the backend. */ stop(): void; /** Current active chat abort signal, if a run is in progress. */ getActiveSignal?(): AbortSignal | undefined; /** Global composer history, shared across sessions and clients. */ getComposerInputHistory(): Promise; /** Persist one submitted chat input. */ recordComposerInputHistory(text: string): Promise; /** Send a chat message, returns the run id. */ sendChat(opts: ChatSendOptions): Promise<{ runId: string; }>; /** Reattach to a live gateway/webchat run when the original response stream stalled. */ resumeChat?(opts: { sessionKey: string; runId: string; }): Promise<{ ok: boolean; reason?: string; }>; /** Abort an active run. */ abortChat(opts: { sessionKey: string; runId: string; }): Promise<{ ok: boolean; }>; /** Inject steering text into an active run (tool-boundary delivery). */ submitChatInput(opts: { sessionKey: string; message: string; delivery: 'next' | 'steer'; }): Promise<{ ok: boolean; effectiveDelivery?: 'next' | 'steer'; }>; getChatInputState(sessionKey: string): Promise; /** Start a workflow run directly, without routing through the LLM. */ startWorkflowRun?(opts: TuiWorkflowRunStartRequest): Promise; /** Resolve or create the project implied by the TUI launch workspace. */ resolveStartupProject?(opts: { workspacePath: string; sessionKey: string; agentId: string; autoCreate?: boolean; }): Promise; /** Load startup resources shown in `/start` and initial help. */ getStartupResources?(sessionKey: string): Promise; /** Re-evaluate project-scoped resources after a local trust decision changes. */ refreshWorkspaceTrust?(): void | Promise; /** Fuzzy search files in this session's effective workspace. */ searchWorkspaceFiles?(sessionKey: string, query: string, options?: { limit?: number; }): Promise; /** Load git branches/commits/status for the interactive review launcher. */ getReviewContext?(sessionKey: string): Promise; /** Load chat history for a session. */ loadHistory(opts: { sessionKey: string; limit?: number; }): Promise<{ messages: HistoryMessage[]; }>; /** Load a bounded transcript window around a persisted row number. */ loadHistoryWindow?(opts: { sessionKey: string; rowNumber: number; before?: number; after?: number; }): Promise; /** Load current transcript rows as a tree-shaped list. */ loadTranscriptTree(sessionKey: string): Promise; /** Load current transcript rows as timeline items for turn navigation. */ loadTimeline(sessionKey: string): Promise; /** Compute transcript message/token statistics. */ getSessionStats(sessionKey: string): Promise; /** List sessions. */ listSessions(): Promise; /** List agents available for TUI agent switching. */ listAgents(): Promise; /** Persist the default agent for fresh TUI sessions. */ setTuiDefaultAgent?(agentId: string): Promise<{ agentId: string; }>; /** Fetch session info (model, tokens, thinking). */ getSessionInfo(sessionKey: string): Promise; /** List available models. */ listModels(): Promise; /** Refresh dynamic model catalogs after credentials change. */ refreshModels?(): Promise; /** Reset / create new session. */ resetSession(sessionKey: string): Promise; /** Rename session display name. */ renameSession(sessionKey: string, name: string): Promise<{ ok: boolean; }>; /** Delete session and transcript. */ deleteSession(sessionKey: string): Promise<{ ok: boolean; }>; /** Patch session settings (e.g. model). */ patchSession(sessionKey: string, patch: Record): Promise; /** Compact session transcript (returns whether compaction ran). */ compactSession(sessionKey: string, options?: { force?: boolean; instructions?: string; }): Promise; /** Export a session transcript. */ exportSession(sessionKey: string, format: ExportFormat): Promise; /** Import an xopc JSON session export into a new session key. */ importSession(targetSessionKey: string, jsonContent: string): Promise<{ sessionKey: string; rowCount: number; }>; /** Create a share link for a workspace file/folder/site artifact. */ createShare(sessionKey: string, request: TuiShareRequest, options?: { agentId?: string; }): Promise; /** Ask an ephemeral side question using this session as read-only background. */ btwQuery(sessionKey: string, question: string): Promise<{ text: string; error?: string; }>; /** Fork one session transcript into a new session key. */ forkSession(sourceSessionKey: string, targetSessionKey: string): Promise<{ sessionKey: string; rowCount: number; }>; /** Fork one session transcript through a selected transcript-tree entry. */ forkSessionAt(sourceSessionKey: string, targetSessionKey: string, entryId: string): Promise<{ sessionKey: string; rowCount: number; }>; /** Append or clear a label for a transcript entry. */ setTranscriptLabel(sessionKey: string, entryId: string, label: string | undefined): Promise<{ ok: boolean; }>; /** Append extension state for replay by TUI extension sessionManager APIs. */ appendCustomEntry(sessionKey: string, customType: string, data?: unknown): Promise<{ ok: boolean; }>; /** Append a visible extension custom message. */ appendCustomMessage(sessionKey: string, message: { customType: string; content?: string | unknown[]; display?: boolean; details?: unknown; }): Promise<{ ok: boolean; }>; /** Persist a local TUI shell execution for replay and optional LLM context. */ appendBashExecution(sessionKey: string, entry: { command: string; output?: string; exitCode?: number | null; signal?: string | null; excludeFromContext?: boolean; truncated?: boolean; fullOutputPath?: string; }): Promise<{ ok: boolean; }>; } /** A single message in chat history (aligned with `ClientHistoryMessage`). */ export type HistoryMessage = ClientHistoryMessage;