91e75e620b
CI: cua-driver distro-compat matrix / debian:12 (glibc 2.36) (push) Has been cancelled
CI: SPDX Headers / Check SPDX headers (warn-only) (push) Has been cancelled
CD: Docs MCP Server / build (linux/amd64) (push) Has been cancelled
CD: Docs MCP Server / build (linux/arm64) (push) Has been cancelled
CD: Docs MCP Server / merge (push) Has been cancelled
CI: cua-driver distro-compat matrix / Resolve release version (push) Has been cancelled
CI: cua-driver distro-compat matrix / fedora:41 (glibc 2.40) (push) Has been cancelled
CI: cua-driver distro-compat matrix / rockylinux:9 (glibc 2.34) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:22.04 (glibc 2.35) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:24.04 (glibc 2.39) (push) Has been cancelled
CI: cua-driver distro-compat matrix / Distro compat summary (push) Has been cancelled
CI: Rust Linux unit / Rust Linux unit and compile (push) Has been cancelled
CI: Rust Windows unit / Rust Windows unit and compile (push) Has been cancelled
CI: Nix Linux Rust source / Nix / compositor build (push) Has been cancelled
CI: Nix Linux Rust source / Nix / driver package (push) Has been cancelled
CI: Nix Linux Rust source / Nix / Rust unit tests (push) Has been cancelled
58 lines
1.7 KiB
Python
58 lines
1.7 KiB
Python
"""Shell interface — run commands, backed by a Transport."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
from cua_sandbox.transport.base import Transport
|
|
|
|
|
|
@dataclass
|
|
class CommandResult:
|
|
stdout: str
|
|
stderr: str
|
|
returncode: int
|
|
|
|
@property
|
|
def success(self) -> bool:
|
|
return self.returncode == 0
|
|
|
|
|
|
class Shell:
|
|
"""Shell command execution."""
|
|
|
|
def __init__(self, transport: Transport):
|
|
self._t = transport
|
|
|
|
async def run(
|
|
self,
|
|
command: str,
|
|
timeout: int = 30,
|
|
background: bool = False,
|
|
) -> CommandResult:
|
|
"""Run a shell command and return the result.
|
|
|
|
When ``background=True``, returns immediately with ``stdout=str(pid)``
|
|
and ``returncode=0``; poll for completion via a sentinel file or by
|
|
inspecting the process list.
|
|
"""
|
|
if background:
|
|
session = await self._t.pty_create(command=command)
|
|
pid = session.get("pid") if isinstance(session, dict) else None
|
|
return CommandResult(stdout=str(pid or ""), stderr="", returncode=0)
|
|
|
|
result = await self._t.send("run_command", command=command, timeout=timeout)
|
|
if isinstance(result, dict):
|
|
rc = result.get("returncode", result.get("return_code", -1))
|
|
return CommandResult(
|
|
stdout=result.get("stdout", ""),
|
|
stderr=result.get("stderr", ""),
|
|
returncode=rc if rc is not None else 0,
|
|
)
|
|
# LocalTransport returns cua_auto.shell.CommandResult directly
|
|
return CommandResult(
|
|
stdout=getattr(result, "stdout", ""),
|
|
stderr=getattr(result, "stderr", ""),
|
|
returncode=getattr(result, "returncode", -1),
|
|
)
|