Add content-only workspace read modes
Make the human workspace read commands easier to use in chat transcripts and shell pipelines by adding CLI-only --content-only to workspace file read and workspace disk read. Keep JSON, SDK, and MCP behavior unchanged while fixing the default human rendering so content without a trailing newline is cleanly separated from the summary footer. Update the 3.9.0 docs and roadmap status, and add CLI regression coverage plus a real guest-backed smoke for live and stopped-disk reads.
This commit is contained in:
parent
407c805ce2
commit
22d284b1f5
13 changed files with 314 additions and 46 deletions
|
|
@ -22,7 +22,7 @@ Networking: tun=yes ip_forward=yes
|
|||
|
||||
```bash
|
||||
$ uvx --from pyro-mcp pyro env list
|
||||
Catalog version: 3.8.0
|
||||
Catalog version: 3.9.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.
|
||||
|
|
@ -77,7 +77,7 @@ $ export WORKSPACE_ID="$(uvx --from pyro-mcp pyro workspace create debian:12 --s
|
|||
$ uvx --from pyro-mcp pyro workspace list
|
||||
$ uvx --from pyro-mcp pyro workspace update "$WORKSPACE_ID" --label owner=codex
|
||||
$ uvx --from pyro-mcp pyro workspace sync push "$WORKSPACE_ID" ./changes
|
||||
$ uvx --from pyro-mcp pyro workspace file read "$WORKSPACE_ID" note.txt
|
||||
$ uvx --from pyro-mcp pyro workspace file read "$WORKSPACE_ID" note.txt --content-only
|
||||
$ uvx --from pyro-mcp pyro workspace patch apply "$WORKSPACE_ID" --patch-file fix.patch
|
||||
$ uvx --from pyro-mcp pyro workspace exec "$WORKSPACE_ID" -- cat note.txt
|
||||
$ uvx --from pyro-mcp pyro workspace snapshot create "$WORKSPACE_ID" checkpoint
|
||||
|
|
@ -86,7 +86,7 @@ $ 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 stop "$WORKSPACE_ID"
|
||||
$ uvx --from pyro-mcp pyro workspace disk list "$WORKSPACE_ID"
|
||||
$ uvx --from pyro-mcp pyro workspace disk read "$WORKSPACE_ID" note.txt
|
||||
$ uvx --from pyro-mcp pyro workspace disk read "$WORKSPACE_ID" note.txt --content-only
|
||||
$ uvx --from pyro-mcp pyro workspace disk export "$WORKSPACE_ID" --output ./workspace.ext4
|
||||
$ uvx --from pyro-mcp pyro workspace start "$WORKSPACE_ID"
|
||||
$ uvx --from pyro-mcp pyro workspace delete "$WORKSPACE_ID"
|
||||
|
|
@ -101,7 +101,7 @@ $ uvx --from pyro-mcp pyro workspace list
|
|||
$ uvx --from pyro-mcp pyro workspace update WORKSPACE_ID --label owner=codex
|
||||
$ uvx --from pyro-mcp pyro workspace sync push WORKSPACE_ID ./changes
|
||||
$ uvx --from pyro-mcp pyro workspace file list WORKSPACE_ID src --recursive
|
||||
$ uvx --from pyro-mcp pyro workspace file read WORKSPACE_ID src/app.py
|
||||
$ uvx --from pyro-mcp pyro workspace file read WORKSPACE_ID src/app.py --content-only
|
||||
$ uvx --from pyro-mcp pyro workspace file write WORKSPACE_ID src/app.py --text-file ./app.py
|
||||
$ uvx --from pyro-mcp pyro workspace patch apply WORKSPACE_ID --patch-file fix.patch
|
||||
$ uvx --from pyro-mcp pyro workspace create debian:12 --network-policy egress
|
||||
|
|
@ -259,7 +259,7 @@ State: started
|
|||
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 `3.8.0`; if it fails partway through, prefer `pyro workspace reset`
|
||||
workspace. Sync is non-atomic in `3.9.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
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ uvx --from pyro-mcp pyro env list
|
|||
Expected output:
|
||||
|
||||
```bash
|
||||
Catalog version: 3.8.0
|
||||
Catalog version: 3.9.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.
|
||||
|
|
@ -144,7 +144,7 @@ WORKSPACE_ID="$(pyro workspace create debian:12 --seed-path ./repo --name repro-
|
|||
pyro workspace list
|
||||
pyro workspace update "$WORKSPACE_ID" --label owner=codex
|
||||
pyro workspace sync push "$WORKSPACE_ID" ./changes
|
||||
pyro workspace file read "$WORKSPACE_ID" note.txt
|
||||
pyro workspace file read "$WORKSPACE_ID" note.txt --content-only
|
||||
pyro workspace patch apply "$WORKSPACE_ID" --patch-file fix.patch
|
||||
pyro workspace exec "$WORKSPACE_ID" -- cat note.txt
|
||||
pyro workspace snapshot create "$WORKSPACE_ID" checkpoint
|
||||
|
|
@ -221,11 +221,11 @@ After the CLI path works, you can move on to:
|
|||
- live workspace updates: `pyro workspace sync push WORKSPACE_ID ./changes`
|
||||
- guest networking policy: `pyro workspace create debian:12 --network-policy egress`
|
||||
- workspace secrets: `pyro workspace create debian:12 --secret API_TOKEN=expected --secret-file PIP_TOKEN=./token.txt`
|
||||
- model-native file editing: `pyro workspace file read WORKSPACE_ID src/app.py`, `pyro workspace file write WORKSPACE_ID src/app.py --text-file ./app.py`, and `pyro workspace patch apply WORKSPACE_ID --patch-file fix.patch`
|
||||
- model-native file editing: `pyro workspace file read WORKSPACE_ID src/app.py --content-only`, `pyro workspace file write WORKSPACE_ID src/app.py --text-file ./app.py`, and `pyro workspace patch apply WORKSPACE_ID --patch-file fix.patch`
|
||||
- baseline diff: `pyro workspace diff WORKSPACE_ID`
|
||||
- snapshots and reset: `pyro workspace snapshot create WORKSPACE_ID checkpoint` and `pyro workspace reset WORKSPACE_ID --snapshot checkpoint`
|
||||
- host export: `pyro workspace export WORKSPACE_ID note.txt --output ./note.txt`
|
||||
- stopped-workspace inspection: `pyro workspace stop WORKSPACE_ID`, `pyro workspace disk list WORKSPACE_ID`, `pyro workspace disk read WORKSPACE_ID note.txt`, and `pyro workspace disk export WORKSPACE_ID --output ./workspace.ext4`
|
||||
- stopped-workspace inspection: `pyro workspace stop WORKSPACE_ID`, `pyro workspace disk list WORKSPACE_ID`, `pyro workspace disk read WORKSPACE_ID note.txt --content-only`, and `pyro workspace disk export WORKSPACE_ID --output ./workspace.ext4`
|
||||
- interactive shells: `pyro workspace shell open WORKSPACE_ID --id-only`
|
||||
- long-running services: `pyro workspace service start WORKSPACE_ID app --ready-file .ready -- sh -lc 'touch .ready && while true; do sleep 60; done'`
|
||||
- localhost-published ports: `pyro workspace create debian:12 --network-policy egress+published-ports` and `pyro workspace service start WORKSPACE_ID app --ready-http http://127.0.0.1:8080/ --publish 18080:8080 -- ./start-app`
|
||||
|
|
@ -258,7 +258,7 @@ pyro workspace create debian:12 --seed-path ./repo --secret API_TOKEN=expected
|
|||
pyro workspace create debian:12 --network-policy egress+published-ports
|
||||
pyro workspace sync push WORKSPACE_ID ./changes --dest src
|
||||
pyro workspace file list WORKSPACE_ID src --recursive
|
||||
pyro workspace file read WORKSPACE_ID src/note.txt
|
||||
pyro workspace file read WORKSPACE_ID src/note.txt --content-only
|
||||
pyro workspace file write WORKSPACE_ID src/app.py --text-file ./app.py
|
||||
pyro workspace patch apply WORKSPACE_ID --patch-file fix.patch
|
||||
pyro workspace exec WORKSPACE_ID -- cat src/note.txt
|
||||
|
|
@ -282,7 +282,7 @@ pyro workspace service stop WORKSPACE_ID web
|
|||
pyro workspace service stop WORKSPACE_ID worker
|
||||
pyro workspace stop WORKSPACE_ID
|
||||
pyro workspace disk list WORKSPACE_ID
|
||||
pyro workspace disk read WORKSPACE_ID src/note.txt
|
||||
pyro workspace disk read WORKSPACE_ID src/note.txt --content-only
|
||||
pyro workspace disk export WORKSPACE_ID --output ./workspace.ext4
|
||||
pyro workspace start WORKSPACE_ID
|
||||
pyro workspace logs WORKSPACE_ID
|
||||
|
|
@ -294,7 +294,7 @@ the identifier programmatically, use `--id-only` for only the identifier or `--j
|
|||
workspace payload. 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 `3.8.0`; if it fails partway through, prefer `pyro workspace reset` to recover
|
||||
is non-atomic in `3.9.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
|
||||
|
|
|
|||
|
|
@ -90,12 +90,12 @@ Behavioral guarantees:
|
|||
- `pyro workspace stop WORKSPACE_ID` stops one persistent workspace without deleting its `/workspace`, snapshots, or command history.
|
||||
- `pyro workspace start WORKSPACE_ID` restarts one stopped workspace without resetting `/workspace`.
|
||||
- `pyro workspace file list WORKSPACE_ID [PATH] [--recursive]` returns metadata for one live path under `/workspace`.
|
||||
- `pyro workspace file read WORKSPACE_ID PATH [--max-bytes N]` reads one regular text file under `/workspace`.
|
||||
- `pyro workspace file read WORKSPACE_ID PATH [--max-bytes N] [--content-only]` reads one regular text file under `/workspace`.
|
||||
- `pyro workspace file write WORKSPACE_ID PATH --text TEXT` and `--text-file PATH` create or replace one regular text file under `/workspace`, creating missing parent directories automatically.
|
||||
- `pyro workspace export WORKSPACE_ID PATH --output HOST_PATH` exports one file or directory from `/workspace` back to the host.
|
||||
- `pyro workspace disk export WORKSPACE_ID --output HOST_PATH` copies the stopped guest-backed workspace rootfs as raw ext4 to the host.
|
||||
- `pyro workspace disk list WORKSPACE_ID [PATH] [--recursive]` inspects a stopped guest-backed workspace rootfs offline without booting the guest.
|
||||
- `pyro workspace disk read WORKSPACE_ID PATH [--max-bytes N]` reads one regular file from a stopped guest-backed workspace rootfs offline.
|
||||
- `pyro workspace disk read WORKSPACE_ID PATH [--max-bytes N] [--content-only]` reads one regular file from a stopped guest-backed workspace rootfs offline.
|
||||
- `pyro workspace disk *` requires `state=stopped` and a guest-backed workspace; it fails on `host_compat`.
|
||||
- `pyro workspace diff WORKSPACE_ID` compares the current `/workspace` tree to the immutable create-time baseline.
|
||||
- `pyro workspace snapshot *` manages explicit named snapshots in addition to the implicit `baseline`.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ goal:
|
|||
make the core agent-workspace use cases feel trivial from a chat-driven LLM
|
||||
interface.
|
||||
|
||||
Current baseline is `3.8.0`:
|
||||
Current baseline is `3.9.0`:
|
||||
|
||||
- the stable workspace contract exists across CLI, SDK, and MCP
|
||||
- one-shot `pyro run` still exists as the narrow entrypoint
|
||||
|
|
@ -59,7 +59,7 @@ The remaining UX friction for a technically strong new user is now narrower:
|
|||
5. [`3.6.0` Use-Case Recipes And Smoke Packs](llm-chat-ergonomics/3.6.0-use-case-recipes-and-smoke-packs.md) - Done
|
||||
6. [`3.7.0` Handoff Shortcuts And File Input Sources](llm-chat-ergonomics/3.7.0-handoff-shortcuts-and-file-input-sources.md) - Done
|
||||
7. [`3.8.0` Chat-Host Onramp And Recommended Defaults](llm-chat-ergonomics/3.8.0-chat-host-onramp-and-recommended-defaults.md) - Done
|
||||
8. [`3.9.0` Content-Only Reads And Human Output Polish](llm-chat-ergonomics/3.9.0-content-only-reads-and-human-output-polish.md) - Planned
|
||||
8. [`3.9.0` Content-Only Reads And Human Output Polish](llm-chat-ergonomics/3.9.0-content-only-reads-and-human-output-polish.md) - Done
|
||||
|
||||
Completed so far:
|
||||
|
||||
|
|
@ -81,11 +81,8 @@ Completed so far:
|
|||
extraction or `$(cat ...)` expansion.
|
||||
- `3.8.0` made `workspace-core` the obvious first MCP/chat-host profile from the first help and
|
||||
docs pass while keeping `workspace-full` as the 3.x compatibility default.
|
||||
|
||||
Planned next:
|
||||
|
||||
- `3.9.0` makes human-mode file reads cleaner in terminals and chat logs, with explicit
|
||||
content-only reads where summaries would otherwise get in the way.
|
||||
- `3.9.0` added content-only workspace file and disk reads plus cleaner default human-mode
|
||||
transcript separation for files that do not end with a trailing newline.
|
||||
|
||||
## Expected Outcome
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# `3.9.0` Content-Only Reads And Human Output Polish
|
||||
|
||||
Status: Planned
|
||||
Status: Done
|
||||
|
||||
## Goal
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue