Refresh docs and examples for workspaces

Rewrite the user-facing persistent sandbox story around pyro workspace ..., including the install guide, first-run transcript, integrations notes, and public contract reference.

Rename the Python example to examples/python_workspace.py and update the docs to use the new workspace create, sync, exec, status, logs, and delete flows with seed_path/workspace_id terminology.

Mark the 2.4.0 workspace-contract pivot as done in the roadmap now that the shipped CLI, SDK, MCP, docs, and tests all use the workspace-first surface.
This commit is contained in:
Thales Maciel 2026-03-12 01:22:26 -03:00
parent 48b82d8386
commit 2de31306b6
9 changed files with 148 additions and 150 deletions

View file

@ -1,6 +1,6 @@
# pyro-mcp
`pyro-mcp` runs one-shot commands and repeated task workspaces inside ephemeral Firecracker microVMs using curated Linux environments such as `debian:12`.
`pyro-mcp` runs one-shot commands and repeated workspaces inside ephemeral Firecracker microVMs using curated Linux environments such as `debian:12`.
[![PyPI version](https://img.shields.io/pypi/v/pyro-mcp.svg)](https://pypi.org/project/pyro-mcp/)
@ -16,10 +16,11 @@ It exposes the same runtime in three public forms:
- Install: [docs/install.md](docs/install.md)
- Vision: [docs/vision.md](docs/vision.md)
- Workspace roadmap: [docs/roadmap/task-workspace-ga.md](docs/roadmap/task-workspace-ga.md)
- First run transcript: [docs/first-run.md](docs/first-run.md)
- Terminal walkthrough GIF: [docs/assets/first-run.gif](docs/assets/first-run.gif)
- PyPI package: [pypi.org/project/pyro-mcp](https://pypi.org/project/pyro-mcp/)
- What's new in 2.3.0: [CHANGELOG.md#230](CHANGELOG.md#230)
- What's new in 2.4.0: [CHANGELOG.md#240](CHANGELOG.md#240)
- Host requirements: [docs/host-requirements.md](docs/host-requirements.md)
- Integration targets: [docs/integrations.md](docs/integrations.md)
- Public contract: [docs/public-contract.md](docs/public-contract.md)
@ -56,7 +57,7 @@ What success looks like:
```bash
Platform: linux-x86_64
Runtime: PASS
Catalog version: 2.3.0
Catalog version: 2.4.0
...
[pull] phase=install environment=debian:12
[pull] phase=ready environment=debian:12
@ -75,8 +76,8 @@ access to `registry-1.docker.io`, and needs local cache space for the guest imag
After the quickstart works:
- prove the full one-shot lifecycle with `uvx --from pyro-mcp pyro demo`
- create a persistent workspace with `uvx --from pyro-mcp pyro task create debian:12 --source-path ./repo`
- update a live task from the host with `uvx --from pyro-mcp pyro task sync push TASK_ID ./changes`
- create a persistent workspace with `uvx --from pyro-mcp pyro workspace create debian:12 --seed-path ./repo`
- update a live workspace from the host with `uvx --from pyro-mcp pyro workspace sync push WORKSPACE_ID ./changes`
- move to Python or MCP via [docs/integrations.md](docs/integrations.md)
## Supported Hosts
@ -130,7 +131,7 @@ uvx --from pyro-mcp pyro env list
Expected output:
```bash
Catalog version: 2.2.0
Catalog version: 2.4.0
debian:12 [installed|not installed] Debian 12 environment with Git preinstalled for common agent workflows.
debian:12-base [installed|not installed] Minimal Debian 12 environment for shell and core Unix tooling.
debian:12-build [installed|not installed] Debian 12 environment with Git and common build tools preinstalled.
@ -194,36 +195,36 @@ When you are done evaluating and want to remove stale cached environments, run `
If you prefer a fuller copy-pasteable transcript, see [docs/first-run.md](docs/first-run.md).
The walkthrough GIF above was rendered from [docs/assets/first-run.tape](docs/assets/first-run.tape) using [scripts/render_tape.sh](scripts/render_tape.sh).
## Persistent Tasks
## Persistent Workspaces
Use `pyro run` for one-shot commands. Use `pyro task ...` when you need repeated commands in one
Use `pyro run` for one-shot commands. Use `pyro workspace ...` when you need repeated commands in one
workspace without recreating the sandbox every time.
The project direction is an agent workspace, not a CI job runner. Persistent
tasks are meant to let an agent stay inside one bounded sandbox across multiple
workspaces are meant to let an agent stay inside one bounded sandbox across multiple
steps. See [docs/vision.md](docs/vision.md) for the product thesis and the
longer-term interaction model.
```bash
pyro task create debian:12 --source-path ./repo
pyro task sync push TASK_ID ./changes --dest src
pyro task exec TASK_ID -- cat src/note.txt
pyro task logs TASK_ID
pyro task delete TASK_ID
pyro workspace create debian:12 --seed-path ./repo
pyro workspace sync push WORKSPACE_ID ./changes --dest src
pyro workspace exec WORKSPACE_ID -- cat src/note.txt
pyro workspace logs WORKSPACE_ID
pyro workspace delete WORKSPACE_ID
```
Task workspaces start in `/workspace` and keep command history until you delete them. For machine
consumption, add `--json` and read the returned `task_id`. Use `--source-path` when you want the
task to start from a host directory or a local `.tar` / `.tar.gz` / `.tgz` archive instead of an
empty workspace. Use `pyro task sync push` when you want to import later host-side changes into a
started task. Sync is non-atomic in `2.3.0`; if it fails partway through, delete and recreate the
task from its seed.
Persistent workspaces start in `/workspace` and keep command history until you delete them. For
machine consumption, add `--json` and read the returned `workspace_id`. Use `--seed-path` when
you want the workspace to start from a host directory or a local `.tar` / `.tar.gz` / `.tgz`
archive instead of an empty workspace. Use `pyro workspace sync push` when you want to import
later host-side changes into a started workspace. Sync is non-atomic in `2.4.0`; if it fails
partway through, delete and recreate the workspace from its seed.
## Public Interfaces
The public user-facing interface is `pyro` and `Pyro`. After the CLI validation path works, you can choose one of three surfaces:
- `pyro` for direct CLI usage, including one-shot `run` and persistent `task` workflows
- `pyro` for direct CLI usage, including one-shot `run` and persistent `workspace` workflows
- `from pyro_mcp import Pyro` for Python orchestration
- `pyro mcp serve` for MCP clients
@ -359,14 +360,14 @@ For repeated commands in one workspace:
from pyro_mcp import Pyro
pyro = Pyro()
task = pyro.create_task(environment="debian:12", source_path="./repo")
task_id = task["task_id"]
workspace = pyro.create_workspace(environment="debian:12", seed_path="./repo")
workspace_id = workspace["workspace_id"]
try:
pyro.push_task_sync(task_id, "./changes", dest="src")
result = pyro.exec_task(task_id, command="cat src/note.txt")
pyro.push_workspace_sync(workspace_id, "./changes", dest="src")
result = pyro.exec_workspace(workspace_id, command="cat src/note.txt")
print(result["stdout"], end="")
finally:
pyro.delete_task(task_id)
pyro.delete_workspace(workspace_id)
```
## MCP Tools
@ -389,18 +390,18 @@ Advanced lifecycle tools:
Persistent workspace tools:
- `task_create(environment, vcpu_count=1, mem_mib=1024, ttl_seconds=600, network=false, allow_host_compat=false, source_path=null)`
- `task_sync_push(task_id, source_path, dest="/workspace")`
- `task_exec(task_id, command, timeout_seconds=30)`
- `task_status(task_id)`
- `task_logs(task_id)`
- `task_delete(task_id)`
- `workspace_create(environment, vcpu_count=1, mem_mib=1024, ttl_seconds=600, network=false, allow_host_compat=false, seed_path=null)`
- `workspace_sync_push(workspace_id, source_path, dest="/workspace")`
- `workspace_exec(workspace_id, command, timeout_seconds=30)`
- `workspace_status(workspace_id)`
- `workspace_logs(workspace_id)`
- `workspace_delete(workspace_id)`
## Integration Examples
- Python one-shot SDK example: [examples/python_run.py](examples/python_run.py)
- Python lifecycle example: [examples/python_lifecycle.py](examples/python_lifecycle.py)
- Python task workspace example: [examples/python_task.py](examples/python_task.py)
- Python workspace example: [examples/python_workspace.py](examples/python_workspace.py)
- MCP client config example: [examples/mcp_client_config.md](examples/mcp_client_config.md)
- Claude Desktop MCP config: [examples/claude_desktop_mcp_config.json](examples/claude_desktop_mcp_config.json)
- Cursor MCP config: [examples/cursor_mcp_config.json](examples/cursor_mcp_config.json)