/**
 * Gravity tunnel orchestration for `agentuity dev --public`.
 *
 * Wraps the lifecycle of the gravity binary that the CLI spawns to
 * front the user's local dev server with a public HTTPS URL:
 *
 *   1. Spawns gravity with the project + endpoint args we got from
 *      the `/cli/devmode/3/<projectId>` API call.
 *   2. Tails stdout for the `HEARTBEAT_PORT=<n>` line gravity prints
 *      shortly after startup, then POSTs `/heartbeat` to that port
 *      every 5 seconds so gravity knows we're still alive. (The
 *      tunnel auto-tears-down if heartbeats stop.)
 *   3. Forwards stderr to the CLI logger so connection issues are
 *      visible.
 *   4. Exposes a `stop()` that kills the entire gravity process tree
 *      (gravity spawns helper children) and clears the heartbeat
 *      interval.
 *
 * Node-compatible: uses `node:child_process.spawn` with a detached
 * process group so we can deliver SIGTERM to the whole tree on
 * shutdown. No `Bun.spawn`.
 */
import { type ChildProcess } from 'node:child_process';
import type { Logger } from '../../types.ts';
/**
 * Kill any lingering `gravity` processes left over from a previous
 * dev session for this project. Scoped by `--project-id` so other
 * concurrent sessions in different repos aren't affected.
 *
 * No-op on Windows; `pkill` not being available is treated as
 * success (we just don't have an old session to clean up).
 */
export declare function killLingeringGravityProcesses(logger: {
    debug: (msg: string, ...args: unknown[]) => void;
}, projectId?: string): void;
export interface GravityStartOptions {
    /** Path to the gravity binary on disk. */
    binary: string;
    /** Endpoint id returned by the CLI devmode API. */
    endpointId: string;
    /** Local port gravity should forward to (the user's dev server). */
    targetPort: number;
    /** Region-specific gravity gRPC URL. */
    gravityURL: string;
    /** Project owner org id. */
    orgId: string;
    /** Project id. */
    projectId: string;
    /**
     * Base64-encoded private key PEM gravity uses to authenticate
     * with the platform.
     */
    privateKeyB64: string;
    /** Working directory for the spawn (defaults to process cwd). */
    cwd?: string;
    logger: Logger;
}
export interface GravityHandle {
    /** Underlying child process so callers can attach extra listeners. */
    readonly process: ChildProcess;
    /** Resolves when the gravity child exits. */
    readonly exited: Promise<{
        exitCode: number | null;
    }>;
    /**
     * Resolves the first time gravity reports a heartbeat port ("the
     * tunnel is actually up"). Useful for sweeping old binaries only
     * after the new one has confirmed it works.
     */
    readonly ready: Promise<void>;
    /**
     * Stop the tunnel: clears the heartbeat interval and SIGTERMs the
     * gravity process group. Safe to call multiple times.
     */
    stop(): Promise<void>;
    /**
     * Synchronous best-effort SIGKILL of the gravity process group.
     * Intended for `process.on('exit', ...)` handlers where async
     * operations cannot run — use `stop()` for normal shutdown.
     */
    forceKillSync(): void;
}
/**
 * Spawn gravity and wire up heartbeats + log forwarding. Returns
 * once the child has been spawned (heartbeats begin async when the
 * binary prints its `HEARTBEAT_PORT=` line).
 */
export declare function startGravity(opts: GravityStartOptions): GravityHandle;
//# sourceMappingURL=gravity.d.ts.map