"""Type stubs for the _microsandbox native extension module."""

from __future__ import annotations

import os
from collections.abc import AsyncIterator, Awaitable, Mapping, Sequence
from typing import Any, Literal

from microsandbox.types import (
    BackendKind,
    DiskCompactionResult,
    DiskImageFormat,
    ExecEventType,
    ExecOptions,
    FsEntryKind,
    GuestFlush,
    HostPermissions,
    ImageArchiveFormat,
    ImageSource,
    InitConfig,
    InitOptions,
    LogLevel,
    LogReadSource,
    LogSource,
    ModificationPolicy,
    MountConfig,
    NamedVolumeMode,
    Network,
    NetworkPolicy,
    PatchConfig,
    PortBinding,
    PullEventType,
    PullPolicy,
    RegistryAuth,
    Rlimit,
    RootDiskConfig,
    SandboxModificationPlan,
    SandboxStatus,
    SecretEntry,
    SecretModifySpec,
    SecurityProfile,
    SnapshotFormat,
    SnapshotScope,
    SnapshotStateKind,
    StatVirtualization,
    Stdin,
    ViolationAction,
    VolumeKind,
    VsockRoute,
)

class ForkOutcome:
    @property
    def name(self) -> str: ...
    @property
    def sandbox(self) -> Sandbox | None: ...
    @property
    def error(self) -> Exception | None: ...

# Deprecated: use ForkOutcome.
BranchOutcome = ForkOutcome

class PyAgentClient:
    """Raw agent client.

    Sandbox names passed to connect_sandbox are limited to 128 UTF-8 bytes.
    """

    @staticmethod
    async def connect_sandbox(
        name: str,
        *,
        timeout: float | None = None,
    ) -> PyAgentClient: ...
    @staticmethod
    async def connect(
        path: str,
        *,
        timeout: float | None = None,
    ) -> PyAgentClient: ...
    @staticmethod
    def socket_path(name: str) -> str: ...
    async def request(self, flags: int, body: bytes) -> dict[str, int | bytes]: ...
    async def stream_open(self, flags: int, body: bytes) -> dict[str, int]: ...
    async def stream_next(self, handle: int) -> dict[str, int | bytes] | None: ...
    async def stream_close(self, handle: int) -> None: ...
    async def send(self, id: int, flags: int, body: bytes) -> None: ...
    def ready_bytes(self) -> bytes: ...
    async def close(self) -> None: ...

class SandboxPage:
    @property
    def sandboxes(self) -> list[SandboxHandle]: ...
    @property
    def next_cursor(self) -> str | None: ...

class Sandbox:
    """Sandbox lifecycle API.

    Sandbox names are limited to 128 UTF-8 bytes.
    """

    @staticmethod
    async def restore(
        snapshot: Snapshot | SnapshotHandle | str | os.PathLike[str],
        *,
        name: str,
        cpus: int | None = None,
        memory: int | None = None,
        network_policy: NetworkPolicy | None = None,
        max_connections: int | None = None,
        max_tcp_connections: int | None = None,
        max_udp_connections: int | None = None,
        disable_network: bool = False,
        security: SecurityProfile | None = None,
        max_duration: float | None = None,
        idle_timeout: float | None = None,
        cow_memory: bool = False,
        forked: bool = False,  # Deprecated: use cow_memory.
        disk_only: bool = False,
        snapshot_base: str | None = None,
        user: str | None = None,
        log_level: LogLevel | None = None,
        volumes: Mapping[str, MountConfig] | None = None,
        captured_volumes: Sequence[str] | None = None,
        ports: Mapping[int, int] | Sequence[PortBinding] | None = None,
        tcp_accept_queue_size: int | None = None,
        vsock: Mapping[str, int] | Sequence[VsockRoute] | None = None,
        external_mount_policy: Literal["strict", "relaxed"] = "strict",
        dangerously_inherit_resources: bool = False,
        allow_missing_resources: bool = False,
    ) -> Sandbox: ...
    @staticmethod
    def restore_with_progress(
        snapshot: Snapshot | SnapshotHandle | str | os.PathLike[str],
        *,
        name: str,
        cpus: int | None = None,
        memory: int | None = None,
        network_policy: NetworkPolicy | None = None,
        max_connections: int | None = None,
        max_tcp_connections: int | None = None,
        max_udp_connections: int | None = None,
        disable_network: bool = False,
        security: SecurityProfile | None = None,
        max_duration: float | None = None,
        idle_timeout: float | None = None,
        cow_memory: bool = False,
        forked: bool = False,  # Deprecated: use cow_memory.
        disk_only: bool = False,
        snapshot_base: str | None = None,
        user: str | None = None,
        log_level: LogLevel | None = None,
        volumes: Mapping[str, MountConfig] | None = None,
        captured_volumes: Sequence[str] | None = None,
        ports: Mapping[int, int] | Sequence[PortBinding] | None = None,
        tcp_accept_queue_size: int | None = None,
        vsock: Mapping[str, int] | Sequence[VsockRoute] | None = None,
        external_mount_policy: Literal["strict", "relaxed"] = "strict",
        dangerously_inherit_resources: bool = False,
        allow_missing_resources: bool = False,
    ) -> PullSession: ...
    @staticmethod
    async def create(
        name: str,
        *,
        image: str | os.PathLike[str] | ImageSource | None = None,
        memory: int | None = None,
        cpus: int | None = None,
        max_memory: int | None = None,
        max_cpus: int | None = None,
        workdir: str | None = None,
        shell: str | None = None,
        security: SecurityProfile | None = None,
        hostname: str | None = None,
        user: str | None = None,
        entrypoint: Sequence[str] | None = None,
        cmd: Sequence[str] | None = None,
        init: str | InitConfig | InitOptions | None = None,
        replace: bool = False,
        replace_with_timeout: float | None = None,
        max_duration: float | None = None,
        idle_timeout: float | None = None,
        ephemeral: bool = False,
        env: Mapping[str, str] | None = None,
        labels: Mapping[str, str] | None = None,
        scripts: Mapping[str, str] | None = None,
        pull_policy: PullPolicy | None = None,
        log_level: LogLevel | None = None,
        registry_auth: RegistryAuth | None = None,
        registry_insecure: bool = False,
        registry_ca_certs: list[bytes | bytearray | str | os.PathLike[str]] | None = None,
        volumes: Mapping[str, MountConfig] | None = None,
        patches: Sequence[PatchConfig] | None = None,
        ports: Mapping[int, int] | Sequence[PortBinding] | None = None,
        vsock: Mapping[str, int] | Sequence[VsockRoute] | None = None,
        network: Network | None = None,
        secrets: Sequence[SecretEntry] | None = None,
        secret_violation_action: ViolationAction | None = None,
        detached: bool = False,
    ) -> Sandbox: ...
    @staticmethod
    async def connect_or_create(
        name: str,
        *,
        image: str | os.PathLike[str] | ImageSource | None = None,
        memory: int | None = None,
        cpus: int | None = None,
        max_memory: int | None = None,
        max_cpus: int | None = None,
        workdir: str | None = None,
        shell: str | None = None,
        security: SecurityProfile | None = None,
        hostname: str | None = None,
        user: str | None = None,
        entrypoint: Sequence[str] | None = None,
        cmd: Sequence[str] | None = None,
        init: str | InitConfig | InitOptions | None = None,
        replace: bool = False,
        replace_with_timeout: float | None = None,
        max_duration: float | None = None,
        idle_timeout: float | None = None,
        ephemeral: bool = False,
        env: Mapping[str, str] | None = None,
        labels: Mapping[str, str] | None = None,
        scripts: Mapping[str, str] | None = None,
        pull_policy: PullPolicy | None = None,
        log_level: LogLevel | None = None,
        registry_auth: RegistryAuth | None = None,
        registry_insecure: bool = False,
        registry_ca_certs: list[bytes | bytearray | str | os.PathLike[str]] | None = None,
        volumes: Mapping[str, MountConfig] | None = None,
        patches: Sequence[PatchConfig] | None = None,
        ports: Mapping[int, int] | Sequence[PortBinding] | None = None,
        vsock: Mapping[str, int] | Sequence[VsockRoute] | None = None,
        network: Network | None = None,
        secrets: Sequence[SecretEntry] | None = None,
        secret_violation_action: ViolationAction | None = None,
        detached: bool = False,
    ) -> Sandbox: ...
    @staticmethod
    async def start(name: str, *, detached: bool = False) -> Sandbox: ...
    @staticmethod
    async def get(name: str) -> SandboxHandle: ...
    @staticmethod
    async def list() -> SandboxPage: ...
    @staticmethod
    async def list_with(
        *,
        cursor: str | None = None,
        limit: int | None = None,
        labels: Mapping[str, str] | None = None,
    ) -> SandboxPage: ...
    @staticmethod
    async def remove(name: str) -> None: ...
    @staticmethod
    def create_with_progress(
        name: str,
        *,
        image: str | os.PathLike[str] | ImageSource | None = None,
        memory: int | None = None,
        cpus: int | None = None,
        max_memory: int | None = None,
        max_cpus: int | None = None,
        workdir: str | None = None,
        shell: str | None = None,
        security: SecurityProfile | None = None,
        hostname: str | None = None,
        user: str | None = None,
        entrypoint: Sequence[str] | None = None,
        cmd: Sequence[str] | None = None,
        init: str | InitConfig | InitOptions | None = None,
        replace: bool = False,
        replace_with_timeout: float | None = None,
        max_duration: float | None = None,
        idle_timeout: float | None = None,
        ephemeral: bool = False,
        env: Mapping[str, str] | None = None,
        labels: Mapping[str, str] | None = None,
        scripts: Mapping[str, str] | None = None,
        pull_policy: PullPolicy | None = None,
        log_level: LogLevel | None = None,
        registry_auth: RegistryAuth | None = None,
        registry_insecure: bool = False,
        registry_ca_certs: list[bytes | bytearray | str | os.PathLike[str]] | None = None,
        volumes: Mapping[str, MountConfig] | None = None,
        patches: Sequence[PatchConfig] | None = None,
        ports: Mapping[int, int] | Sequence[PortBinding] | None = None,
        vsock: Mapping[str, int] | Sequence[VsockRoute] | None = None,
        network: Network | None = None,
        secrets: Sequence[SecretEntry] | None = None,
        secret_violation_action: ViolationAction | None = None,
        detached: bool = False,
    ) -> PullSession: ...
    async def name(self) -> str: ...
    async def id(self) -> str: ...
    @property
    def owns_lifecycle(self) -> Awaitable[bool]: ...
    @property
    def fs(self) -> SandboxFsOps: ...
    async def exec_default(
        self,
        *,
        cwd: str | None = None,
        user: str | None = None,
        env: Mapping[str, str] | None = None,
        timeout: float | None = None,
        stdin: Stdin | bytes | None = None,
        tty: bool = False,
        rlimits: list[Rlimit] | None = None,
    ) -> ExecOutput: ...
    async def exec_default_stream(
        self,
        *,
        cwd: str | None = None,
        user: str | None = None,
        env: Mapping[str, str] | None = None,
        timeout: float | None = None,
        stdin: Stdin | bytes | None = None,
        tty: bool = False,
        rlimits: list[Rlimit] | None = None,
    ) -> ExecHandle: ...
    async def exec(
        self,
        cmd: str,
        args: list[str] | ExecOptions | None = None,
        *,
        cwd: str | None = None,
        user: str | None = None,
        env: Mapping[str, str] | None = None,
        timeout: float | None = None,
        stdin: Stdin | bytes | None = None,
        tty: bool = False,
        rlimits: list[Rlimit] | None = None,
    ) -> ExecOutput: ...
    async def exec_stream(
        self,
        cmd: str,
        args: list[str] | ExecOptions | None = None,
        *,
        cwd: str | None = None,
        user: str | None = None,
        env: Mapping[str, str] | None = None,
        timeout: float | None = None,
        stdin: Stdin | bytes | None = None,
        tty: bool = False,
        rlimits: list[Rlimit] | None = None,
    ) -> ExecHandle: ...
    async def shell(
        self,
        script: str,
        *,
        cwd: str | None = None,
        user: str | None = None,
        env: Mapping[str, str] | None = None,
        timeout: float | None = None,
        stdin: Stdin | bytes | None = None,
        tty: bool = False,
        rlimits: list[Rlimit] | None = None,
    ) -> ExecOutput: ...
    async def shell_stream(
        self,
        script: str,
        *,
        cwd: str | None = None,
        user: str | None = None,
        env: Mapping[str, str] | None = None,
        timeout: float | None = None,
        stdin: Stdin | bytes | None = None,
        tty: bool = False,
        rlimits: list[Rlimit] | None = None,
    ) -> ExecHandle: ...
    def ssh(self) -> SandboxSshOps: ...
    async def attach_default(
        self,
        *,
        cwd: str | None = None,
        user: str | None = None,
        env: Mapping[str, str] | None = None,
        detach_keys: str | None = None,
    ) -> int: ...
    async def attach(
        self,
        cmd: str,
        args: list[str] | None = None,
        *,
        cwd: str | None = None,
        user: str | None = None,
        env: Mapping[str, str] | None = None,
        detach_keys: str | None = None,
    ) -> int: ...
    async def attach_shell(self) -> int: ...
    async def metrics(self) -> SandboxMetrics: ...
    async def ping(self) -> SandboxPingResult: ...
    async def touch(self) -> SandboxTouchResult: ...
    async def compact(
        self,
        *,
        layers: int | None = None,
        dry_run: bool = False,
        disk: str | None = None,
        root_disk_only: bool = False,
    ) -> DiskCompactionResult: ...
    async def modify(
        self,
        *,
        cpus: int | None = None,
        max_cpus: int | None = None,
        memory: int | None = None,
        max_memory: int | None = None,
        root_disk_size: int | None = None,
        env: Mapping[str, str] | None = None,
        env_rm: list[str] | None = None,
        labels: Mapping[str, str] | None = None,
        labels_rm: list[str] | None = None,
        workdir: str | None = None,
        secrets: Mapping[str, SecretModifySpec] | None = None,
        secrets_rm: list[str] | None = None,
        policy: ModificationPolicy | None = None,
        dry_run: bool = False,
    ) -> SandboxModificationPlan: ...
    async def metrics_stream(self, interval: float = 1.0) -> MetricsStream: ...
    async def logs(
        self,
        tail: int | None = None,
        since_ms: float | None = None,
        until_ms: float | None = None,
        sources: list[LogReadSource] | None = None,
    ) -> list[LogEntry]: ...
    async def log_stream(
        self,
        sources: list[LogReadSource] | None = None,
        since_ms: float | None = None,
        from_cursor: str | None = None,
        until_ms: float | None = None,
        follow: bool = False,
    ) -> LogStream: ...
    async def restore_warnings(self) -> list[ExternalMountWarning]: ...
    async def stop(self, timeout: float | None = None) -> None: ...
    async def stop_with_timeout(self, timeout: float) -> None: ...
    async def fork(
        self, name: str, *, record_integrity: bool = False,
        guest_flush: GuestFlush | None = None,
    ) -> Sandbox: ...
    # Deprecated: use fork.
    async def branch(
        self, name: str, *, record_integrity: bool = False,
        guest_flush: GuestFlush | None = None,
    ) -> Sandbox: ...
    async def fork_many(
        self, names: list[str], *, record_integrity: bool = False,
        guest_flush: GuestFlush | None = None,
    ) -> list[ForkOutcome]: ...
    # Deprecated: use fork_many.
    async def branch_many(
        self, names: list[str], *, record_integrity: bool = False,
        guest_flush: GuestFlush | None = None,
    ) -> list[ForkOutcome]: ...
    async def pause(self, *, guest_flush: GuestFlush | None = None) -> None: ...
    async def resume(self) -> None: ...
    async def request_stop(self) -> None: ...
    async def kill(self, timeout: float | None = None) -> None: ...
    async def request_kill(self) -> None: ...
    async def request_drain(self) -> None: ...
    async def wait_for_status(self, status: SandboxStatus) -> SandboxHandle: ...
    async def restart(
        self,
        *,
        force: bool = False,
        timeout: float | None = None,
        detached: bool = False,
    ) -> Sandbox: ...
    async def destroy(self, *, force: bool = False, timeout: float | None = None) -> None: ...
    async def wait_until_stopped(self) -> SandboxStopResult: ...
    async def detach(self) -> None: ...
    async def __aenter__(self) -> Sandbox: ...
    async def __aexit__(
        self, exc_type: type | None, exc_val: BaseException | None, exc_tb: Any
    ) -> bool: ...

