import type { DevToolsSys } from "../types";
import { type Credentials } from "./credentials";
import { TimelineCollector } from "./utils/timeline-collector";
import type { CodegenFeedback, CodeGenToolMap, CodegenTurn, CodegenTurnDone, CustomInstruction, FusionConfig, GenerateCompletionState, GenerateCompletionStep, GenerateUserMessage, SessionMode, UserContext, UserSource, WorkspaceFolder, LoadWholeSessionOptions, LoadWholeSessionResult, LoadHistoryResult, ApplyActionsResult, PrivacyMode, CodeGenPosition, BackupGitRepoResult, SuggestedActionBuildError, PushChangesArgs, CodegenApiResult, CodegenApiTerminal, ConfigureDevOrchestratorOpts, ConfigureDevOrchestratorUpdates, RepoMetrics, FolderWatchEvent, MCPClientStatus, MCPServerConfig, CodegenApiCreateTerminal, SyncChangesFromRemote, SearchFilesOptions, SearchFilesResult, SearchFileTreeOptions, SearchFileTreeResult, HttpServerState, ExplorationMetadataToolInput, CodegenAbortOptions, MessageUpdateOptions, GitRepoContext, SystemReminderObj, GitSnapshot, AutoPushMode, QueueMode, CustomAgentDefinition, AgentModelOverrides, MemorySummary, SendMessageToOrgAgentInput, ReasoningEffort } from "#ai-utils";
import { type ToolResolution } from "./code-tools";
import { type SubAgent } from "./utils/agent-discovery";
import EventEmitter from "node:events";
import { type McpScope } from "./mcp-manage";
import { type RunCommandOptions } from "./utils/git";
import { type DevServerOrchestrator } from "./launch/dev-server-orchestrator";
import type { FusionStatusMonitor } from "./launch/machine-health";
export interface SyncChangesFromBranches {
    canPush: boolean;
    branches: string[];
    uncommittedChanges: "stash" | "commit" | "fail";
    allowUnrelatedHistory: boolean;
    fastForward: "never" | "required" | "auto";
    requestRefresh?: boolean;
    /**
     * When true, compute the remote branch per-repo using #getRemoteBranch(ctx)
     * instead of using the passed branches array. This handles multi-repo
     * scenarios where each repo may have a different feature branch.
     */
    syncRemoteBranch?: boolean;
    /**
     * When true, perform a hard reset to the remote feature/base branch instead
     * of merging. The `branches` array must contain the feature/base branch name.
     */
    resetToBase?: boolean;
    /**
     * Whether to update the internal "last AI commits" baseline after the sync
     * completes. Defaults to `true`. When `false`, `#lastAICommits` is left
     * untouched so `getChangesReport()` keeps diffing from the previous
     * baseline (useful to surface what changed since the reset in a prompt).
     */
    updateLastCommits?: boolean;
}
export interface SessionContext {
    sessionId: string;
    turns: CodegenTurn[];
    customInstructions: CustomInstruction[];
    customAgents: CustomAgentDefinition[];
    userContext: UserContext;
    prettierConfig: Record<string, unknown> | null;
    state: GenerateCompletionState;
    title: string | undefined;
    beforeCommit: GitSnapshot | undefined;
    createdUnixTime: number;
    updatedUnixTime: number;
    canLoadMore: boolean;
    sessionMode: SessionMode;
}
export interface CodeGenSessionOptionsBase {
    sys: DevToolsSys;
    credentials: Credentials;
    position: CodeGenPosition;
    maxTokens?: number;
    queueMode?: QueueMode;
    /**
     * Default {@link SyncChangesFromRemote} policy applied to user messages
     * that arrive without an explicit `syncChanges` field. Typically set when
     * spawning a sub-agent whose definition declares `defaultSyncChanges`
     * (e.g. the setup-project agent uses this to reset to base before each
     * message). `undefined` keeps the historical no-op behavior.
     */
    defaultSyncChanges?: SyncChangesFromRemote;
    privacyMode?: PrivacyMode;
    softContextWindow?: number;
    builtInCustomInstructions?: CustomInstruction[];
    builtInCustomAgents?: SubAgent[];
    builtInMCPServerConfig?: MCPServerConfig;
    autoImportLocalMCPs?: boolean;
    systemPromptOverride?: string | string[];
    fusionConfig?: FusionConfig;
    devServerOrchestrator?: DevServerOrchestrator;
    git?: boolean;
    gitAutoInit?: boolean;
    workingDirectory?: string;
    mcpServers?: boolean;
    enabledTools?: (keyof CodeGenToolMap)[];
    modelOverride?: string;
    agentModelOverrides?: AgentModelOverrides;
    skipFileDiff?: boolean;
    agentType?: string;
    includeMemories?: boolean;
    fusionStatusMonitor?: FusionStatusMonitor;
    asyncSubAgents?: boolean;
    persistSessionLocally?: boolean;
    /** Default reasoning effort level for this session. Sent to the service with each completion request. */
    reasoning?: ReasoningEffort;
    /** Immediate parent session id when this is a sub-agent. */
    parentSessionId?: string;
    /** Root session of the agent tree. Inherited by every descendant; cost rolls up here in one hop. */
    mainSessionId?: string;
}
export interface CodeGenSessionOptionsSession extends CodeGenSessionOptionsBase {
    sessionOrCompletionId?: string;
}
export interface CodeGenSessionOptionsInitialUrl extends CodeGenSessionOptionsBase {
    initialUrl: string;
}
export type CodeGenSessionOptions = CodeGenSessionOptionsSession | CodeGenSessionOptionsInitialUrl;
export type SpawnAgentResult = SpawnAgentResultSuccess | SpawnAgentResultFailed;
export interface SpawnAgentResultSuccess {
    success: boolean;
    response: string;
    metadata: ExplorationMetadataToolInput;
    lastTurn?: CodegenTurn;
    sessionId: string;
}
export interface SpawnAgentResultFailed {
    success: false;
    response: string;
}
export type CodeGenEventEmitter = EventEmitter<{
    step: [GenerateCompletionStep];
    idle: [];
}>;
export declare class CodeGenSession {
    #private;
    /**
     * Returns the primary git working directory path.
     * This is always #gitRepoContexts[0].path for backwards compatibility.
     */
    get primaryGitPath(): string;
    constructor(options: CodeGenSessionOptions);
    get fusionConfig(): FusionConfig | undefined;
    /** Returns the first git-enabled folder for backwards compatibility */
    get gitEnabledFolder(): WorkspaceFolder | undefined;
    /** Returns all git-enabled folders */
    get gitEnabledFolders(): WorkspaceFolder[];
    /** Returns runtime git repo contexts for all enabled repos */
    get gitRepoContexts(): readonly GitRepoContext[];
    get workingDirectory(): string;
    get bashWorkingDirectory(): string;
    getSessionMode(): SessionMode;
    switchSessionMode(newMode: SessionMode): Promise<void>;
    switchModelOverride(model: string | undefined): Promise<void>;
    removeSystemReminder(tag: string): void;
    /**
     * Returns memories whose glob matches the given file path, excluding ones
     * already injected this session. Marks returned memories as reminded.
     */
    getMemoriesForFile(filePath: string): MemorySummary[];
    queueSystemReminder(reminder: SystemReminderObj): {
        operation: string;
    };
    setDefaultAutoPush(autoPush: AutoPushMode | undefined): void;
    setPrivacyMode(privacyMode: PrivacyMode | undefined): Promise<void>;
    /**
     * Snapshot of the current local MCP statuses (CLI-managed servers only).
     * Server-managed MCPs are returned by the codegen pipeline via the
     * `mcp-status` step; the slash command merges both maps client-side.
     */
    getLocalMcpStatus(): Record<string, MCPClientStatus>;
    /**
     * Re-emit the merged MCP status snapshot on demand. Lets a freshly-attached
     * UI (e.g. the dev-server console connecting before any completion has run)
     * pull the current view without firing a noop completion. Server-managed
     * entries are whatever was last seen from the codegen pipeline; local
     * entries are always live.
     */
    refreshMcpStatus(): Record<string, MCPClientStatus>;
    /**
     * Kick off OAuth for a single CLI-managed MCP. Returns immediately; the
     * loopback browser flow completes in the background and emits a
     * `local-mcp-auth-complete` step on success/failure (same path the LLM
     * `__authenticate` synthetic tool uses).
     *
     * For server-managed MCPs (`source === "server"`), tells the caller that
     * v1 only supports re-auth from the Builder.io org settings — wiring up
     * `POST /mcp/oauth/connect` from the CLI is deferred to v2.
     */
    authenticateMcpServer(serverName: string): Promise<{
        started: boolean;
        message?: string;
    }>;
    /**
     * Drop persisted tokens for a CLI-managed remote MCP and surface it as
     * `auth_required` so the UI can prompt for re-authentication. Server-
     * managed MCPs are out of scope in v1 — token storage is in Firestore
     * and requires an authenticated `DELETE /mcp/oauth/credentials` endpoint
     * the service doesn't expose yet.
     */
    clearMcpAuth(serverName: string): Promise<{
        cleared: boolean;
        message?: string;
    }>;
    /**
     * Re-run `connectRemoteMCP` for a single CLI-managed server. Useful after
     * editing `mcp.json`, clearing auth, or recovering from a transient
     * network failure. Server-managed MCPs reconnect fresh on every codegen
     * turn and have no long-lived client to bounce — `/mcp` hides the action
     * for them.
     */
    reconnectMcpServer(serverName: string): Promise<{
        success: boolean;
        toolsAdded: number;
        message?: string;
    }>;
    /**
     * Persist `disabled: true|false` to the right `mcp.json` and refresh the
     * status snapshot. The next manager rebuild reads the flag and either
     * skips the transport or reconnects; for an immediate refresh we also
     * mutate the in-memory client (disable only — re-enabling requires a
     * full reconnect on the next turn so transport state is sound).
     */
    setMcpServerDisabled(serverName: string, disabled: boolean, scope?: McpScope): Promise<{
        disabled: boolean;
        path: string;
        scope: McpScope;
    }>;
    initializeSession(opts?: {
        skipSessionLoading?: boolean;
        signal?: AbortSignal;
    }): Promise<void>;
    loadHistory(): Promise<LoadHistoryResult>;
    loadWholeSession(opts?: LoadWholeSessionOptions): Promise<LoadWholeSessionResult>;
    loadMoreTurns(): Promise<CodegenTurn[]>;
    setCustomInstructions(instructions: CustomInstruction[]): Promise<void>;
    setCustomAgents(agents: SubAgent[]): Promise<void>;
    pushRepoV2(repoInfo: {
        repoFullName: string;
        repoUrl: string;
    }): Promise<CodegenApiResult>;
    /**
     * Ensures git authentication is valid by refreshing git URLs and tokens.
     * This should be called before executing git/gh commands to prevent
     * authentication failures due to expired tokens.
     */
    ensureGitAuth(): Promise<CodegenApiResult>;
    zipFolder(folderName: string): Promise<string>;
    archiveProject(): Promise<string>;
    isIdle(): boolean;
    explainBusy(): {
        isBusy: boolean;
        gitRunning: boolean;
        sessionRunning: boolean;
        pendingPromises: boolean;
        runningSubAgents: boolean;
    };
    needsBackup(): Promise<boolean>;
    uploadBackup(forcedFullBackup?: boolean): Promise<BackupGitRepoResult | {
        success: false;
        error: Error;
    }>;
    getCommitMode(): import("#ai-utils").CommitMode;
    pushChanges(opts: PushChangesArgs): Promise<CodegenApiResult>;
    abortMerge(emitStatus?: boolean): Promise<CodegenApiResult>;
    syncChangesFromRemote(opts?: SyncChangesFromRemote): Promise<CodegenApiResult>;
    /**
     * Get the current commit hash
     */
    getCurrentCommitHash(branchName?: string, repoPath?: string): Promise<string | undefined>;
    getCurrentBranch(repoPath?: string): Promise<string>;
    /**
     * Get the feature branch name
     */
    getFeatureBranch(): string;
    /**
     * Get the AI branch name
     */
    getAiBranch(): string;
    git(args: string[], opts?: string | Partial<RunCommandOptions>): Promise<string>;
    setDebug(debug: boolean): void;
    createTerminal(options?: CodegenApiCreateTerminal): Promise<CodegenApiTerminal>;
    updateTerminal({ terminalId, cols, rows, title }: {
        terminalId: string;
        cols?: number;
        rows?: number;
        title?: string;
    }): boolean;
    writeTerminal({ terminalId, data }: {
        terminalId: string;
        data: string;
    }): boolean;
    signalTerminal({ terminalId, signal }: {
        terminalId: string;
        signal: "SIGINT" | "SIGTERM" | "SIGKILL";
    }): boolean;
    disposeTerminal({ terminalId, emitTerminals }: {
        terminalId: string;
        emitTerminals?: boolean;
    }): boolean;
    restartTerminal({ terminalId }: {
        terminalId: string;
    }): Promise<boolean>;
    subscribeTerminal({ terminalId, onData, onExit }: {
        terminalId: string;
        onData: (chunk: string) => void;
        onExit?: (code?: number) => void;
    }): (() => void) | undefined;
    getAllFiles(options?: {
        getDotFiles?: boolean;
        globbyPattern?: string;
        includePattern?: string;
        gitignore?: boolean;
        deep?: number;
        truncate?: number;
        maxFiles?: number;
        onlyFiles?: boolean;
    }): Promise<string[]>;
    searchFiles(options: SearchFilesOptions): Promise<SearchFilesResult>;
    /**
     * Search for files by their names/paths using Fuse.js fuzzy matching.
     * Matches against the full path (including directory segments), so
     * "components" matches "src/components/Button.tsx" — unlike the old
     * ripgrep glob approach which only matched the filename.
     * Respects access control policies (deny patterns).
     */
    searchFileTree(options: SearchFileTreeOptions): Promise<SearchFileTreeResult>;
    collectRepoMetrics(opts?: {
        rootPath?: string;
        folderName?: string;
    }): Promise<RepoMetrics>;
    getSessionId(): string;
    /** Root session id passed to each spawned sub-agent as their mainSessionId. */
    getMainSessionId(): string;
    updateMetadata(metadata: Record<string, any>): void;
    getMetadata(): Record<string, any>;
    setTimeline(timeline: TimelineCollector): void;
    getTimeline(): TimelineCollector | null;
    getSpaceId(): string | undefined;
    revertToCommitSnapshot(commitSnapshot: GitSnapshot): Promise<void>;
    revertToCommitHash(commitHash: string): Promise<void>;
    resetToCommitSnapshot(commitSnapshot: GitSnapshot, requestRefresh?: boolean): Promise<void>;
    resetToCommitHash(commitHash: string, requestRefresh?: boolean): Promise<void>;
    /**
     * Core function to restore the codebase to a state that matches a predicate.
     * This is the main function that handles both git-based and file-based restoration.
     *
     * @param predicate Function that takes a turn and its index and returns true if we should restore up to that turn
     * @param dryRun If true, only simulate the restoration without making changes
     * @returns Array of file paths that were changed
     */
    restore({ location, predicate, revert, dryRun, forceReplay, debug }: {
        location: "before" | "after";
        predicate: (turn: CodegenTurn, index: number) => boolean;
        dryRun?: boolean;
        revert?: boolean;
        forceReplay?: boolean;
        debug?: string;
    }): Promise<{
        undone: string[] | null;
        message: string;
    }>;
    restoreFromCompletionId({ location, completionId, forceReplay }: {
        location: "before" | "after";
        completionId: string;
        forceReplay?: boolean;
    }): Promise<{
        undone: string[] | null;
        message: string;
    }>;
    restoreBeforeCompletionId(completionId: string): Promise<{
        undone: string[] | null;
        message: string;
    }>;
    /**
     * Undo all changes back to the last user message
     */
    undoLastUserMessage(dryRun?: boolean): Promise<{
        undone: string[] | null;
        message: string;
    }>;
    getLastUserCompletionId(): string | undefined;
    getLastCompletionId(): string | undefined;
    getCurrentState(): GenerateCompletionState;
    getLastApplyResultsTurn(): CodegenTurn | undefined;
    getLastTurn(): CodegenTurnDone | undefined;
    getLastMessage(): string | undefined;
    getNextUrl(): string | undefined;
    sendFeedback(feedback: Partial<CodegenFeedback>): Promise<void>;
    lastTurnHasChanges(): Promise<boolean>;
    waitUntilState(state: GenerateCompletionState, timeout?: number): Promise<void>;
    getProxyConfig(): {
        proxyOrigin: string | undefined;
        proxyDefaultOrigin: string | undefined;
        proxyDestination: string | undefined;
    };
    clearSession(): Promise<void>;
    clearMessageQueue(emitUserMessages?: boolean): Promise<void>;
    updateMessage(opts: MessageUpdateOptions): void;
    flushMessageQueue(): Promise<void>;
    sendMessage(message: GenerateUserMessage | GenerateUserMessage[]): Promise<string | null>;
    /**
     * Waits for the setup command to finish if it's currently running.
     * Returns information about the setup command state.
     *
     * @param signal - Optional abort signal
     * @returns Object with setup command state information
     */
    waitForSetupCommand(signal?: AbortSignal): Promise<{
        state: "installed" | "not-installed" | "install-failed" | "install-aborted";
        shouldProceed: boolean;
    }>;
    waitForDevServer(signal?: AbortSignal, timeoutMs?: number, expectedStates?: HttpServerState[]): Promise<{
        shouldProceed: boolean;
        message: string;
        serverUrl?: string;
    }>;
    getNamedAgentConfig(agentName: string | undefined, sessionId: string, signal?: AbortSignal): Promise<{
        success: true;
        options: CodeGenSessionOptions;
        resetAfterRun: boolean;
        subagent_type: string;
        /** Set when the run was launched with browser session replay enabled. */
        replayId?: string;
        /**
         * HTTP(S) URL to force-close the browser-service WebSocket on
         * agent shutdown/abort. Present whenever a Chrome connection
         * was acquired (not just when replay is enabled) so the pool
         * slot is freed promptly instead of sitting idle for 30min.
         */
        browserDisconnectUrl?: string;
        /** Optional override for the maximum timeout for this agent. */
        maxTimeoutMs?: number;
    } | {
        success: false;
        response: string;
    }>;
    /**
     * Spawn a named custom agent by ID or name
     * @param agentNameOrId - The agent's name or ID
     * @param options - Additional spawning options
     * @returns SpawnAgentResult
     */
    spawnNamedAgent(agentName: string | undefined, options: {
        prompt: string;
        user: UserSource;
        signal: AbortSignal;
        maxCompletions: number;
        sessionId: string;
        resume?: string;
        mcpServers?: boolean;
        attachmentUrls?: string[];
    }): Promise<SpawnAgentResult>;
    /**
     * Returns info about currently running background sub-agents.
     */
    getRunningSubAgents(): Array<{
        id: string;
        subagentType: string;
        description: string;
        startedAt: number;
        resumed: boolean;
        turns: number;
        state: GenerateCompletionState | "unknown";
        toolsRunning: boolean;
    }>;
    canHandleTool(toolName: keyof CodeGenToolMap): boolean;
    /**
     * Declare tools that are handleable at the session level, independent of
     * live streaming connections. Used by fire-and-forget (queue-based)
     * integrations like Slack where tool calls are handled asynchronously
     * via event hooks rather than a persistent connection.
     *
     * These capabilities are automatically cleared when the session goes idle,
     * simulating a "disconnect". The next message from the integration will
     * re-register them.
     */
    setSessionCanHandleTools(tools: (keyof CodeGenToolMap)[]): void;
    clearSessionCanHandleTools(): void;
    setProxyOrigin(proxySrc: string | undefined, proxyDefaultOrigin: string | undefined): void;
    getTurns(): CodegenTurn[];
    getSessionContext(): SessionContext;
    runSetupCommand(): Promise<import("#ai-utils").SetupCommandResult | undefined>;
    abortSetupCommand(): Promise<import("#ai-utils").SetupCommandResult | undefined> | undefined;
    abortValidateCommand(): Promise<import("#ai-utils").ValidateCommandResult | undefined> | undefined;
    toolsRunning(): boolean;
    abortAllTools(): void;
    /**
     * Fulfil a pending tool call (usually AskUser or any passThrough tool)
     * Exposed via websocket as `toolFullfilment` for the Builder UI to send back
     * the user's response.
     */
    toolFullfilment(id: string, result: ToolResolution | string): boolean;
    /**
     * Resume a question whose in-flight turn was lost to a container reboot. There
     * is no promise to resolve, so we clear the persisted record and feed the
     * answer back as a normal user message, letting the model continue from
     * persisted history.
     */
    resumePersistedToolFulfilment(id: string, result: ToolResolution): boolean;
    cancelAllPendingToolFulfilments(userMessage?: string): void;
    fulfillToolCall(id: string, result: ToolResolution): boolean;
    abortToolCall(id: string, reason?: string): boolean;
    acceptCode(): Promise<void>;
    abort(abortOptions?: CodegenAbortOptions | boolean): Promise<boolean>;
    stopEventLoop(): Promise<void>;
    requestRefresh(): void;
    configureDevOrchestrator(opts: ConfigureDevOrchestratorOpts): Promise<ConfigureDevOrchestratorUpdates>;
    /**
     * Subscribe to file change events for the entire working directory.
     * Returns a dispose function to unsubscribe.
     * The watcher is lazily initialized on first subscription and cleaned up on last unsubscribe.
     */
    subscribeToFileChanges(onEvent: (event: FolderWatchEvent) => void): () => Promise<void>;
    tsServerInit(): Promise<{
        ok: boolean;
        cwd?: string;
        error?: string;
    }>;
    tsServerOpenFile(filePath: string, content: string): Promise<void>;
    tsServerChangeFile(filePath: string, content: string): Promise<void>;
    tsServerCloseFile(filePath: string): Promise<void>;
    tsServerGetCompletions(filePath: string, line: number, offset: number, options?: {
        triggerCharacter?: string;
        includeExternalModuleExports?: boolean;
    }): Promise<import("./tsserver-manager").TsServerRequestResult>;
    tsServerGetCompletionDetails(filePath: string, line: number, offset: number, entryNames: string[]): Promise<import("./tsserver-manager").TsServerRequestResult>;
    tsServerGetDefinition(filePath: string, line: number, offset: number): Promise<import("./tsserver-manager").TsServerRequestResult>;
    tsServerGetTypeDefinition(filePath: string, line: number, offset: number): Promise<import("./tsserver-manager").TsServerRequestResult>;
    tsServerGetQuickInfo(filePath: string, line: number, offset: number): Promise<import("./tsserver-manager").TsServerRequestResult>;
    tsServerGetReferences(filePath: string, line: number, offset: number): Promise<import("./tsserver-manager").TsServerRequestResult>;
    tsServerGetSignatureHelp(filePath: string, line: number, offset: number): Promise<import("./tsserver-manager").TsServerRequestResult>;
    tsServerRequestDiagnostics(filePaths: string[]): Promise<void>;
    tsServerGetRenameLocations(filePath: string, line: number, offset: number): Promise<import("./tsserver-manager").TsServerRequestResult>;
    tsServerGetNavTree(filePath: string): Promise<import("./tsserver-manager").TsServerRequestResult>;
    tsServerOrganizeImports(filePath: string): Promise<import("./tsserver-manager").TsServerRequestResult>;
    tsServerGetInlayHints(filePath: string): Promise<import("./tsserver-manager").TsServerRequestResult>;
    tsServerGetCodeFixes(filePath: string, startLine: number, startOffset: number, endLine: number, endOffset: number, errorCodes: number[]): Promise<import("./tsserver-manager").TsServerRequestResult>;
    tsServerGetApplicableRefactors(filePath: string, startLine: number, startOffset: number, endLine: number, endOffset: number): Promise<import("./tsserver-manager").TsServerRequestResult>;
    tsServerGetEditsForRefactor(filePath: string, startLine: number, startOffset: number, endLine: number, endOffset: number, refactorName: string, actionName: string): Promise<import("./tsserver-manager").TsServerRequestResult>;
    tsServerGetImplementation(filePath: string, line: number, offset: number): Promise<import("./tsserver-manager").TsServerRequestResult>;
    tsServerGetSelectionRange(filePath: string, locations: Array<{
        line: number;
        offset: number;
    }>): Promise<import("./tsserver-manager").TsServerRequestResult>;
    tsServerGetLinkedEditingRange(filePath: string, line: number, offset: number): Promise<import("./tsserver-manager").TsServerRequestResult>;
    tsServerGetFormatRange(filePath: string, startLine: number, startOffset: number, endLine: number, endOffset: number): Promise<import("./tsserver-manager").TsServerRequestResult>;
    subscribeToDiagnostics(onEvent: (event: any) => void): () => void;
    close(opts?: {
        reason?: string;
        uploadGitBackup?: boolean;
    }): Promise<void>;
    sendMessageToOrgAgent(options: SendMessageToOrgAgentInput): Promise<{
        status: "success";
    } | {
        status: "error";
        error: string;
    }>;
    /**
     * Queues a semantic git status reminder for the LLM.
     * Call this after significant git operations to keep the LLM informed.
     */
    queueGitStatusReminder(context: {
        trigger: "session-start" | "sync-success" | "push-success" | "pull-success";
        syncedBranches?: string[];
        pushedToRemote?: boolean;
    }): void;
    manualCommit(options: {
        add: string;
        commitMessage: string;
        folderName?: string;
    }): Promise<boolean>;
    getLastSuggestedAction(): SuggestedActionBuildError | undefined;
    connectToEventLoop(shouldReplay: boolean, onStep: (step: GenerateCompletionStep) => void, options?: {
        canHandleTools?: (keyof CodeGenToolMap)[];
    }): () => void;
    waitUntilPendingPromises(signal?: AbortSignal): Promise<void>;
    waitUntilBlockingPendingPromises(signal?: AbortSignal): Promise<void>;
    waitUntilIdle(signal?: AbortSignal): Promise<void>;
    waitForEventLoop(): Promise<void>;
    /**
     * Stages and optionally commits work in progress.
     *
     * When `#batchCommitsEnabled` is false (default): stages AND commits immediately.
     * When `#batchCommitsEnabled` is true: only stages files, sets #pendingCommit flag.
     *
     * @returns commit hash if committed, false if no changes or staged only
     */
    commitWorkInProgress(defaultCommitMessage: string, changedFiles: string[], owningTurn?: CodegenTurnDone): Promise<void>;
    getChangesReport(): Promise<{
        diff: string;
        files: string[];
    } | undefined>;
    /**
     * Resolves a workspace file path to its actual file system path
     * @param filePath A file path that may include a workspace prefix (e.g., "workspace1/path/to/file.js")
     * @param forceWorkspace If true, will try the first workspace as fallback when no workspace folder is found
     * @returns The actual file system path and the workspace folder it belongs to
     */
    resolveWorkspacePath(filePath: string, forceWorkspace: boolean): {
        resolvedPath: string;
        workspaceFolder?: WorkspaceFolder;
    };
    /**
     * Converts an absolute file system path to a workspace URL
     * @param absolutePath The absolute file system path to convert
     * @returns The workspace URL if the path can be converted, undefined otherwise
     */
    absolutePathToWorkspaceUrl(absolutePath: string): string | undefined;
    /**
     * Launches the editor for a given file path
     * @param filePath The file path to launch the editor for
     * @param line The line number to launch the editor at
     * @param column The column number to launch the editor at
     * @returns void
     */
    launchEditor(opts?: {
        filePath?: string;
        line?: number;
        column?: number;
    }): Promise<{
        success: boolean;
        message?: string;
    }>;
    /**
     * Reads a file from the workspace
     * @param filePath A file path that may include a workspace prefix
     * @returns The file content or null if the file doesn't exist
     */
    readFile(filePath: string, skipAclCheck?: boolean): Promise<string | null>;
    /**
     * Reads a file and returns content with a checksum for caching.
     * If previousChecksum is provided and matches, returns notModified: true
     * without sending the file content.
     */
    readFileWithChecksum(args: {
        filePath: string;
        previousChecksum?: string;
        skipAclCheck?: boolean;
    }): Promise<{
        content: string | null;
        checksum: string | null;
        notModified?: boolean;
    }>;
    /**
     * Reads a binary file from the workspace and returns its content as base64.
     * Unlike readFile which reads as UTF-8 (corrupting binary data), this method
     * preserves binary content by encoding it as base64.
     */
    readBinaryFile(filePath: string): Promise<string | null>;
    /**
     * Gets file content at a specific git reference (e.g., origin/main, HEAD~1, commit hash)
     * @param filePath - The file path relative to the workspace
     * @param gitRef - The git reference (branch, commit, tag) - defaults to parent branch
     * @returns The file content at that reference, or null if not found
     */
    getFileAtRef(filePath: string, gitRef?: string, repoPathOverride?: string): Promise<string | null>;
    /**
     * Gets the diff information for a single file including full content
     * @param args - Either an options object or a file path string (legacy)
     * @param opts.path - The file path, can be folder-prefixed (e.g., 'builder-anime-works/client/App.tsx') or relative
     * @param opts.folderName - Optional folder name (deprecated, prefer folder-prefixed path)
     * @param opts.mode - Diff baseline mode. "remote-parent-branch" (default)
     *   compares against the parent branch merge-base. "remote-current-branch"
     *   compares against origin/<currentBranch> (with fallback to merge-base
     *   when the branch has never been pushed).
     * @returns Object with oldContent (from baseline ref) and newContent (current)
     */
    getSingleFileDiff(args: {
        path: string;
        folderName?: string;
        previousChecksum?: string;
        mode?: "remote-parent-branch" | "remote-current-branch";
    } | string): Promise<{
        oldContent: string | null;
        newContent: string | null;
        action: "create" | "update" | "delete";
        checksum: string | null;
        notModified?: boolean;
    }>;
    /**
     * Discards changes for a specific file by creating a revert commit
     * @param args - Either an options object or a file path string (legacy)
     * @param opts.filePath - The file path, can be folder-prefixed (e.g., 'builder-anime-works/client/App.tsx')
     * @param opts.folderName - Optional folder name (deprecated, prefer folder-prefixed path)
     * @returns success status, commit hash for reverting, and optional error message
     */
    discardFileChanges(args: {
        filePath: string;
        folderName?: string;
    } | string): Promise<{
        success: boolean;
        commitHash?: string;
        error?: string;
    }>;
    /**
     * Reverts a discard commit using git revert
     * @param commitHash - The commit hash to revert
     * @param folderName - Optional folder name to target specific repo (more efficient)
     * @returns success status and optional error message
     */
    revertDiscard(options: {
        commitHash: string;
        folderName?: string;
    }): Promise<{
        success: boolean;
        error?: string;
    }>;
    /**
     * Checks if a file exists in the workspace
     * @param filePath A file path that may include a workspace prefix
     * @returns True if the file exists, false otherwise
     */
    fileExists(filePath: string): Promise<{
        absolutePath: string | undefined;
        recommendedPath: string | undefined;
        workspaceFolder: WorkspaceFolder | undefined;
        virtual: boolean;
    }>;
    /**
     * Reads a file from the workspace synchronously
     * @param filePath A file path that may include a workspace prefix
     * @returns The file content or null if the file doesn't exist
     */
    readFileSync(filePath: string, skipAclCheck?: boolean): string | null;
    /**
     * Writes content to a file in the workspace
     * @param filePath A file path that may include a workspace prefix
     * @param content The content to write
     * @returns True if the write was successful, false otherwise
     */
    writeFile(filePath: string, content: string | Uint8Array, skipAclCheck?: boolean): Promise<string | null>;
    /**
     * Lists files in a directory in the workspace
     * @param dirPath A directory path that may include a workspace prefix
     * @returns Array of file names in the directory or empty array if directory doesn't exist
     */
    listDir(dirPath: string): Promise<string[]>;
    /**
     * List custom instructions (rules and skills) discovered from the workspace.
     * Returns instructions with isSkill flag to distinguish skills from rules.
     */
    listCustomInstructions(): Promise<Array<{
        id: string;
        name: string;
        description?: string;
        type?: string;
        isSkill: boolean;
        disableModelInvocation?: boolean;
        userInvocable?: boolean;
    }>>;
    /**
     * Get stats for a file in the workspace
     * @param filePath A file path that may include a workspace prefix
     * @returns The file stats or null if the file doesn't exist
     */
    stat(filePath: string, skipAclCheck?: boolean): Promise<{
        isDirectory: () => boolean;
        isFile: () => boolean;
        size: number;
    } | null>;
    /**
     * Deletes a file or directory from the workspace.
     * Directories are removed recursively along with all of their contents.
     * @param filePath A file or directory path that may include a workspace prefix
     * @returns The resolved path that was deleted, or null on failure / if it didn't exist
     */
    deleteFile(filePath: string, skipAclCheck?: boolean): Promise<string | null>;
    getLinesStats(): {
        added: number;
        removed: number;
        net: number;
    };
    /**
     * Get git diff between current commit and remote branch
     * If remote current branch doesn't exist, gets diff between default branch and current branch
     * @param numberOfContextLines - Optional number of context lines to include in the diff
     * @param includeFilesOnly - If true, only return filePath and action properties
     * @param filePaths - Optional array of file paths to limit the diff to specific files
     * @param folderName - Optional folder name to specify which repo to get diff from
     */
    getDiffFromRemote({ numberOfContextLines, includeFilesOnly, filePaths, folderName }: {
        numberOfContextLines?: number;
        includeFilesOnly?: boolean;
        filePaths?: Array<string>;
        folderName?: string;
    }): Promise<ApplyActionsResult[]>;
    /**
     * Get git diff based on the specified mode
     * @param mode - The diff mode: 'previous-commit', 'parent-branch', or 'remote'
     * @param numberOfContextLines - Optional number of context lines to include in the diff (e.g., 999 for -U999)
     * @param includeFilesOnly - If true, only return filePath and action properties
     * @param filePaths - Optional array of file paths to limit the diff to specific files
     * @param folderName - Optional folder name to specify which repo to get diff from
     */
    getDiff({ mode, numberOfContextLines, includeFilesOnly, filePaths, folderName }: {
        mode: "remote-parent-branch" | "remote-current-branch";
        numberOfContextLines?: number;
        includeFilesOnly?: boolean;
        filePaths?: Array<string>;
        folderName?: string;
    }): Promise<{
        state: "error" | "success";
        diff?: ApplyActionsResult[];
        error?: Error;
    }>;
    private getDefaultBranch;
    private getDiffFromParentBranch;
}
