/** * Session-picker, tree/fork navigation, and model-selector flows extracted from * interactive-mode. * * Each entry opens a selector overlay (via `host.showSelector`) or renders a * session-info block, driving `AgentSession`/`AgentSessionRuntime` navigation and * the fork/resume/clone/goal-continuation paths. The interdependent selector * flows share one narrow `SessionFlowHost` seam; the three prototype-tested leaf * commands (`handleCloneCommand`, `handleGoalContinueCommand`, * `handleSessionCommand`) take their own minimal host shapes so their behaviour * tests keep exercising them through interactive-mode's thin wrappers unchanged. */ import type { SessionManager } from "@caupulican/pi-agent-core/node"; import type { Api, Model } from "@caupulican/pi-ai"; import type { EditorComponent } from "@caupulican/pi-tui"; import { type Component, type Container, Loader, type TUI } from "@caupulican/pi-tui"; import type { AgentSession, GoalContinuationLoopOptions, GoalContinuationLoopResult } from "../../core/agent-session.ts"; import type { AgentSessionRuntime } from "../../core/agent-session-runtime.ts"; import type { ExtensionCommandContext } from "../../core/extensions/index.ts"; import { type GoalStateRevision } from "../../core/goals/goal-lifecycle.ts"; import { type GoalState } from "../../core/goals/goal-state.ts"; import type { KeybindingsManager } from "../../core/keybindings.ts"; import { MissingSessionCwdError } from "../../core/session-cwd.ts"; import type { SettingsManager } from "../../core/settings-manager.ts"; import { type TaskStepsState } from "../../core/tasks/task-state.ts"; import type { CustomEditor } from "./components/custom-editor.ts"; import type { FooterComponent } from "./components/footer.ts"; import type { ExtensionUiHost } from "./extension-ui-host.ts"; /** Shared seam for the interdependent selector/navigation flows. */ export interface SessionFlowHost { readonly session: AgentSession; readonly sessionManager: SessionManager; readonly settingsManager: SettingsManager; readonly runtimeHost: AgentSessionRuntime; readonly ui: TUI; readonly chatContainer: Container; readonly statusContainer: Container; readonly editor: EditorComponent; readonly defaultEditor: CustomEditor; readonly footer: FooterComponent; readonly extensionUiHost: ExtensionUiHost; readonly keybindings: KeybindingsManager; loadingAnimation: Loader | undefined; showSelector(create: (done: () => void) => { component: Component; focus: Component; }): void; showStatus(message: string): void; showError(message: string): void; refreshAutonomyFooterStatus(): void; renderCurrentSessionState(): void; renderInitialMessages(options?: { forceHistoryLoad?: boolean; }): Promise; flushCompactionQueue(options?: { willRetry?: boolean; }): Promise; handleFatalRuntimeError(prefix: string, error: unknown): Promise; promptForMissingSessionCwd(error: MissingSessionCwdError): Promise; updateEditorBorderColor(): void; updateAvailableProviderCount(): Promise; maybeWarnAboutAnthropicSubscriptionAuth(model?: Model): Promise; checkDaxnutsEasterEgg(model: { provider: string; id: string; }): void; getModelCandidates(): Promise[]>; shutdown(options?: { fromSignal?: boolean; }): Promise; } export declare function showModelSelector(host: SessionFlowHost, initialSearchInput?: string): Promise; export declare function showModelsSelector(host: SessionFlowHost): Promise; export declare function showUserMessageSelector(host: SessionFlowHost, newSessionName?: string): void; export declare function showTreeSelector(host: SessionFlowHost, initialSelectedId?: string): void; export declare function showTrustSelector(host: SessionFlowHost): void; export declare function showSessionSelector(host: SessionFlowHost): void; export declare function handleResumeSession(host: SessionFlowHost, sessionPath: string, options?: Parameters[1]): Promise<{ cancelled: boolean; }>; export declare function handleModelCommand(host: SessionFlowHost, searchTerm?: string): Promise; export declare function findExactModelMatch(host: SessionFlowHost, searchTerm: string): Promise | undefined>; export interface CloneCommandHost { readonly sessionManager: { getLeafId: () => string | null; }; readonly runtimeHost: { fork: (entryId: string, options?: { position?: "before" | "at"; }) => Promise<{ cancelled: boolean; }>; }; renderCurrentSessionState(): void; readonly editor: { setText: (text: string) => void; }; readonly session: { setSessionName: (name: string) => void; }; showStatus(message: string): void; showError(message: string): void; readonly ui: { requestRender: () => void; }; } export declare function handleCloneCommand(host: CloneCommandHost, newSessionName?: string): Promise; export type ParsedGoalContinueCommand = { ok: true; maxTurns: number; maxStallTurns: number; maxWallClockMinutes: number; } | { ok: false; error: string; }; export interface GoalResumeHost { readonly session: { getGoalStateSnapshot: () => GoalState | undefined; saveGoalStateSnapshot: (state: GoalState, expected?: GoalStateRevision) => string; clearGoalStateSnapshot?: (state: GoalState, now: string) => string; restoreGoalRuntimeAfterResume: () => void; }; refreshAutonomyFooterStatus(): void; } export interface GoalCommandHost extends GoalResumeHost { readonly session: GoalResumeHost["session"] & { continueGoalLoop: (options: GoalContinuationLoopOptions) => Promise; getGoalRuntimeSnapshot: (settings: { maxStallTurns: number; }) => ReturnType; }; promptForGoalEdit?(currentObjective: string): Promise; getMaxStallTurns?(): number; showStatus(message: string): void; showError(message: string): void; } export type GoalResumeResult = { ok: true; resumed: true; state: GoalState; } | { ok: false; error: string; }; /** Canonical persisted transition used by both `/goal resume` and session `/resume`. */ export declare function resumeCurrentGoal(host: GoalResumeHost, now?: string): GoalResumeResult; export declare function handleGoalCommand(host: GoalCommandHost, text: string): Promise; export interface TaskCommandHost { readonly session: { getTaskStepsStateSnapshot: () => TaskStepsState | undefined; saveTaskStepsStateSnapshot: (state: TaskStepsState) => string; }; showStatus(message: string): void; showError(message: string): void; } export declare function handleTaskCommand(host: TaskCommandHost, text: string): void; export interface GoalContinueCommandHost { readonly session: { continueGoalLoop: (options: GoalContinuationLoopOptions) => Promise; }; parseGoalContinueCommand(text: string): ParsedGoalContinueCommand; showStatus(message: string): void; showError(message: string): void; refreshAutonomyFooterStatus(): void; } export declare function handleGoalContinueCommand(host: GoalContinueCommandHost, text: string): Promise; export interface SessionInfoCommandHost { readonly session: { getSessionStats: () => ReturnType; getCostSummary: () => ReturnType; getModelRouterStatus: (formatLabel: (label: string) => string) => string; }; readonly sessionManager: { getSessionName: () => string | undefined; }; readonly chatContainer: Container; readonly ui: { requestRender: () => void; }; } export declare function handleSessionCommand(host: SessionInfoCommandHost): void; //# sourceMappingURL=session-flow-commands.d.ts.map