class SandboxStopResult:
    @property
    def name(self) -> str: ...
    @property
    def status(self) -> SandboxStatus: ...
    @property
    def exit_code(self) -> int | None: ...
    @property
    def signal(self) -> int | None: ...
    @property
    def observed_at(self) -> float: ...
    @property
    def source(self) -> str | None: ...

class SandboxPingResult:
    @property
    def name(self) -> str: ...
    @property
    def latency_ms(self) -> float: ...

class SandboxTouchResult:
    @property
    def name(self) -> str: ...
    @property
    def activity_seq(self) -> int: ...

class SandboxHandle:
    """Lightweight sandbox metadata handle.

    Sandbox names are limited to 128 UTF-8 bytes.
    """

    @property
    def name(self) -> str: ...
    @property
    def id(self) -> str: ...
    @property
    def status(self) -> SandboxStatus: ...
    @property
    def config_json(self) -> str: ...
    @property
    def created_at(self) -> float | None: ...
    @property
    def updated_at(self) -> float | None: ...
    async def metrics(self) -> SandboxMetrics: ...
    async def storage_usage(self) -> StorageItemUsage: ...
    async def ping(self) -> SandboxPingResult: ...
    async def touch(self) -> SandboxTouchResult: ...
    async def compact(
        self,
        *,
        layers: int | None = None,
        dry_run: bool = False,
        disk: str | None = None,
        root_disk_only: bool = False,
    ) -> DiskCompactionResult: ...
    async def modify(
        self,
        *,
        cpus: int | None = None,
        max_cpus: int | None = None,
        memory: int | None = None,
        max_memory: int | None = None,
        root_disk_size: int | None = None,
        env: Mapping[str, str] | None = None,
        env_rm: list[str] | None = None,
        labels: Mapping[str, str] | None = None,
        labels_rm: list[str] | None = None,
        workdir: str | None = None,
        secrets: Mapping[str, SecretModifySpec] | None = None,
        secrets_rm: list[str] | None = None,
        policy: ModificationPolicy | None = None,
        dry_run: bool = False,
    ) -> SandboxModificationPlan: ...
    async def logs(
        self,
        tail: int | None = None,
        since_ms: float | None = None,
        until_ms: float | None = None,
        sources: list[LogReadSource] | None = None,
    ) -> list[LogEntry]: ...
    async def log_stream(
        self,
        sources: list[LogReadSource] | None = None,
        since_ms: float | None = None,
        from_cursor: str | None = None,
        until_ms: float | None = None,
        follow: bool = False,
    ) -> LogStream: ...
    async def start(self, *, detached: bool = False) -> Sandbox: ...
    def config(self) -> dict[str, Any]: ...
    async def refresh(self) -> SandboxHandle: ...
    async def connect(self, timeout: float | None = None) -> Sandbox: ...
    async def connect_or_start(self, *, detached: bool = False) -> Sandbox: ...
    async def stop(self, timeout: float | None = None) -> None: ...
    async def stop_with_timeout(self, timeout: float) -> None: ...
    async def fork(
        self, name: str, *, record_integrity: bool = False,
        guest_flush: GuestFlush | None = None,
    ) -> Sandbox: ...
    # Deprecated: use fork.
    async def branch(
        self, name: str, *, record_integrity: bool = False,
        guest_flush: GuestFlush | None = None,
    ) -> Sandbox: ...
    async def fork_many(
        self, names: list[str], *, record_integrity: bool = False,
        guest_flush: GuestFlush | None = None,
    ) -> list[ForkOutcome]: ...
    # Deprecated: use fork_many.
    async def branch_many(
        self, names: list[str], *, record_integrity: bool = False,
        guest_flush: GuestFlush | None = None,
    ) -> list[ForkOutcome]: ...
    async def pause(self, *, guest_flush: GuestFlush | None = None) -> None: ...
    async def resume(self) -> None: ...
    async def request_stop(self) -> None: ...
    async def kill(self, timeout: float | None = None) -> None: ...
    async def request_kill(self) -> None: ...
    async def request_drain(self) -> None: ...
    async def wait_for_status(self, status: SandboxStatus) -> SandboxHandle: ...
    async def restart(
        self,
        *,
        force: bool = False,
        timeout: float | None = None,
        detached: bool = False,
    ) -> Sandbox: ...
    async def destroy(self, *, force: bool = False, timeout: float | None = None) -> None: ...
    async def wait_until_stopped(self) -> SandboxStopResult: ...
    async def remove(self) -> None: ...
    async def snapshot(self, name: str) -> Snapshot: ...

