import { type Files } from '../files.ts';
import type { Decisions } from '../../policy/decisions.ts';
import type { MountEntry } from '../mount/mount.ts';
import type { SessionState } from '../session/session.ts';
import type { ExecuteResult, SessionExecuteOptions } from '../workspace/types.ts';
import { FileVersionTracker } from './file_version.ts';
import { type WorkspaceMediaRead } from './read_file.ts';
export interface ToolResult {
    [key: string]: unknown;
    content: {
        type: 'text';
        text: string;
    }[];
    isError?: boolean;
}
/** What a tool table acts through: one session's entry points (`Session`). */
export interface SessionLike {
    readonly sessionId: string;
    readonly state: SessionState;
    readonly decisions: Decisions;
    readonly vfs: Files;
    mounts(): readonly MountEntry[];
    shell(command: string, options?: SessionExecuteOptions): Promise<ExecuteResult>;
    glob(pattern: string): Promise<string[]>;
    loaded(): Promise<void>;
    reads(): Promise<FileVersionTracker>;
}
/** What an adapter takes to pick a session's tool table. */
export interface MirageToolOperationsOptions {
    staleWriteProtection?: boolean;
    /**
     * The session the tools act as, with its cwd, environment and mount
     * grants; the workspace's default session when absent.
     */
    sessionId?: string;
}
export declare function ensureParents(vfs: Files, path: string): Promise<void>;
/** Every tool, in the order the entry points list them. */
export declare const TOOL_NAMES: readonly ["shell", "read", "write", "edit", "ls", "grep", "glob"];
/**
 * Whether a session may write anywhere: a mount it can see whose mode,
 * narrowed by the profile or opened by a show entry below it, reaches
 * write. `/dev` is left out: its null sink takes a write from anyone and
 * stores nothing. Mirrors Python's `writes`.
 */
export declare function writes(session: SessionState, mounts: readonly MountEntry[]): boolean;
/**
 * The agent tools for one session, independent of any agent framework.
 * `session.tools` is the session's own table. Every guarded table of a
 * session shares the session's read history, so a read through one
 * guards a write through another. Build one directly only to turn the
 * guard off.
 */
export declare class MirageToolOperations {
    private readonly session;
    private readonly own;
    /**
     * @param session The session the tools act as, with its cwd,
     *   environment and mount grants.
     * @param staleWriteProtection False lets an agent overwrite a file that
     *   changed since it read it.
     */
    constructor(session: SessionLike, staleWriteProtection?: boolean);
    /**
     * The read history this call uses: the session's, which every guarded
     * table of the session shares, or this table's own when the guard is
     * off. A call keeps the one it started with, so a restore during the
     * call cannot mix two histories.
     */
    private versions;
    /**
     * The tools this session can use, in the order the entry points list them.
     * Read off the session's profile, so no entry point offers a tool every call
     * of which would be refused: `shell` needs a command the allow list
     * installs, `ls` and `grep` run those commands and need them, and
     * `write` and `edit` need somewhere the session may write. `read` and
     * `glob` are always offered; what they cannot reach answers as the
     * error it is. A session not loaded yet (a stored one before its first
     * call) is offered every tool, since its profile is not known here; the
     * policies still judge each call, and `offered` loads it first. Mirrors
     * Python's `names`.
     */
    names(): readonly string[];
    /**
     * The tools this session can use, its sessions loaded first, so a stored
     * session answers with its own profile: what an async entry point lists and
     * calls by. Mirrors Python's `offered`.
     */
    offered(): Promise<readonly string[]>;
    private lineOptions;
    /** Run a line in the session's shell; `signal` aborts it, as in-app. */
    shell(command: string, signal?: AbortSignal): Promise<ToolResult>;
    /** Read a file as line-numbered text; a relative path is taken under the session's cwd, spelled as given. */
    read(given: string, offset?: number, limit?: number): Promise<ToolResult>;
    /**
     * Read a file for an entry point that hands media to the model, in one fetch:
     * an image or a PDF comes back as media and counts as seen in full;
     * anything else is the `read` answer for the same bytes. Either way
     * the file is stamped for a later edit.
     */
    readMedia(given: string, offset?: number, limit?: number): Promise<ToolResult | WorkspaceMediaRead>;
    private readFailure;
    private numbered;
    /**
     * Write a file; an existing one must have been read in full first. A
     * new file is created with its missing parents. An existing one is
     * overwritten only when the agent was shown all of it and it did not
     * change since, so a write never clobbers text the agent has not seen. A
     * relative path is taken under the session's cwd, spelled as given.
     */
    write(given: string, content: string): Promise<ToolResult>;
    /** Replace a string in an existing file; a relative path is taken under the session's cwd, spelled as given. */
    edit(given: string, oldString: string, newString: string, replaceAll?: boolean): Promise<ToolResult>;
    ls(path: string, signal?: AbortSignal): Promise<ToolResult>;
    /**
     * Search recursively for a pattern, as `grep -rn` does. Each option is
     * the GNU grep flag of the same name, and the line runs in the
     * session's shell, so the search is the shell's own: the same policy,
     * push-down and history as typing it. grep exits 1 when nothing
     * matched, an empty answer rather than a failure, so only an exit above
     * 1 (a bad regex, an unreadable path) is a tool error.
     */
    grep(pattern: string, path: string, options?: {
        ignoreCase?: boolean | undefined;
        fixedStrings?: boolean | undefined;
        include?: string | undefined;
        context?: number | undefined;
        filesWithMatches?: boolean | undefined;
        count?: boolean | undefined;
        maxCount?: number | undefined;
    }, signal?: AbortSignal): Promise<ToolResult>;
    /**
     * Find files, not directories, whose path matches a pattern. The
     * pattern is expanded by `Session.glob`, the shell's own resolver:
     * `**` matches any number of directories, and a relative pattern is
     * matched under `path`. A symlink to a file counts; a dangling one does
     * not, nor does a match the workspace refuses to stat, since nothing
     * says what it is. Any other failure propagates rather than pass for a
     * short list.
     */
    glob(pattern: string, path?: string): Promise<ToolResult>;
    /**
     * Run one tool by name with its JSON input. The one entry every entry point
     * shares: MCP, the HTTP routes, the CLI and the agent adapters hand a
     * tool's name and its input, as the tool's `*_INPUT` schema reads it,
     * to this method, so each tool answers the same way through each of
     * them. Throws for a name no tool has, or one the session's profile does
     * not offer (`offered`). Mirrors Python's `call`.
     */
    call(name: string, args: Readonly<Record<string, unknown>>, signal?: AbortSignal): Promise<ToolResult>;
}
//# sourceMappingURL=tool_operations.d.ts.map