import type { Message, Provider, ThinkingLevel } from "@kenkaiiii/gg-ai"; import type { AgentTool } from "@kenkaiiii/gg-agent"; import type { ProcessManager } from "../core/process-manager.js"; import type { SubAgentManager } from "../core/subagent-manager.js"; import type { MCPClientManager } from "../core/mcp/index.js"; import type { AuthStorage } from "../core/auth-storage.js"; import type { Skill } from "../core/skills.js"; import type { CheckpointStore } from "../core/checkpoint-store.js"; import type { LspManager } from "../core/lsp/manager.js"; import type { ReviewCoverageTracker } from "../core/ideal-review.js"; import type { TurnMetricPayload } from "../core/session-manager.js"; import { type CompletedItem, type DoneStatus } from "./App.js"; import type { PlanStep } from "../utils/plan-steps.js"; import { type ThemeName } from "./theme/theme.js"; export interface RenderAppConfig { provider: Provider; model: string; tools: AgentTool[]; webSearch?: boolean; messages: Message[]; maxTokens: number; thinking?: ThinkingLevel; apiKey?: string; baseUrl?: string; accountId?: string; projectId?: string; cwd: string; version: string; theme?: "auto" | ThemeName; showTokenUsage?: boolean; idealReviewEnabled?: boolean; onSlashCommand?: (input: string) => Promise; loggedInProviders?: Provider[]; credentialsByProvider?: Record; initialHistory?: CompletedItem[]; initialTurnMetrics?: TurnMetricPayload[]; sessionsDir?: string; sessionPath?: string; sessionId?: string; processManager?: ProcessManager; subAgentManager?: SubAgentManager; lspManager?: LspManager; reviewCoverageTracker?: ReviewCoverageTracker; settingsFile?: string; mcpManager?: MCPClientManager; authStorage?: AuthStorage; planModeRef?: { current: boolean; }; skills?: Skill[]; checkpointStore?: CheckpointStore; rebuildReadTool?: (model: string) => AgentTool; connectInitialMcpTools?: () => Promise; onRuntimeStateChange?: (updates: Partial) => void; planCallbacks?: { onEnterPlan?: (reason?: string) => void | Promise; onExitPlan?: (planPath: string) => Promise; }; } /** * Runtime UI choices that survive every unmount/remount (including `/clear`). * Lives in `renderApp`'s closure so the user's model/provider/thinking * picks aren't lost when an overlay close, plan accept, etc. tears down * the React tree. */ export interface RuntimeState { model: string; provider: Provider; thinking?: ThinkingLevel; } /** * Session state that needs to survive unmount/remount for paths that * KEEP the conversation (overlay close, plan reject) — and which we * deliberately wipe for paths that start a fresh session (`/clear`, * plan accept). * * App.tsx mirrors its in-React state into this object via useEffects, * so when `resetUI` rebuilds the Ink instance, the new App can re-seed * from the latest snapshot. This is the price of using unmount/remount * as our reset mechanism (the only thing that actually escapes Ink's * cumulative live-area drift). */ type OverlayKind = "model" | "skills" | "plan" | "theme" | null; export interface SessionStore { messages: Message[]; history: CompletedItem[]; turnMetrics?: TurnMetricPayload[]; /** Live, not-yet-flushed rows that must survive overlay/resize remounts. */ liveItems?: CompletedItem[]; /** Transient completion footer (e.g. "✻ Mulled it over for 3s") that is still visible. */ doneStatus?: DoneStatus | null; approvedPlanPath?: string; planSteps: PlanStep[]; sessionPath?: string; sessionId?: string; /** Which overlay (Skills, Plan, Theme, Model) is open. */ overlay?: OverlayKind; /** Plan overlay auto-expand-newest flag (only meaningful when overlay==='plan'). */ planAutoExpand?: boolean; /** * Action to run on the next mount (consumed once). Used by paths that * remount AND immediately drive the agent — plan accept / reject, * etc. The new App reads this on mount, fires the agent, * and clears the field. */ pendingAction?: { prompt: string; infoText?: string; /** Structured event for the post-resetUI banner — renders as a styled * plan_event item instead of the bland info row. */ planEvent?: { event: "approved" | "rejected" | "dismissed"; detail?: string; }; }; /** * True while the agent loop is running. Mirrored by App.tsx so renderApp's * resize handler can skip the unmount/remount that would abort the agent * (useAgentLoop's unmount cleanup calls abortRef.abort()). */ isAgentRunning?: boolean; /** * Set whenever a path that would normally `resetUI()` had to fall back to * an in-place update because the agent was running (resize, overlay open/ * close). Consumed by App.tsx when the agent goes idle: a deferred * resetUI() runs to clean up any log-update drift that accumulated during * the run. The setTimeout delay lets onDone's two-phase flush commit to * sessionStore.history before the unmount, so the chat isn't lost. */ pendingResetUI?: boolean; /** Plan mode display/restriction state. */ planMode?: boolean; /** Whether pre-final ideal review is enabled for this UI session. */ idealReviewEnabled?: boolean; } export interface ResetUIOptions { /** Replace messages entirely (e.g. fresh system prompt for `/clear` or plan accept). */ messages?: Message[]; /** Wipe history, plan steps, session metadata. Applied BEFORE other fields. */ wipeSession?: boolean; /** Replace history outright (applied AFTER wipeSession). */ history?: CompletedItem[]; /** Set the approved plan path on the new mount. */ approvedPlanPath?: string; /** Set plan steps (e.g. parsed from the freshly approved plan). */ planSteps?: PlanStep[]; /** Override session path (e.g. plan accept creates a new session file). */ sessionPath?: string; /** Clear malformed live frames after terminal resize and redraw durable history. */ resizeRedraw?: boolean; /** Action to fire on the new mount (info banner + agent prompt). */ pendingAction?: { prompt: string; infoText?: string; /** Structured event for the post-resetUI banner — renders as a styled * plan_event item instead of the bland info row. */ planEvent?: { event: "approved" | "rejected" | "dismissed"; detail?: string; }; }; } /** * Fullscreen alternate-screen viewport mode. Default OFF: native terminal * scrollback is the default (smooth, GPU-accelerated, real mouse-wheel scroll). * Set `GG_FULLSCREEN=1` to opt into the alternate-screen in-Ink viewport * (pinned footer, but no native scrollback). Non-TTY / CI / print modes never * use it. */ export declare function isFullscreenViewportEnabled(): boolean; export declare function getResetClearMode(options: Pick | undefined): "screen" | "viewport"; export declare function renderApp(config: RenderAppConfig): Promise; export {}; //# sourceMappingURL=render.d.ts.map