class ExecOutput:
    @property
    def exit_code(self) -> int: ...
    @property
    def success(self) -> bool: ...
    @property
    def stdout_text(self) -> str: ...
    @property
    def stderr_text(self) -> str: ...
    @property
    def stdout_bytes(self) -> bytes: ...
    @property
    def stderr_bytes(self) -> bytes: ...

class ExecHandle:
    @property
    def id(self) -> str: ...
    def take_stdin(self) -> ExecSink | None: ...
    async def recv(self) -> ExecEvent | None: ...
    async def wait(self) -> tuple[int, bool]: ...
    async def collect(self) -> ExecOutput: ...
    async def signal(self, sig: int) -> None: ...
    async def kill(self) -> None: ...
    async def resize(self, rows: int, cols: int) -> None: ...
    def __aiter__(self) -> AsyncIterator[ExecEvent]: ...
    async def __anext__(self) -> ExecEvent: ...

class ExecSink:
    async def write(self, data: bytes) -> None: ...
    async def close(self) -> None: ...

class ExecEvent:
    event_type: ExecEventType
    pid: int | None
    data: bytes | None
    code: int | None

class SandboxSshOps:
    async def open_client(
        self,
        *,
        user: str = "root",
        term: str | None = None,
        sftp: bool = True,
        inactivity_timeout: float | None = None,
    ) -> SshClient: ...
    async def prepare_server(
        self,
        *,
        host_key_path: str | os.PathLike[str] | None = None,
        authorized_keys_path: str | os.PathLike[str] | None = None,
        user: str | None = None,
        sftp: bool = True,
        inactivity_timeout: float | None = None,
    ) -> SshServer: ...

class SshOutput:
    @property
    def status(self) -> int: ...
    @property
    def success(self) -> bool: ...
    @property
    def stdout_text(self) -> str: ...
    @property
    def stderr_text(self) -> str: ...
    @property
    def stdout_bytes(self) -> bytes: ...
    @property
    def stderr_bytes(self) -> bytes: ...

class SshClient:
    async def exec(self, command: str, *, tty: bool = False) -> SshOutput: ...
    async def attach(
        self,
        *,
        term: str | None = None,
        detach_keys: str | None = None,
    ) -> int: ...
    async def sftp(self) -> SftpClient: ...
    async def close(self) -> None: ...

class SftpClient:
    async def read(self, path: str) -> bytes: ...
    async def write(self, path: str, data: bytes) -> None: ...
    async def mkdir(self, path: str) -> None: ...
    async def remove_file(self, path: str) -> None: ...
    async def remove_dir(self, path: str) -> None: ...
    async def rename(self, old_path: str, new_path: str) -> None: ...
    async def real_path(self, path: str) -> str: ...
    async def read_link(self, path: str) -> str: ...
    async def symlink(self, target: str, link_path: str) -> None: ...
    async def close(self) -> None: ...

class SshServer:
    async def serve_connection(self) -> None: ...
    def close(self) -> None: ...

class SandboxFsOps:
    async def read(self, path: str) -> bytes: ...
    async def read_text(self, path: str) -> str: ...
    async def read_stream(self, path: str) -> FsReadStream: ...
    async def write(self, path: str, data: bytes) -> None: ...
    async def write_stream(self, path: str) -> FsWriteSink: ...
    async def list(self, path: str) -> list[FsEntry]: ...
    async def mkdir(self, path: str) -> None: ...
    async def remove(self, path: str) -> None: ...
    async def remove_dir(self, path: str) -> None: ...
    async def copy(self, src: str, dst: str) -> None: ...
    async def rename(self, src: str, dst: str) -> None: ...
    async def stat(self, path: str) -> FsMetadata: ...
    async def exists(self, path: str) -> bool: ...
    async def copy_from_host(self, host_path: str, guest_path: str) -> None: ...
    async def copy_to_host(self, guest_path: str, host_path: str) -> None: ...

class FsReadStream:
    def __aiter__(self) -> AsyncIterator[bytes]: ...
    async def __anext__(self) -> bytes: ...
    async def collect(self) -> bytes: ...

class FsWriteSink:
    async def write(self, data: bytes) -> None: ...
    async def close(self) -> None: ...
    async def __aenter__(self) -> FsWriteSink: ...
    async def __aexit__(
        self, exc_type: type | None, exc_val: BaseException | None, exc_tb: Any
    ) -> bool: ...

class FsEntry:
    path: str
    kind: FsEntryKind
    size: int
    mode: int
    modified: float | None

class FsMetadata:
    kind: FsEntryKind
    size: int
    mode: int
    readonly: bool
    modified: float | None
    created: float | None

class SandboxMetrics:
    cpu_percent: float
    vcpu_time_ns: int
    memory_bytes: int
    memory_available_bytes: int | None
    memory_host_resident_bytes: int | None
    memory_limit_bytes: int
    disk_read_bytes: int
    disk_write_bytes: int
    net_rx_bytes: int
    net_tx_bytes: int
    upper_used_bytes: int | None
    upper_free_bytes: int | None
    upper_host_allocated_bytes: int | None
    uptime_ms: int
    timestamp_ms: float

class MetricsStream:
    def __aiter__(self) -> AsyncIterator[SandboxMetrics]: ...
    async def __anext__(self) -> SandboxMetrics: ...

class LogEntry:
    timestamp_ms: float
    source: LogSource
    session_id: int | None  # None for `system` entries
    cursor: str  # opaque resume token, pass back via `from_cursor`
    @property
    def data(self) -> bytes: ...
    def text(self) -> str: ...

class LogStream:
    def __aiter__(self) -> AsyncIterator[LogEntry]: ...
    async def __anext__(self) -> LogEntry: ...

