pyro-mcp/docs/public-contract.md
Thales Maciel 3f8293ad24 Add persistent workspace shell sessions
Let agents inhabit a workspace across separate calls instead of only submitting one-shot execs.

Add workspace shell open/read/write/signal/close across the CLI, Python SDK, and MCP server, with persisted shell records, a local PTY-backed mock implementation, and guest-agent support for real Firecracker workspaces.

Mark the 2.5.0 roadmap milestone done, refresh docs/examples and the release metadata, and verify with uv lock, UV_CACHE_DIR=.uv-cache make check, and UV_CACHE_DIR=.uv-cache make dist-check.
2026-03-12 02:31:57 -03:00

187 lines
6.9 KiB
Markdown

# Public Contract
This document defines the supported public interface for `pyro-mcp` `2.x`.
## Package Identity
- Distribution name: `pyro-mcp`
- Public executable: `pyro`
- Public Python import: `from pyro_mcp import Pyro`
- Public package-level factory: `from pyro_mcp import create_server`
## CLI Contract
Top-level commands:
- `pyro env list`
- `pyro env pull`
- `pyro env inspect`
- `pyro env prune`
- `pyro mcp serve`
- `pyro run`
- `pyro workspace create`
- `pyro workspace sync push`
- `pyro workspace exec`
- `pyro workspace shell open`
- `pyro workspace shell read`
- `pyro workspace shell write`
- `pyro workspace shell signal`
- `pyro workspace shell close`
- `pyro workspace status`
- `pyro workspace logs`
- `pyro workspace delete`
- `pyro doctor`
- `pyro demo`
- `pyro demo ollama`
Stable `pyro run` interface:
- positional environment name
- `--vcpu-count`
- `--mem-mib`
- `--timeout-seconds`
- `--ttl-seconds`
- `--network`
- `--allow-host-compat`
- `--json`
Behavioral guarantees:
- `pyro run <environment> -- <command>` defaults to `1 vCPU / 1024 MiB`.
- `pyro run` fails if guest boot or guest exec is unavailable unless `--allow-host-compat` is set.
- `pyro run`, `pyro env list`, `pyro env pull`, `pyro env inspect`, `pyro env prune`, and `pyro doctor` are human-readable by default and return structured JSON with `--json`.
- `pyro demo ollama` prints log lines plus a final summary line.
- `pyro workspace create` auto-starts a persistent workspace.
- `pyro workspace create --seed-path PATH` seeds `/workspace` from a host directory or a local `.tar` / `.tar.gz` / `.tgz` archive before the workspace is returned.
- `pyro workspace sync push WORKSPACE_ID SOURCE_PATH [--dest WORKSPACE_PATH]` imports later host-side directory or archive content into a started workspace.
- `pyro workspace exec` runs in the persistent `/workspace` for that workspace and does not auto-clean.
- `pyro workspace shell *` manages persistent PTY sessions inside a started workspace.
- `pyro workspace logs` returns persisted command history for that workspace until `pyro workspace delete`.
- Workspace create/status results expose `workspace_seed` metadata describing how `/workspace` was initialized.
## Python SDK Contract
Primary facade:
- `Pyro`
Supported public entrypoints:
- `create_server()`
- `Pyro.create_server()`
- `Pyro.list_environments()`
- `Pyro.pull_environment(environment)`
- `Pyro.inspect_environment(environment)`
- `Pyro.prune_environments()`
- `Pyro.create_vm(...)`
- `Pyro.create_workspace(...)`
- `Pyro.push_workspace_sync(workspace_id, source_path, *, dest="/workspace")`
- `Pyro.open_shell(workspace_id, *, cwd="/workspace", cols=120, rows=30)`
- `Pyro.read_shell(workspace_id, shell_id, *, cursor=0, max_chars=65536)`
- `Pyro.write_shell(workspace_id, shell_id, *, input, append_newline=True)`
- `Pyro.signal_shell(workspace_id, shell_id, *, signal_name="INT")`
- `Pyro.close_shell(workspace_id, shell_id)`
- `Pyro.start_vm(vm_id)`
- `Pyro.exec_vm(vm_id, *, command, timeout_seconds=30)`
- `Pyro.exec_workspace(workspace_id, *, command, timeout_seconds=30)`
- `Pyro.stop_vm(vm_id)`
- `Pyro.delete_vm(vm_id)`
- `Pyro.delete_workspace(workspace_id)`
- `Pyro.status_vm(vm_id)`
- `Pyro.status_workspace(workspace_id)`
- `Pyro.logs_workspace(workspace_id)`
- `Pyro.network_info_vm(vm_id)`
- `Pyro.reap_expired()`
- `Pyro.run_in_vm(...)`
Stable public method names:
- `create_server()`
- `list_environments()`
- `pull_environment(environment)`
- `inspect_environment(environment)`
- `prune_environments()`
- `create_vm(...)`
- `create_workspace(...)`
- `push_workspace_sync(workspace_id, source_path, *, dest="/workspace")`
- `open_shell(workspace_id, *, cwd="/workspace", cols=120, rows=30)`
- `read_shell(workspace_id, shell_id, *, cursor=0, max_chars=65536)`
- `write_shell(workspace_id, shell_id, *, input, append_newline=True)`
- `signal_shell(workspace_id, shell_id, *, signal_name="INT")`
- `close_shell(workspace_id, shell_id)`
- `start_vm(vm_id)`
- `exec_vm(vm_id, *, command, timeout_seconds=30)`
- `exec_workspace(workspace_id, *, command, timeout_seconds=30)`
- `stop_vm(vm_id)`
- `delete_vm(vm_id)`
- `delete_workspace(workspace_id)`
- `status_vm(vm_id)`
- `status_workspace(workspace_id)`
- `logs_workspace(workspace_id)`
- `network_info_vm(vm_id)`
- `reap_expired()`
- `run_in_vm(...)`
Behavioral defaults:
- `Pyro.create_vm(...)` and `Pyro.run_in_vm(...)` default to `vcpu_count=1` and `mem_mib=1024`.
- `Pyro.create_workspace(...)` defaults to `vcpu_count=1` and `mem_mib=1024`.
- `allow_host_compat` defaults to `False` on `create_vm(...)` and `run_in_vm(...)`.
- `allow_host_compat` defaults to `False` on `create_workspace(...)`.
- `Pyro.create_workspace(..., seed_path=...)` seeds `/workspace` from a host directory or a local `.tar` / `.tar.gz` / `.tgz` archive before the workspace is returned.
- `Pyro.push_workspace_sync(...)` imports later host-side directory or archive content into a started workspace.
- `Pyro.exec_vm(...)` runs one command and auto-cleans that VM after the exec completes.
- `Pyro.exec_workspace(...)` runs one command in the persistent workspace and leaves it alive.
- `Pyro.open_shell(...)` opens a persistent PTY shell attached to one started workspace.
- `Pyro.read_shell(...)` reads merged text output from that shell by cursor.
- `Pyro.write_shell(...)`, `Pyro.signal_shell(...)`, and `Pyro.close_shell(...)` operate on that persistent shell session.
## MCP Contract
Primary tool:
- `vm_run`
Advanced lifecycle tools:
- `vm_list_environments`
- `vm_create`
- `vm_start`
- `vm_exec`
- `vm_stop`
- `vm_delete`
- `vm_status`
- `vm_network_info`
- `vm_reap_expired`
Persistent workspace tools:
- `workspace_create`
- `workspace_sync_push`
- `workspace_exec`
- `shell_open`
- `shell_read`
- `shell_write`
- `shell_signal`
- `shell_close`
- `workspace_status`
- `workspace_logs`
- `workspace_delete`
Behavioral defaults:
- `vm_run` and `vm_create` default to `vcpu_count=1` and `mem_mib=1024`.
- `workspace_create` defaults to `vcpu_count=1` and `mem_mib=1024`.
- `vm_run` and `vm_create` expose `allow_host_compat`, which defaults to `false`.
- `workspace_create` exposes `allow_host_compat`, which defaults to `false`.
- `workspace_create` accepts optional `seed_path` and seeds `/workspace` from a host directory or a local `.tar` / `.tar.gz` / `.tgz` archive before the workspace is returned.
- `workspace_sync_push` imports later host-side directory or archive content into a started workspace, with an optional `dest` under `/workspace`.
- `vm_exec` runs one command and auto-cleans that VM after the exec completes.
- `workspace_exec` runs one command in a persistent `/workspace` and leaves the workspace alive.
- `shell_open`, `shell_read`, `shell_write`, `shell_signal`, and `shell_close` manage persistent PTY shells inside a started workspace.
## Versioning Rule
- `pyro-mcp` uses SemVer.
- Environment names are stable identifiers in the shipped catalog.
- Changing a public command name, public flag, public method name, public MCP tool name, or required request field is a breaking change.