import type { AgentMessage } from "@gajae-code/agent-core"; import type { CompactionOutcome } from "@gajae-code/agent-core/compaction"; import type { AssistantMessage, ImageContent, Message, UsageReport } from "@gajae-code/ai/core"; import type { Component, Container, EditorTheme, Loader, SlashCommand, Spacer, Text, TUI } from "@gajae-code/tui"; import type { KeybindingsManager } from "../config/keybindings"; import type { Settings } from "../config/settings"; import type { ExtensionUIContext, ExtensionUIDialogOptions, ExtensionWidgetContent, ExtensionWidgetOptions } from "../extensibility/extensions"; import type { CompactOptions } from "../extensibility/extensions/types"; import type { Skill } from "../extensibility/skills"; import type { MCPManager } from "../runtime-mcp"; import type { NotificationSessionReconcileResult, NotificationSessionStatus } from "../sdk/bus/session-control"; import type { AgentSession, AgentSessionEvent } from "../session/agent-session"; import type { HistoryStorage } from "../session/history-storage"; import type { SessionContext, SessionManager } from "../session/session-manager"; import type { CredentialAutoImportOptions } from "../setup/credential-auto-import"; import type { LspStartupServerInfo } from "../tools"; import type { AssistantMessageComponent } from "./components/assistant-message"; import type { BashExecutionComponent } from "./components/bash-execution"; import type { CommandPaletteAction } from "./components/command-palette"; import type { CustomEditor } from "./components/custom-editor"; import type { EvalExecutionComponent } from "./components/eval-execution"; import type { PetMode } from "./components/gajae-pet-widget"; import type { HookEditorComponent } from "./components/hook-editor"; import type { HookInputComponent } from "./components/hook-input"; import type { HookSelectorComponent } from "./components/hook-selector"; import type { ToolExecutionHandle } from "./components/tool-execution"; import type { StatusLineComponent } from "./components/tool-status-header"; import type { IrcObservationLedger } from "./irc-observation-ledger"; import type { OAuthManualInputManager } from "./oauth-manual-input"; import type { PromptSuggestionController } from "./prompt-suggestion-controller"; import type { Theme } from "./theme/theme"; import type { ParsedIrcMessage } from "./utils/irc-message"; export type TranscriptRebuildPolicy = "replace-identity" | "reconcile-same-transcript"; export type CompactionQueuedMessage = { text: string; mode: "steer" | "followUp"; followUpQueuePolicy?: "sequential"; }; export type SubmittedUserInput = { text: string; images?: ImageContent[]; customType?: string; display?: boolean; cancelled: boolean; started: boolean; }; export type ComposerSubmissionOptions = Readonly<{ ownsComposer: boolean; editor: CustomEditor; }>; export declare function canApplyComposerSubmission(options: ComposerSubmissionOptions | undefined, editor: CustomEditor): boolean; type PartialActivityStatusContainer = Partial>; export type ActivityIndicatorStopOptions = Readonly<{ restoreBackground?: boolean; /** The terminal event is authoritative even if the session's streaming flag has not settled yet. */ foregroundSettled?: boolean; }>; export declare function stopInteractiveActivityIndicator(ctx: { loadingAnimation?: Loader; statusContainer?: PartialActivityStatusContainer; stopLoadingAnimation?: (options?: ActivityIndicatorStopOptions) => void; }, options?: ActivityIndicatorStopOptions): void; export declare function clearInteractiveActivityLoaders(ctx: Pick): void; export declare function suspendInteractiveActivityIndicator(ctx: { loadingAnimation?: Loader; statusContainer?: PartialActivityStatusContainer; stopLoadingAnimation?: (options?: ActivityIndicatorStopOptions) => void; syncActivityIndicator?: () => void; suspendActivityIndicator?: () => () => void; }): () => void; export declare function syncInteractiveActivityIndicator(ctx: { syncActivityIndicator?: () => void; }): void; export type TodoStatus = "pending" | "in_progress" | "completed" | "abandoned"; export type TodoItem = { content: string; status: TodoStatus; details?: string; notes?: string[]; }; export type TodoPhase = { name: string; tasks: TodoItem[]; }; export type IrcArrivalSnapshot = Readonly<{ panelVisible: boolean; /** User-requested open state; may be true while the panel yields at narrow widths. */ panelRequestedVisible: boolean; sidebarAvailable: boolean; resolvedToggleKey: string | null; }>; export interface InteractiveModeContext { ui: TUI; chatContainer: Container; pendingMessagesContainer: Container; statusContainer: Container; todoContainer: Container; btwContainer: Container; editor: CustomEditor; editorContainer: Container; hookWidgetContainerAbove: Container; hookWidgetContainerBelow: Container; statusLine: StatusLineComponent; session: AgentSession; sessionManager: SessionManager; settings: Settings; keybindings: KeybindingsManager; agent: AgentSession["agent"]; historyStorage?: HistoryStorage; mcpManager?: MCPManager; lspServers?: LspStartupServerInfo[]; /** Shared controller query; absent in ACP/lightweight test contexts. */ getCurrentSessionNotificationStatus?(): NotificationSessionStatus | undefined; /** Toggle only the current session; absent in ACP/lightweight test contexts. */ setCurrentSessionNotificationsEnabled?(enabled: boolean): Promise; readonly ircLedger: IrcObservationLedger; isInitialized: boolean; isBackgrounded: boolean; isBashMode: boolean; isBashNoContext: boolean; toolOutputExpanded: boolean; todoExpanded: boolean; hideThinkingBlock: boolean; pendingImages: ImageContent[]; compactionQueuedMessages: CompactionQueuedMessage[]; pendingTools: Map; pendingBashComponents: BashExecutionComponent[]; bashComponent: BashExecutionComponent | undefined; pendingPythonComponents: EvalExecutionComponent[]; pythonComponent: EvalExecutionComponent | undefined; isPythonMode: boolean; streamingComponent: AssistantMessageComponent | undefined; streamingMessage: AssistantMessage | undefined; loadingAnimation: Loader | undefined; autoCompactionLoader: Loader | undefined; retryLoader: Loader | undefined; autoCompactionEscapeHandler?: () => void; retryEscapeHandler?: () => void; retryEscapePrimed: boolean; retryCountdownTimer?: NodeJS.Timeout; unsubscribe?: () => void; onInputCallback?: (input: SubmittedUserInput) => void; optimisticUserMessageSignature: string | undefined; locallySubmittedUserSignatures: Set; optimisticInjectedSignatures: Map; lastSigintTime: number; lastEscapeTime: number; lastComposerClearEscapeTime: number; shutdownRequested: boolean; hookSelector: HookSelectorComponent | undefined; hookInput: HookInputComponent | undefined; hookEditor: HookEditorComponent | undefined; lastStatusSpacer: Spacer | undefined; lastStatusText: Text | undefined; fileSlashCommands: Set; skillCommands: Map; oauthManualInput: OAuthManualInputManager; todoPhases: TodoPhase[]; /** Ghost-text next-prompt prediction; absent in ACP/lightweight test contexts. */ promptSuggestion?: PromptSuggestionController; init(): Promise; shutdown(): Promise; checkShutdownRequested(): Promise; isStopped?(): boolean; onStop(callback: () => void): () => void; setToolUIContext(uiContext: ExtensionUIContext, hasUI: boolean): void; initializeHookRunner(uiContext: ExtensionUIContext, hasUI: boolean): void; createBackgroundUiContext(): ExtensionUIContext; setEditorComponent(factory: ((tui: TUI, theme: EditorTheme, keybindings: KeybindingsManager) => CustomEditor) | undefined): void; handleBackgroundEvent(event: AgentSessionEvent): Promise; showStatus(message: string, options?: { dim?: boolean; }): void; showError(message: string): void; showWarning(message: string): void; notifyConfigChanged?: () => Promise | void; showNewVersionNotification(newVersion: string): void; clearEditor(): void; updatePendingMessagesDisplay(): void; queueCompactionMessage(text: string, mode: "steer" | "followUp", options?: ComposerSubmissionOptions): void; flushCompactionQueue(options?: { willRetry?: boolean; }): Promise; flushPendingBashComponents(): void; setWorkingMessage(message?: string): void; applyPendingWorkingMessage(): void; ensureLoadingAnimation(): void; syncActivityIndicator(): void; suspendActivityIndicator(): () => void; stopLoadingAnimation(options?: ActivityIndicatorStopOptions): void; /** * Commit a pet mode through the shared result-returning policy: capability * is rechecked immediately before mutation and the preference persists only * on acceptance. Returns whether the commit was accepted. */ setPetMode(mode: PetMode): boolean; /** Live-preview a pet skin during a selector without persisting. */ previewPetMode(mode: PetMode): void; /** * Commit a settings-overlay pet change without re-mounting the composer. * Same shared commit policy and result semantics as `setPetMode`. */ commitPetPreviewMode(mode: PetMode): boolean; /** Re-mount the composer (pet-aware) after an overlay/selector closes. */ restoreComposer(): void; startPendingSubmission(input: { text: string; images?: ImageContent[]; customType?: string; display?: boolean; }, options?: ComposerSubmissionOptions): SubmittedUserInput; cancelPendingSubmission(): boolean; /** * True while a submission is pending: not yet started, or started but still * awaiting prompt delivery (`session.prompt()` has not flipped streaming yet). * Interrupt handling uses this to keep a started-preflight submission * cancellable instead of misclassifying its loader as stale (#4741). */ hasPendingSubmission(): boolean; markPendingSubmissionStarted(input: SubmittedUserInput): boolean; finishPendingSubmission(input: SubmittedUserInput): void; /** * Marks a locally-initiated user submission so the eventual `message_start` * event for that user message does not clobber the editor draft (see #783). * Returns a dispose function that removes the signature; call it on * delivery failure so a retry can be re-marked cleanly. */ recordLocalSubmission(text: string, imageCount?: number): () => void; /** * Wraps `fn` in a `recordLocalSubmission` marker that is automatically * removed if `fn` rejects. Use this for the common case where a thrown * delivery error should leave the signature set untouched. */ withLocalSubmission(text: string, fn: () => Promise, options?: { imageCount?: number; }): Promise; isKnownSlashCommand(text: string): boolean; addMessageToChat(message: AgentMessage, options?: { populateHistory?: boolean; }): Component[]; addLiveIrcObservationToChat(message: ParsedIrcMessage, arrival: IrcArrivalSnapshot): Component[]; removeRenderedIrcInlineComponents(observationId: string): readonly Component[] | undefined; resetRenderedIrcInlineComponents(): readonly (readonly Component[])[]; renderSessionContext(sessionContext: SessionContext, options?: { updateFooter?: boolean; populateHistory?: boolean; }): void; rebuildInitialMessages(policy: TranscriptRebuildPolicy, prebuiltContext?: SessionContext, options?: { preserveExistingChat?: boolean; }): void; getUserMessageText(message: Message): string; getAssistantViewportAnchorId?(message: AssistantMessage): string; findLastAssistantMessage(): AssistantMessage | undefined; extractAssistantText(message: AssistantMessage): string; /** Records one semantic visible-transcript mutation for the sticky viewport. */ recordVisibleTranscriptMutation?(): void; updateEditorTopBorder(): void; updateEditorBorderColor(): void; rebuildChatFromMessages(policy: TranscriptRebuildPolicy): void; updateEditorChrome(): void; setTodos(todos: TodoItem[] | TodoPhase[]): void; reloadTodos(): Promise; toggleTodoExpansion(): void; toggleIrcSidebar(): void; captureIrcArrivalSnapshot(): IrcArrivalSnapshot; applyIrcSidebarAvailability(enabled: boolean): void; resetIrcSidebarSession(): void; handleExportCommand(text: string): Promise; handleShareCommand(): Promise; handleCopyCommand(sub?: string): void; handleTodoCommand(args: string): Promise; handleSessionCommand(): Promise; handleJobsCommand(): Promise; handleUsageCommand(reports?: UsageReport[] | null): Promise; handleChangelogCommand(showFull?: boolean): Promise; handleHotkeysCommand(): void; handleHelpCommand(): void; handleToolsCommand(): void; handleContextCommand(): void; handleDumpCommand(): void; handleDebugTranscriptCommand(): Promise; handleClearCommand(): Promise; handleContextClearCommand(): Promise; handleDropCommand(): Promise; handleForkCommand(): Promise; handleBashCommand(command: string, excludeFromContext?: boolean): Promise; handlePythonCommand(code: string, excludeFromContext?: boolean): Promise; handleMCPCommand(text: string): Promise; handleSSHCommand(text: string): Promise; handleCompactCommand(customInstructions?: string): Promise; handleHandoffCommand(customInstructions?: string): Promise; handleContributionPrepCommand(customInstructions?: string): Promise; handleMoveCommand(targetPath: string): Promise; handleRenameCommand(title: string): Promise; handleMemoryCommand(text: string): Promise; handleSTTToggle(): Promise; executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean): Promise; openInBrowser(urlOrPath: string): void; /** Resolved source of truth for slash autocomplete and command palette entries. */ getSlashCommands?(): readonly SlashCommand[]; refreshSlashCommandState(cwd?: string): Promise; ensureHistoryStorage(): Promise; showCommandPalette(commands: SlashCommand[], actions: CommandPaletteAction[], executeSlashCommand: (name: string) => Promise): void; showSettingsSelector(): void; showThemeSelector(): void; showPetSelector(): void; showHistorySearch(): Promise; showExtensionsDashboard(): void; showCustomizationDashboard(): void; showAgentsDashboard(): void; showModelSelector(options?: { temporaryOnly?: boolean; smartRoutingOnly?: boolean; }): void; setAutoroutingEnabled(enabled: boolean): Promise; showEffortSelector(): void; showProviderOnboarding(): void; showFrictionlessOnboarding(): Promise; showPluginSelector(mode?: "install" | "uninstall"): void; showUserMessageSelector(): void; showTreeSelector(): void; showSessionSelector(): void; showSessionsDashboard(): void; handleResumeSession(sessionPath: string): Promise; handleSessionDeleteCommand(): Promise; showOAuthSelector(mode: "login" | "logout", providerId?: string, options?: OAuthSelectorOptions): Promise; showHookConfirm(title: string, message: string): Promise; showDebugSelector(): void; showSessionObserver(): void; showJobsOverlay(): void; showTasksPane(): void; showTranscriptViewer(): void; isTranscriptViewerOpen(): boolean; refreshTranscriptViewer(): void; resetObserverRegistry(): void; handleCtrlC(): void; handleCtrlD(): void; handleCtrlZ(): void; handleDequeue(): void; handleBackgroundCommand(): void; handleImagePaste(): Promise; handleBtwCommand(question: string): Promise; handleBtwFollowUp(question: string): Promise<"accepted" | "busy" | "closed" | "rejected">; hasActiveBtw(): boolean; handleBtwEscape(): boolean; cycleThinkingLevel(): void; cycleRoleModel(options?: { temporary?: boolean; }): Promise; toggleToolOutputExpansion(): void; setToolsExpanded(expanded: boolean): void; toggleThinkingBlockVisibility(): void; openExternalEditor(): void; registerExtensionShortcuts(): void; initHooksAndCustomTools(): Promise; emitCustomToolSessionEvent(reason: "start" | "switch" | "branch" | "tree" | "shutdown", previousSessionFile?: string): Promise; planModeController: Pick; goalModeController: Pick; setHookWidget(key: string, content: ExtensionWidgetContent, options?: ExtensionWidgetOptions): void; setHookStatus(key: string, text: string | undefined): void; showHookSelector(title: string, options: string[], dialogOptions?: ExtensionUIDialogOptions): Promise; hideHookSelector(): void; showHookInput(title: string, placeholder?: string, dialogOptions?: ExtensionUIDialogOptions, inputOptions?: { readonly initialValue?: string; }): Promise; hideHookInput(): void; showHookEditor(title: string, prefill?: string, dialogOptions?: ExtensionUIDialogOptions, editorOptions?: { promptStyle?: boolean; }): Promise; hideHookEditor(): void; showHookNotify(message: string, type?: "info" | "warning" | "error"): void; showHookCustom(factory: (tui: TUI, theme: Theme, keybindings: KeybindingsManager, done: (result: T) => void) => (Component & { dispose?(): void; }) | Promise, options?: { overlay?: boolean; }): Promise; showExtensionError(extensionPath: string, error: string): void; showToolError(toolName: string, error: string): void; } export interface OAuthSelectorOptions { allowExternalCredentialDiscovery?: boolean; trigger?: "bare-login"; externalCredentialDiscover?: CredentialAutoImportOptions["discover"]; /** * Pair by pasting the code the provider displays instead of waiting on the * loopback callback. Set by `/login --manual` for browsers that * cannot reach this machine. */ manualCode?: boolean; } export {};