class Volume:
    @staticmethod
    async def create(
        name: str,
        *,
        kind: VolumeKind = VolumeKind.DIRECTORY,
        size_mib: int | None = None,
        quota_mib: int | None = None,
        labels: dict[str, str] | None = None,
    ) -> Volume: ...
    @staticmethod
    async def get(name: str) -> VolumeHandle: ...
    @staticmethod
    async def get_default() -> VolumeHandle: ...
    @staticmethod
    async def list() -> list[VolumeHandle]: ...
    @staticmethod
    async def remove(name: str) -> None: ...
    @staticmethod
    def bind(
        path: str,
        *,
        readonly: bool = False,
        noexec: bool = False,
        nosuid: bool = False,
        nodev: bool = False,
        stat_virtualization: StatVirtualization | None = None,
        host_permissions: HostPermissions | None = None,
        uid: int | None = None,
        gid: int | None = None,
    ) -> MountConfig: ...
    @staticmethod
    def named(
        name: str,
        *,
        mode: NamedVolumeMode | None = None,
        kind: VolumeKind | None = None,
        size_mib: int | None = None,
        quota_mib: int | None = None,
        readonly: bool = False,
        noexec: bool = False,
        nosuid: bool = False,
        nodev: bool = False,
        stat_virtualization: StatVirtualization | None = None,
        host_permissions: HostPermissions | None = None,
        uid: int | None = None,
        gid: int | None = None,
    ) -> MountConfig: ...
    @staticmethod
    def owned(
        *,
        kind: VolumeKind | None = None,
        size_mib: int | None = None,
        quota_mib: int | None = None,
        readonly: bool = False,
        noexec: bool = False,
        nosuid: bool = False,
        nodev: bool = False,
        stat_virtualization: StatVirtualization | None = None,
        host_permissions: HostPermissions | None = None,
        uid: int | None = None,
        gid: int | None = None,
    ) -> MountConfig: ...
    @staticmethod
    def tmpfs(
        *,
        size_mib: int | None = None,
        readonly: bool = False,
        noexec: bool = False,
        nosuid: bool = False,
        nodev: bool = False,
    ) -> MountConfig: ...
    @staticmethod
    def disk(
        path: str,
        *,
        format: DiskImageFormat | None = None,
        fstype: str | None = None,
        readonly: bool = False,
        noexec: bool = False,
        nosuid: bool = False,
        nodev: bool = False,
    ) -> MountConfig: ...
    @property
    def name(self) -> str: ...
    @property
    def path(self) -> str: ...

class VolumeHandle:
    @property
    def name(self) -> str: ...
    @property
    def is_default(self) -> bool: ...
    @property
    def kind(self) -> VolumeKind: ...
    @property
    def quota_mib(self) -> int | None: ...
    @property
    def used_bytes(self) -> int: ...
    @property
    def capacity_bytes(self) -> int | None: ...
    @property
    def disk_format(self) -> DiskImageFormat | None: ...
    @property
    def disk_fstype(self) -> str | None: ...
    @property
    def labels(self) -> dict[str, str]: ...
    @property
    def created_at(self) -> float | None: ...
    @property
    def fs(self) -> VolumeFs: ...
    async def remove(self) -> None: ...

class VolumeFs:
    async def read(self, path: str) -> bytes: ...
    async def read_text(self, path: str) -> str: ...
    async def write(self, path: str, data: bytes) -> None: ...
    async def list(self, path: str) -> list[FsEntry]: ...
    async def mkdir(self, path: str) -> None: ...
    async def remove_file(self, path: str) -> None: ...
    async def remove_dir(self, path: str) -> None: ...
    async def copy(self, from_: str, to: str) -> None: ...
    async def rename(self, from_: str, to: str) -> None: ...
    async def stat(self, path: str) -> FsMetadata: ...
    async def exists(self, path: str) -> bool: ...

class Storage:
    """Backend-scoped observations and explicit runtime-cache cleanup."""

    @staticmethod
    async def usage() -> StorageUsage: ...
    @staticmethod
    async def prune(
        *, dry_run: bool = False, older_than_seconds: int | None = None,
    ) -> MemoryCacheReport:
        """Revalidate ownership before removing unused RAM; None applies no age filter."""
        ...

class StorageUsage:
    @property
    def images(self) -> StorageCategoryUsage: ...
    @property
    def snapshots(self) -> StorageCategoryUsage: ...
    @property
    def sandboxes(self) -> StorageCategoryUsage: ...
    @property
    def volumes(self) -> StorageCategoryUsage: ...
    @property
    def branch_memory(self) -> StorageCategoryUsage: ...
    @property
    def snapshot_memory(self) -> StorageCategoryUsage: ...
    @property
    def notes(self) -> list[str]: ...

class StorageCategoryUsage:
    @property
    def count(self) -> int | None: ...
    @property
    def in_use(self) -> int | None: ...
    @property
    def logical_bytes(self) -> int | None: ...
    @property
    def allocated_bytes(self) -> int | None: ...
    @property
    def reclaimable_logical_bytes(self) -> int | None: ...
    @property
    def items(self) -> list[StorageItemUsage]: ...
    @property
    def notes(self) -> list[str]: ...

class StorageItemUsage:
    @property
    def name(self) -> str: ...
    @property
    def path(self) -> str: ...
    @property
    def logical_bytes(self) -> int | None: ...
    @property
    def allocated_bytes(self) -> int | None: ...
    @property
    def in_use(self) -> bool | None: ...
    @property
    def reclaimable(self) -> bool | None: ...
    @property
    def reasons(self) -> list[str]: ...

class MemoryCacheEntry:
    @property
    def path(self) -> str: ...
    @property
    def kind(self) -> Literal["branch_memory", "snapshot_memory"]: ...
    @property
    def logical_bytes(self) -> int | None: ...
    @property
    def allocated_bytes(self) -> int | None: ...
    @property
    def state(self) -> Literal[
        "reclaimable", "in_use", "pending_handoff", "too_young",
        "missing_handoff_lock", "changed", "removed", "error",
    ]: ...
    @property
    def error(self) -> str | None: ...

class MemoryCacheReport:
    @property
    def dry_run(self) -> bool: ...
    @property
    def entries(self) -> list[MemoryCacheEntry]: ...
    @property
    def files_removed(self) -> int: ...
    @property
    def logical_bytes_removed(self) -> int: ...
    @property
    def physical_bytes_reclaimed(self) -> int | None: ...
    @property
    def truncated(self) -> bool: ...

class Image:
    @staticmethod
    def oci(
        reference: str,
        *,
        root_disk: RootDiskConfig | int | None = None,
        upper_size_mib: int | None = None,
    ) -> ImageSource: ...
    @staticmethod
    def bind(path: str) -> ImageSource: ...
    @staticmethod
    def disk(path: str, *, fstype: str | None = None) -> ImageSource: ...
    @staticmethod
    async def get(reference: str) -> ImageHandle: ...
    @staticmethod
    async def list() -> list[ImageHandle]: ...
    @staticmethod
    async def inspect(reference: str) -> ImageDetail: ...
    @staticmethod
    async def remove(reference: str, *, force: bool = False) -> None: ...
    @staticmethod
    async def prune() -> ImagePruneReport: ...
    @staticmethod
    async def load(input_path: str, *, tag: str | None = None) -> list[ImageHandle]: ...
    @staticmethod
    async def save(
        reference: str | Sequence[str],
        *,
        output_path: str,
        format: ImageArchiveFormat = ImageArchiveFormat.DOCKER,
    ) -> None: ...

class ImageHandle:
    @property
    def reference(self) -> str: ...
    @property
    def size_bytes(self) -> int | None: ...
    @property
    def manifest_digest(self) -> str | None: ...
    @property
    def architecture(self) -> str | None: ...
    @property
    def os(self) -> str | None: ...
    @property
    def layer_count(self) -> int: ...
    @property
    def last_used_at(self) -> float | None: ...
    @property
    def created_at(self) -> float | None: ...
    async def inspect(self) -> ImageDetail: ...
    async def remove(self, *, force: bool = False) -> None: ...

class ImageDetail:
    @property
    def handle(self) -> ImageHandle: ...
    @property
    def config(self) -> ImageConfigDetail | None: ...
    @property
    def layers(self) -> list[ImageLayerDetail]: ...

class ImageConfigDetail:
    @property
    def digest(self) -> str: ...
    @property
    def env(self) -> list[str]: ...
    @property
    def cmd(self) -> list[str] | None: ...
    @property
    def entrypoint(self) -> list[str] | None: ...
    @property
    def working_dir(self) -> str | None: ...
    @property
    def user(self) -> str | None: ...
    @property
    def labels(self) -> dict[str, Any] | None: ...
    @property
    def stop_signal(self) -> str | None: ...

class ImageLayerDetail:
    @property
    def diff_id(self) -> str: ...
    @property
    def blob_digest(self) -> str: ...
    @property
    def media_type(self) -> str | None: ...
    @property
    def compressed_size_bytes(self) -> int | None: ...
    @property
    def erofs_size_bytes(self) -> int | None: ...
    @property
    def position(self) -> int: ...

class ImagePruneReport:
    @property
    def skipped_in_use(self) -> int: ...
    @property
    def image_refs_removed(self) -> int: ...
    @property
    def manifests_removed(self) -> int: ...
    @property
    def layers_removed(self) -> int: ...
    @property
    def fsmeta_removed(self) -> int: ...
    @property
    def vmdk_removed(self) -> int: ...
    @property
    def bytes_reclaimed(self) -> int | None: ...

class ExternalMountWarning:
    @property
    def guest_path(self) -> str: ...
    @property
    def reason(self) -> str: ...
    @property
    def stale_inodes(self) -> list[int]: ...

class Snapshot:
    async def storage_usage(self) -> StorageItemUsage: ...
    @staticmethod
    async def create(
        name: str = "",
        *,
        from_sandbox: str,
        group: str | None = None,
        dest_dir: str | os.PathLike[str] | None = None,
        labels: dict[str, str] | None = None,
        force: bool = False,
        record_integrity: bool = False,
        full: bool = False,
        guest_flush: GuestFlush | None = None,
    ) -> Snapshot: ...
    @staticmethod
    async def create_archive(
        name: str,
        archive: str | os.PathLike[str],
        *,
        from_sandbox: str,
        group: str | None = None,
        labels: dict[str, str] | None = None,
        force: bool = False,
        record_integrity: bool = False,
        full: bool = False,
        plain_tar: bool = False,
        guest_flush: GuestFlush | None = None,
    ) -> SnapshotArchive: ...
    @staticmethod
    async def open(path_or_name: str) -> Snapshot: ...
    @staticmethod
    async def get(name_or_digest: str) -> SnapshotHandle: ...
    @staticmethod
    async def list() -> list[SnapshotHandle]: ...
    @staticmethod
    async def remove(path_or_name: str, *, force: bool = False) -> None: ...
    @staticmethod
    async def reindex(dir: str | os.PathLike[str] | None = None) -> int: ...
    @staticmethod
    async def save(
        name_or_path: str,
        out: str | os.PathLike[str],
        *,
        with_parents: bool = False,
        with_image: bool = False,
        plain_tar: bool = False,
        since: str | None = None,
        last_layers: int | None = None,
    ) -> None: ...
    @staticmethod
    async def load(
        archive: str | os.PathLike[str],
        *,
        dest: str | os.PathLike[str] | None = None,
        base: str | None = None,
        group: str | None = None,
        set_head: bool = False,
    ) -> SnapshotHandle: ...
    @staticmethod
    async def load_many(
        archives: Sequence[str | os.PathLike[str]],
        *,
        dest: str | os.PathLike[str] | None = None,
        base: str | None = None,
        group: str | None = None,
        set_head: bool = False,
    ) -> list[SnapshotHandle]: ...
    @staticmethod
    async def group_head(selector: str) -> dict[str, str | bool | None]: ...
    @property
    def head_update(self) -> dict[str, str | bool | None] | None: ...
    @property
    def id(self) -> str: ...
    @property
    def reference(self) -> str: ...
    @property
    def path(self) -> str:
        """Deprecated: use reference. Raises UnsupportedError for remote snapshots."""
        ...
    @property
    def reference_kind(self) -> Literal["id", "path"]: ...
    @property
    def digest(self) -> str: ...
    @property
    def size_bytes(self) -> int | None: ...
    @property
    def image_ref(self) -> str: ...
    @property
    def image_manifest_digest(self) -> str: ...
    @property
    def state_kind(self) -> SnapshotStateKind: ...
    @property
    def format(self) -> SnapshotFormat | None: ...
    @property
    def fstype(self) -> str | None: ...
    @property
    def checkpoint_id(self) -> str | None: ...
    @property
    def checkpoint_manifest_digest(self) -> str | None: ...
    @property
    def parent(self) -> str | None: ...
    @property
    def scope(self) -> SnapshotScope: ...
    @property
    def created_at(self) -> str: ...
    @property
    def labels(self) -> dict[str, str]: ...
    @property
    def source_sandbox(self) -> str | None: ...
    @staticmethod
    async def list_dir(dir: str | os.PathLike[str]) -> list[Snapshot]: ...
    async def save_to(
        self,
        out: str | os.PathLike[str],
        *,
        with_parents: bool = False,
        with_image: bool = False,
        plain_tar: bool = False,
        since: str | None = None,
        last_layers: int | None = None,
    ) -> None: ...
    def copy_to(self, output_archive_path: str | os.PathLike[str]) -> SnapshotCopyBuilder: ...
    async def verify(self) -> dict[str, Any]: ...

