/**
 * Local-server discovery for the stdio MCP proxy (Increment 1 of the unified
 * multi-peer editing model — see ~/.claude/plans/indexed-stirring-turtle.md).
 *
 * When `studiograph serve` is running it writes `.studiograph/server.json`
 * describing how to reach it ({ url, pid, workspacePath, serverId }). The stdio
 * proxy (`stdio-proxy.ts`) reads that file and decides, per tool call, whether
 * to forward to the live HTTP server (so writes go through BodyWriteCoordinator
 * and merge into any open editor) or to fall back to an in-process server (safe:
 * no server ⇒ no live editor to clobber).
 *
 * SECURITY (Codex-hardened):
 *  - The Bearer token is only ever sent to a LOOPBACK url. A non-loopback url in
 *    server.json is treated as "no server" — never trusted, never sent a token.
 *  - A 401/403 from the probe means "server present, auth rejected" → FAIL LOUD.
 *    We must NOT fall back to a local in-process write in that case, because a
 *    live editor may be open; a silent local write is the exact data-loss path
 *    this increment removes.
 *  - Identity is the serverId echo + workspacePath match, NOT team_name.
 */
export interface ServerInfo {
    /** Loopback HTTP base url, e.g. "http://127.0.0.1:3000" (no trailing slash). */
    url: string;
    /** PID of the serve process — primary staleness guard. */
    pid: number;
    /** Absolute workspace path the server is bound to. */
    workspacePath: string;
    /** Random per-boot id echoed by GET /api/server-info. */
    serverId: string;
}
export type ProbeResult = {
    mode: 'remote';
    url: string;
    serverId: string;
} | {
    mode: 'local';
} | {
    mode: 'fail';
    reason: string;
};
/** Path to the discovery file for a workspace. */
export declare function serverInfoPath(workspacePath: string): string;
/**
 * Atomically write the discovery file (tmp + rename, like SessionManager's
 * pending-commits persistence) and make sure `server.json` is gitignored in
 * `.studiograph/.gitignore` (covers workspaces created before this template
 * change). Best-effort on the gitignore — a failure there never blocks serve.
 */
export declare function writeServerInfo(workspacePath: string, info: ServerInfo): void;
/** Best-effort removal of the discovery file (called after server.close()). */
export declare function deleteServerInfo(workspacePath: string): void;
/** Read + parse the discovery file. Returns null on missing or malformed JSON. */
export declare function readServerInfo(workspacePath: string): ServerInfo | null;
/** Append `entry` to a `.gitignore` file if not already present (one per line). */
export declare function ensureGitignoreEntry(gitignorePath: string, entry: string): void;
/** True only for loopback hosts. The Bearer token is never sent elsewhere. */
export declare function isLoopbackUrl(url: string): boolean;
/** True if a process with `pid` exists (signal 0 probe). */
export declare function isPidAlive(pid: number): boolean;
export interface ProbeDeps {
    fetchFn?: typeof fetch;
    isPidAliveFn?: (pid: number) => boolean;
    readInfoFn?: (workspacePath: string) => ServerInfo | null;
}
/**
 * Decide whether the stdio proxy should forward to the live local server.
 *
 * Returns `remote` only when every identity check passes; `fail` only when the
 * server is reachable but rejects our token (401/403); `local` for every other
 * case (no file, dead pid, non-loopback, wrong workspace, connection refused,
 * or a different server answering on the port).
 */
export declare function probeServer(workspacePath: string, token: string, deps?: ProbeDeps): Promise<ProbeResult>;
