import type { DevToolsSys } from "../types";
import { type Credentials } from "./credentials";
import type { CodegenFeedback, CodegenTurn, CommitMode, CustomInstruction, FusionConfig, GenerateCompletionState, GenerateCompletionStep, GenerateCompletionStepGit, GenerateUserMessage, UserContext, WorkspaceConfiguration, WorkspaceFolder, LoadWholeSessionOptions, LoadWholeSessionResult, LoadHistoryResult } from "$/ai-utils";
import prettier from "prettier";
import { type FusionContext } from "./code-tools";
import EventEmitter from "node:events";
export interface SessionContext {
    sessionId: string;
    turns: CodegenTurn[];
    customInstructions: CustomInstruction[];
    userContext: UserContext;
    prettierConfig: prettier.Config | null;
    state: GenerateCompletionState;
    title: string | undefined;
    beforeCommit: string | undefined;
    createdUnixTime: number;
    updatedUnixTime: number;
    canLoadMore: boolean;
}
export interface CodeGenSessionOptionsBase {
    sys: DevToolsSys;
    credentials: Credentials;
    position: string;
    maxTokens?: number;
    mode?: "quality" | "quality-v3";
    builtInCustomInstructions?: CustomInstruction[];
    fusionContext?: FusionContext;
    fusionConfig?: FusionConfig;
    workingDirectory?: string;
    workspace?: WorkspaceConfiguration;
    mcpServers?: boolean;
    enabledTools?: string;
}
export interface CodeGenSessionOptionsSession extends CodeGenSessionOptionsBase {
    sessionOrCompletionId?: string;
}
export interface CodeGenSessionOptionsInitialUrl extends CodeGenSessionOptionsBase {
    initialUrl: string;
}
export type CodeGenSessionOptions = CodeGenSessionOptionsSession | CodeGenSessionOptionsInitialUrl;
export type CodeGenEventEmitter = EventEmitter<{
    step: [GenerateCompletionStep];
    idle: [];
}>;
export declare class CodeGenSession {
    #private;
    constructor(options: CodeGenSessionOptions);
    get workingDirectory(): string;
    initializeSession(): Promise<void>;
    loadHistory(): Promise<LoadHistoryResult>;
    loadWholeSession(opts?: LoadWholeSessionOptions): Promise<LoadWholeSessionResult>;
    loadMoreTurns(): Promise<CodegenTurn[]>;
    setRepoUrl(repoUrl: string): void;
    getRepoUrl(): string | undefined;
    setPrUrl(prUrl: string): void;
    prExists(): boolean;
    pushRepo(repoFullName: string, githubToken: string): Promise<{
        success: boolean;
        error: string;
        details?: undefined;
    } | {
        output: string;
        upToDate: boolean;
        createdBranch: boolean;
        setUpToStream: boolean;
        status: GenerateCompletionStepGit | null;
        success: boolean;
        error?: undefined;
        details?: undefined;
    } | {
        success: boolean;
        error: string;
        details: string;
    }>;
    archiveProject(): Promise<string>;
    uploadBackup(): Promise<{
        success: boolean;
        filePath: string;
        expiresAt: string;
        bundleSize: number;
    }>;
    createPR(...args: [
        {
            repoFullName: string;
            githubToken: string;
            branchName: string;
            projectId: string;
        }
    ] | [string, string, string, string]): Promise<{
        output: string;
        upToDate: boolean;
        createdBranch: boolean;
        setUpToStream: boolean;
        status: GenerateCompletionStepGit | null;
        success: boolean;
        prUrl: any;
        prNumber: any;
        error?: undefined;
        details?: undefined;
    } | {
        success: boolean;
        error: string;
        details: unknown;
    }>;
    getCommitMode(): CommitMode | undefined;
    setCommitMode(commitMode: CommitMode): void;
    pushChanges(pullFirst?: boolean): Promise<{
        output: string;
        upToDate: boolean;
        createdBranch: boolean;
        setUpToStream: boolean;
        status: GenerateCompletionStepGit | null;
    }>;
    hasChangesRelativeToRemote(): Promise<boolean>;
    pullLatestFromRemote(): Promise<void>;
    syncChangesFromMain(mainBranchName: string): Promise<{
        success: boolean;
        message: string;
        conflicts?: undefined;
    } | {
        success: boolean;
        conflicts: boolean;
        message: string;
    }>;
    /**
     * Get the current commit hash
     */
    getCurrentCommitHash(): Promise<string | undefined>;
    /**
     * Get the feature branch name
     */
    getFeatureBranch(): string | undefined;
    /**
     * Get the AI branch name
     */
    getAiBranch(): string | undefined;
    /**
     * Helper to run git commands
     */
    runGitCommand(command: string, cwd?: string): Promise<string>;
    /**
     * Helper to run git commands
     */
    runCheckCommand(): Promise<{
        code: number;
        logs: string;
    } | null>;
    setDebug(debug: boolean): void;
    getAllFiles(): Promise<string[]>;
    getSessionId(): string;
    getSpaceId(): string | undefined;
    /**
     * 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, dryRun, forceReplay, debug, }: {
        location: "before" | "after";
        predicate: (turn: CodegenTurn | null, index: number) => boolean;
        dryRun?: boolean;
        forceReplay?: boolean;
        debug?: string;
    }): Promise<string[] | null>;
    restoreHEAD(): Promise<string[] | null>;
    restoreAll(): Promise<string[] | null>;
    restoreFromCompletionId({ location, completionId, forceReplay, }: {
        location: "before" | "after";
        completionId: string;
        forceReplay?: boolean;
    }): Promise<string[] | null>;
    restoreBeforeCompletionId(completionId: string): Promise<string[] | null>;
    /**
     * Undo all changes back to the last user message
     */
    undoLastUserMessage(dryRun?: boolean): Promise<string[] | null>;
    getLastCompletionId(): string | undefined;
    getCurrentState(): GenerateCompletionState;
    getLastApplyResultsTurn(): CodegenTurn | undefined;
    getLastTurn(): CodegenTurn | undefined;
    getNextUrl(): string | undefined;
    getNextMessage(): {
        shouldWait: boolean;
        promise: Promise<GenerateUserMessage | undefined>;
    };
    sendFeedback(feedback: Partial<CodegenFeedback>): Promise<void>;
    lastTurnHasChanges(): Promise<boolean>;
    waitUntilState(state: GenerateCompletionState, timeout?: number): Promise<void>;
    clearSession(): void;
    sendMessage(message: GenerateUserMessage, immediate?: boolean): Promise<void>;
    getTurns(): CodegenTurn[];
    getSessionContext(): SessionContext;
    runSetupCommand(): Promise<import("./launch/dev-server-orchestrator").SetupCommandResult | undefined>;
    abortSetupCommand(): void;
    abort(cleanCurrentMessage?: boolean): Promise<boolean>;
    stopEventLoop(): Promise<void>;
    requestRefresh(): void;
    close(uploadGitBackup?: boolean): Promise<void>;
    emitGitStatus(): Promise<GenerateCompletionStepGit | null>;
    manualCommit(options: {
        add: string;
        commitMessage: string;
    }): Promise<void>;
    connectToEventLoop(shouldReplay: boolean, onStep: (step: GenerateCompletionStep) => void): () => void;
    waitUntilIdle(): Promise<void>;
    waitForEventLoop(): Promise<void>;
    agentCompletion(userMessage: GenerateUserMessage, signal: AbortSignal | undefined, onStep: (step: GenerateCompletionStep) => void): Promise<void>;
    commitWorkInProgress(lastTurn: CodegenTurn): Promise<string | undefined>;
    isCleanWorkTree(): Promise<boolean>;
    /**
     * 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;
    };
    /**
     * 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): Promise<string | null>;
    /**
     * 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<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): 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): Promise<boolean>;
    /**
     * 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[]>;
    /**
     * 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): Promise<{
        isDirectory: () => boolean;
        isFile: () => boolean;
    } | null>;
    /**
     * Deletes a file from the workspace
     * @param filePath A file path that may include a workspace prefix
     * @returns True if the delete was successful, false otherwise
     */
    deleteFile(filePath: string): Promise<boolean>;
    getNetLinesChanged(): number;
}
export declare function getUserContext(sys: DevToolsSys, gitWorkingDirectory?: string): Promise<UserContext>;
export declare function makeAsyncIterator<T>(): readonly [AsyncGenerator<T, void, void>, (event: T) => void, () => void];
/**
 * Loads a workspace configuration from a JSON file
 * @param sys DevToolsSys instance
 * @param workspaceFile Path to the workspace JSON file
 * @returns The workspace configuration and working directory
 */
export declare function loadWorkspace(sys: DevToolsSys, workspaceFile: string): Promise<{
    workspace: WorkspaceConfiguration;
    workingDirectory: string;
}>;
export declare function keepAlive(): () => void;