class SnapshotArchive:
    @property
    def id(self) -> str: ...
    @property
    def descriptor_digest(self) -> str: ...
    @property
    def path(self) -> str: ...

class SnapshotCopyBuilder:
    def labels(self, labels: dict[str, str]) -> SnapshotCopyBuilder: ...
    def record_integrity(self, enabled: bool) -> SnapshotCopyBuilder: ...
    async def save(self) -> None: ...

class SnapshotHandle:
    async def storage_usage(self) -> StorageItemUsage: ...
    @property
    def group(self) -> str | None: ...
    @property
    def head_update(self) -> dict[str, str | bool | None] | None: ...
    @property
    def id(self) -> str: ...
    @property
    def digest(self) -> str: ...
    @property
    def name(self) -> str | None: ...
    @property
    def parent_digest(self) -> str | None: ...
    @property
    def scope(self) -> SnapshotScope: ...
    @property
    def image_ref(self) -> str: ...
    @property
    def state_kind(self) -> SnapshotStateKind: ...
    @property
    def format(self) -> SnapshotFormat | None: ...
    @property
    def fstype(self) -> str | None: ...
    @property
    def checkpoint_manifest_digest(self) -> str | None: ...
    @property
    def size_bytes(self) -> int | None: ...
    @property
    def locality(self) -> str: ...
    @property
    def availability(self) -> str: ...
    @property
    def migration_state(self) -> str: ...
    @property
    def migration_error_code(self) -> str | None: ...
    @property
    def created_at(self) -> float: ...
    @property
    def reference(self) -> str: ...
    @property
    def path(self) -> str:
        """Deprecated: use reference. Raises UnsupportedError for remote snapshots."""
        ...
    @property
    def reference_kind(self) -> Literal["id", "path"]: ...
    async def open(self) -> Snapshot: ...
    async def remove(self, *, force: bool = False) -> None: ...
    async def save_to(
        self,
        out: str | os.PathLike[str],
        *,
        with_parents: bool = False,
        with_image: bool = False,
        plain_tar: bool = False,
        since: str | None = None,
        last_layers: int | None = None,
    ) -> None: ...

class PullSession:
    def cancel(self) -> None: ...
    @property
    def progress(self) -> PullProgressIter: ...
    async def result(self) -> Sandbox: ...
    async def __aenter__(self) -> PullSession: ...
    async def __aexit__(
        self, exc_type: type | None, exc_val: BaseException | None, exc_tb: Any
    ) -> bool: ...

class PullProgressIter:
    def __aiter__(self) -> AsyncIterator[PullEvent]: ...
    async def __anext__(self) -> PullEvent: ...

class PullEvent:
    event_type: PullEventType
    phase: str | None
    completed_bytes: int | None
    reference: str | None
    manifest_digest: str | None
    layer_count: int | None
    total_download_bytes: int | None
    layer_index: int | None
    digest: str | None
    diff_id: str | None
    downloaded_bytes: int | None
    total_bytes: int | None
    bytes_read: int | None

async def all_sandbox_metrics() -> dict[str, SandboxMetrics]: ...
async def install_runtime(config_json: str, options_json: str) -> str: ...
async def ensure_runtime(config_json: str, options_json: str) -> str: ...
def resolve_runtime(config_json: str) -> str: ...
def is_runtime_installed(config_json: str) -> bool: ...
def set_default_backend(
    kind: BackendKind,
    *,
    url: str | None = None,
    api_key: str | None = None,
    profile: str | None = None,
) -> None: ...
def backend_scope(
    kind: BackendKind,
    *,
    url: str | None = None,
    api_key: str | None = None,
    profile: str | None = None,
) -> Any: ...
def default_backend_kind() -> BackendKind: ...
def resolved_msb_path() -> str: ...
def resolved_cli_msb_path() -> str: ...
def set_runtime_msb_path(path: str) -> None: ...
def set_packaged_msb_path(path: str) -> None: ...
def version() -> str: ...
