Promote stable workspace product for 3.0.0
Freeze the current workspace-first surface as the stable 3.0 contract and reposition the landing docs, CLI help, and public contract around the stable workspace path after the one-shot proof. Bump the package and catalog compatibility to 3.0.0, add a dedicated workspace walkthrough tape/GIF, and mark the 3.0.0 roadmap milestone done while keeping runtime capability unchanged in this release. Validation: uv lock; UV_CACHE_DIR=.uv-cache make check; UV_CACHE_DIR=.uv-cache make dist-check; UV_CACHE_DIR=.uv-cache uv build; UV_CACHE_DIR=.uv-cache uvx --from twine twine check dist/*; built-wheel CLI smoke for pyro --help and pyro workspace --help; vhs validate plus rendered workspace-first-run.gif outside the sandbox because vhs crashes when sandboxed.
This commit is contained in:
parent
c82f4629b2
commit
f2d20ef30a
15 changed files with 255 additions and 42 deletions
BIN
docs/assets/workspace-first-run.gif
Normal file
BIN
docs/assets/workspace-first-run.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
98
docs/assets/workspace-first-run.tape
Normal file
98
docs/assets/workspace-first-run.tape
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
Output docs/assets/workspace-first-run.gif
|
||||
|
||||
Require uv
|
||||
Require python3
|
||||
|
||||
Set Shell "zsh"
|
||||
Set FontSize 18
|
||||
Set Width 1400
|
||||
Set Height 860
|
||||
Set Theme "Dracula"
|
||||
Set TypingSpeed 35ms
|
||||
Set Padding 24
|
||||
Set WindowBar Colorful
|
||||
|
||||
Hide
|
||||
Type "cd /home/thales/projects/personal/pyro"
|
||||
Enter
|
||||
Type "setopt interactivecomments"
|
||||
Enter
|
||||
Type "export UV_CACHE_DIR=.uv-cache"
|
||||
Enter
|
||||
Type "export PYRO_ENVIRONMENT_CACHE_DIR=$(mktemp -d)"
|
||||
Enter
|
||||
Type "alias pyro='uv run pyro'"
|
||||
Enter
|
||||
Type "SEED_DIR=$(mktemp -d)"
|
||||
Enter
|
||||
Type "SYNC_DIR=$(mktemp -d)"
|
||||
Enter
|
||||
Type "EXPORT_DIR=$(mktemp -d)"
|
||||
Enter
|
||||
Type 'printf "%s\n" "hello from seed" > "$SEED_DIR/note.txt"'
|
||||
Enter
|
||||
Type 'printf "%s\n" "hello from sync" > "$SYNC_DIR/note.txt"'
|
||||
Enter
|
||||
Type "pyro env pull debian:12 >/dev/null"
|
||||
Enter
|
||||
Show
|
||||
|
||||
Type "# Create a stable workspace from host content and capture its id"
|
||||
Enter
|
||||
Sleep 700ms
|
||||
Type 'pyro workspace create debian:12 --seed-path "$SEED_DIR" --json | tee /tmp/pyro-workspace.json'
|
||||
Enter
|
||||
Sleep 2200ms
|
||||
|
||||
Hide
|
||||
Type 'export WORKSPACE_ID=$(python3 -c "import json; print(json.load(open(\"/tmp/pyro-workspace.json\", encoding=\"utf-8\"))[\"workspace_id\"])")'
|
||||
Enter
|
||||
Show
|
||||
|
||||
Type "# Push a later host-side change into the same workspace"
|
||||
Enter
|
||||
Sleep 700ms
|
||||
Type 'pyro workspace sync push "$WORKSPACE_ID" "$SYNC_DIR"'
|
||||
Enter
|
||||
Sleep 1800ms
|
||||
|
||||
Type "# Run inside the live workspace"
|
||||
Enter
|
||||
Sleep 700ms
|
||||
Type 'pyro workspace exec "$WORKSPACE_ID" -- cat note.txt'
|
||||
Enter
|
||||
Sleep 2000ms
|
||||
|
||||
Type "# Capture a checkpoint, then start one long-running service"
|
||||
Enter
|
||||
Sleep 700ms
|
||||
Type 'pyro workspace snapshot create "$WORKSPACE_ID" checkpoint'
|
||||
Enter
|
||||
Sleep 1800ms
|
||||
Type 'pyro workspace service start "$WORKSPACE_ID" web --ready-file .web-ready -- sh -lc "touch .web-ready && while true; do sleep 60; done"'
|
||||
Enter
|
||||
Sleep 2200ms
|
||||
|
||||
Type "# Reset the full sandbox back to that checkpoint"
|
||||
Enter
|
||||
Sleep 700ms
|
||||
Type 'pyro workspace reset "$WORKSPACE_ID" --snapshot checkpoint'
|
||||
Enter
|
||||
Sleep 2200ms
|
||||
|
||||
Type "# Export one file back to the host and inspect it locally"
|
||||
Enter
|
||||
Sleep 700ms
|
||||
Type 'pyro workspace export "$WORKSPACE_ID" note.txt --output "$EXPORT_DIR/note.txt"'
|
||||
Enter
|
||||
Sleep 1800ms
|
||||
Type 'cat "$EXPORT_DIR/note.txt"'
|
||||
Enter
|
||||
Sleep 1800ms
|
||||
|
||||
Type "# Remove the workspace when the loop is done"
|
||||
Enter
|
||||
Sleep 700ms
|
||||
Type 'pyro workspace delete "$WORKSPACE_ID"'
|
||||
Enter
|
||||
Sleep 2000ms
|
||||
|
|
@ -22,7 +22,7 @@ Networking: tun=yes ip_forward=yes
|
|||
|
||||
```bash
|
||||
$ uvx --from pyro-mcp pyro env list
|
||||
Catalog version: 2.10.0
|
||||
Catalog version: 3.0.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.
|
||||
|
|
@ -66,7 +66,25 @@ The guest command output and the `[run] ...` summary are written to different st
|
|||
may appear in either order in terminals or capture tools. Use `--json` if you need a
|
||||
deterministic structured result.
|
||||
|
||||
## 5. Optional next steps
|
||||
## 5. Continue into the stable workspace path
|
||||
|
||||
The commands below use the published-package form. The same stable workspace path works with an
|
||||
installed `pyro` binary by dropping the `uvx --from pyro-mcp` prefix, or with `uv run pyro` from
|
||||
a source checkout.
|
||||
|
||||
```bash
|
||||
$ uvx --from pyro-mcp pyro workspace create debian:12 --seed-path ./repo --json | tee /tmp/pyro-workspace.json
|
||||
$ export WORKSPACE_ID="$(python -c 'import json,sys; print(json.load(sys.stdin)["workspace_id"])' < /tmp/pyro-workspace.json)"
|
||||
$ uvx --from pyro-mcp pyro workspace sync push "$WORKSPACE_ID" ./changes
|
||||
$ uvx --from pyro-mcp pyro workspace exec "$WORKSPACE_ID" -- cat note.txt
|
||||
$ uvx --from pyro-mcp pyro workspace snapshot create "$WORKSPACE_ID" checkpoint
|
||||
$ uvx --from pyro-mcp pyro workspace service start "$WORKSPACE_ID" web --ready-file .web-ready -- sh -lc 'touch .web-ready && while true; do sleep 60; done'
|
||||
$ uvx --from pyro-mcp pyro workspace reset "$WORKSPACE_ID" --snapshot checkpoint
|
||||
$ uvx --from pyro-mcp pyro workspace export "$WORKSPACE_ID" note.txt --output ./note.txt
|
||||
$ uvx --from pyro-mcp pyro workspace delete "$WORKSPACE_ID"
|
||||
```
|
||||
|
||||
## 6. Optional one-shot demo and expanded workspace flow
|
||||
|
||||
```bash
|
||||
$ uvx --from pyro-mcp pyro demo
|
||||
|
|
@ -187,7 +205,7 @@ $ uvx --from pyro-mcp pyro workspace service stop WORKSPACE_ID worker
|
|||
Use `--seed-path` when the workspace should 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 need to import later host-side changes into a started
|
||||
workspace. Sync is non-atomic in `2.10.0`; if it fails partway through, prefer `pyro workspace reset`
|
||||
workspace. Sync is non-atomic in `3.0.0`; if it fails partway through, prefer `pyro workspace reset`
|
||||
to recover from `baseline` or one named snapshot. Use `pyro workspace diff` to compare the current
|
||||
`/workspace` tree to its immutable create-time baseline, `pyro workspace snapshot *` to create
|
||||
named checkpoints, and `pyro workspace export` to copy one changed file or directory back to the
|
||||
|
|
@ -203,6 +221,10 @@ materialized at `/run/pyro-secrets/<name>`, and `--secret-env SECRET_NAME[=ENV_V
|
|||
secret into one exec, shell, or service call without storing that environment mapping on the
|
||||
workspace itself.
|
||||
|
||||
The stable workspace walkthrough GIF in the README is rendered from
|
||||
[docs/assets/workspace-first-run.tape](assets/workspace-first-run.tape) with
|
||||
[scripts/render_tape.sh](../scripts/render_tape.sh).
|
||||
|
||||
Example output:
|
||||
|
||||
```json
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ pyro run debian:12 -- git --version
|
|||
|
||||
If you are running from a repo checkout instead, replace `pyro` with `uv run pyro`.
|
||||
|
||||
After that one-shot proof works, continue into the stable workspace path with `pyro workspace ...`.
|
||||
|
||||
### 1. Check the host first
|
||||
|
||||
```bash
|
||||
|
|
@ -83,7 +85,7 @@ uvx --from pyro-mcp pyro env list
|
|||
Expected output:
|
||||
|
||||
```bash
|
||||
Catalog version: 2.10.0
|
||||
Catalog version: 3.0.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.
|
||||
|
|
@ -131,7 +133,34 @@ deterministic structured result.
|
|||
If guest execution is unavailable, the command fails unless you explicitly pass
|
||||
`--allow-host-compat`.
|
||||
|
||||
## 5. Optional demo proof point
|
||||
## 5. Continue into the stable workspace path
|
||||
|
||||
The commands below use plain `pyro ...`. Run the same flow with `uvx --from pyro-mcp pyro ...`
|
||||
for the published package, or `uv run pyro ...` from a source checkout.
|
||||
|
||||
```bash
|
||||
uv tool install pyro-mcp
|
||||
WORKSPACE_ID="$(pyro workspace create debian:12 --seed-path ./repo --json | python -c 'import json,sys; print(json.load(sys.stdin)["workspace_id"])')"
|
||||
pyro workspace sync push "$WORKSPACE_ID" ./changes
|
||||
pyro workspace exec "$WORKSPACE_ID" -- cat note.txt
|
||||
pyro workspace snapshot create "$WORKSPACE_ID" checkpoint
|
||||
pyro workspace service start "$WORKSPACE_ID" web --ready-file .web-ready -- sh -lc 'touch .web-ready && while true; do sleep 60; done'
|
||||
pyro workspace reset "$WORKSPACE_ID" --snapshot checkpoint
|
||||
pyro workspace export "$WORKSPACE_ID" note.txt --output ./note.txt
|
||||
pyro workspace delete "$WORKSPACE_ID"
|
||||
```
|
||||
|
||||
This is the stable persistent-workspace contract:
|
||||
|
||||
- `workspace create` seeds `/workspace`
|
||||
- `workspace sync push` imports later host-side changes
|
||||
- `workspace exec` and `workspace shell *` keep work inside one sandbox
|
||||
- `workspace service *` manages long-running processes with typed readiness
|
||||
- `workspace snapshot *` and `workspace reset` make reset-over-repair explicit
|
||||
- `workspace diff` compares against the immutable create-time baseline
|
||||
- `workspace export` copies results back to the host
|
||||
|
||||
## 6. Optional demo proof point
|
||||
|
||||
```bash
|
||||
uvx --from pyro-mcp pyro demo
|
||||
|
|
@ -188,7 +217,7 @@ After the CLI path works, you can move on to:
|
|||
- Python SDK: `from pyro_mcp import Pyro`
|
||||
- Demos: `pyro demo` or `pyro demo --network`
|
||||
|
||||
## Persistent Workspace
|
||||
## Stable Workspace
|
||||
|
||||
Use `pyro workspace ...` when you need repeated commands in one sandbox instead of one-shot `pyro run`.
|
||||
|
||||
|
|
@ -225,7 +254,7 @@ Workspace commands default to the persistent `/workspace` directory inside the g
|
|||
the identifier programmatically, use `--json` and read the `workspace_id` field. Use `--seed-path`
|
||||
when the workspace should start from a host directory or a local `.tar` / `.tar.gz` / `.tgz`
|
||||
archive. Use `pyro workspace sync push` for later host-side changes to a started workspace. Sync
|
||||
is non-atomic in `2.10.0`; if it fails partway through, prefer `pyro workspace reset` to recover
|
||||
is non-atomic in `3.0.0`; if it fails partway through, prefer `pyro workspace reset` to recover
|
||||
from `baseline` or one named snapshot. Use `pyro workspace diff` to compare the current workspace
|
||||
tree to its immutable create-time baseline, `pyro workspace snapshot *` to capture named
|
||||
checkpoints, and `pyro workspace export` to copy one changed file or directory back to the host. Use
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ CLI path in [install.md](install.md) or [first-run.md](first-run.md).
|
|||
|
||||
## Recommended Default
|
||||
|
||||
Use `vm_run` first for one-shot commands.
|
||||
Use `vm_run` first for one-shot commands, then move to the stable workspace surface when the
|
||||
agent needs to inhabit one sandbox across multiple calls.
|
||||
|
||||
That keeps the model-facing contract small:
|
||||
|
||||
|
|
@ -16,8 +17,8 @@ That keeps the model-facing contract small:
|
|||
- one ephemeral VM
|
||||
- automatic cleanup
|
||||
|
||||
Move to `workspace_*` only when the agent truly needs repeated commands in one workspace across
|
||||
multiple calls.
|
||||
Move to `workspace_*` when the agent needs repeated commands, shells, services, snapshots, reset,
|
||||
diff, or export in one stable workspace across multiple calls.
|
||||
|
||||
## OpenAI Responses API
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Public Contract
|
||||
|
||||
This document defines the supported public interface for `pyro-mcp` `2.x`.
|
||||
This document defines the stable public interface for `pyro-mcp` `3.x`.
|
||||
|
||||
## Package Identity
|
||||
|
||||
|
|
@ -9,6 +9,11 @@ This document defines the supported public interface for `pyro-mcp` `2.x`.
|
|||
- Public Python import: `from pyro_mcp import Pyro`
|
||||
- Public package-level factory: `from pyro_mcp import create_server`
|
||||
|
||||
Stable product framing:
|
||||
|
||||
- `pyro run` is the stable one-shot entrypoint.
|
||||
- `pyro workspace ...` is the stable persistent workspace contract.
|
||||
|
||||
## CLI Contract
|
||||
|
||||
Top-level commands:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
This roadmap turns the agent-workspace vision into release-sized milestones.
|
||||
|
||||
Current baseline is `2.10.0`:
|
||||
Current baseline is `3.0.0`:
|
||||
|
||||
- workspace persistence exists and the public surface is now workspace-first
|
||||
- host crossing currently covers create-time seeding, later sync push, and explicit export
|
||||
|
|
@ -37,16 +37,13 @@ also expected to update:
|
|||
5. [`2.8.0` Named Snapshots And Reset](task-workspace-ga/2.8.0-named-snapshots-and-reset.md) - Done
|
||||
6. [`2.9.0` Secrets](task-workspace-ga/2.9.0-secrets.md) - Done
|
||||
7. [`2.10.0` Network Policy And Host Port Publication](task-workspace-ga/2.10.0-network-policy-and-host-port-publication.md) - Done
|
||||
8. [`3.0.0` Stable Workspace Product](task-workspace-ga/3.0.0-stable-workspace-product.md)
|
||||
8. [`3.0.0` Stable Workspace Product](task-workspace-ga/3.0.0-stable-workspace-product.md) - Done
|
||||
9. [`3.1.0` Secondary Disk Tools](task-workspace-ga/3.1.0-secondary-disk-tools.md)
|
||||
|
||||
## Definition Of Done For The Roadmap
|
||||
## Remaining Follow-Up
|
||||
|
||||
The workspace product is ready to leave beta when:
|
||||
The core workspace product is now stable. The remaining planned follow-up is intentionally
|
||||
secondary:
|
||||
|
||||
- the public contract is workspace-first rather than task-first
|
||||
- an agent can inhabit a sandbox through shell, exec, service, diff, export,
|
||||
snapshot, reset, and explicit host-crossing operations
|
||||
- the main docs lead with the workspace product, not one-shot VM execution
|
||||
- the remaining deliberate deferrals are secondary disk tools rather than core
|
||||
workspace features
|
||||
- `3.1.0` secondary disk tools for offline inspection and disk-level workflows
|
||||
- no further roadmap milestone changes the stable workspace-first core contract
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
# `3.0.0` Stable Workspace Product
|
||||
|
||||
Status: Done
|
||||
|
||||
## Goal
|
||||
|
||||
Freeze the workspace-first public contract and promote the product from a
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue