From 5a7bf7ef147278b97eb637f8313636662b3294ed Mon Sep 17 00:00:00 2001 From: Tyler Payne Date: Mon, 14 Sep 2026 15:22:31 -0400 Subject: [PATCH 1/5] Refresh release documentation and README highlights Add dated PyPI release links, update installation and platform guidance, and synchronize package documentation with the published release. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- README.md | 25 ++++++--- docs/contributor-guide/04-releasing.md | 8 ++- docs/packages/quicksand-core.md | 13 +++-- docs/under-the-hood/01-installation.md | 70 +++++++++++--------------- docs/under-the-hood/index.md | 3 +- docs/user-guide/01-installation.md | 51 ++++++++++++------- packages/quicksand-core/README.md | 13 +++-- packages/quicksand/README.md | 25 ++++++--- 8 files changed, 128 insertions(+), 80 deletions(-) diff --git a/README.md b/README.md index ad797ee..56e720d 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,15 @@ ![Quicksand](docs/banner-light.png) -Quicksand is an async Python API to launch, control, and snapshot [QEMU](https://www.qemu.org) virtual machines with a particular focus on sandboxing AI agents. Quicksand provides pre-built Linux VMs for Ubuntu and Alpine distros. It works on x86_64 and ARM64 across macOS, Linux, and Windows with no root privileges, no Docker, and no system dependencies. Just `pip install quick-sandbox`. +Quicksand is an async Python API to launch, control, and snapshot [QEMU](https://www.qemu.org) virtual machines with a particular focus on sandboxing AI agents. Quicksand provides pre-built Linux VMs for Ubuntu and Alpine distros and supports x86_64 and ARM64 across macOS, Linux, and Windows. Running sandboxes needs no root privileges or Docker; install the QEMU and image extras for a bundled runtime on supported platforms. + +## Recent releases + +- ๐Ÿš€ **2026-09-14 โ€” [quick-sandbox 0.12.0](https://pypi.org/project/quick-sandbox/0.12.0/):** Streaming `stdin`, guest-user accounts, and guest-local `flock`/SQLite locking. Includes refreshed Ubuntu and Alpine images; upgrade your images alongside the host package. +- ๐Ÿ”๏ธ **2026-09-09 โ€” [quicksand-alpine 0.9.12](https://pypi.org/project/quicksand-alpine/0.9.12/):** Rebuilt Alpine 3.23 images across the supported platforms and corrected the minimal-image package documentation. +- ๐ŸชŸ **2026-07-07 โ€” [quick-sandbox 0.11.15](https://pypi.org/project/quick-sandbox/0.11.15/):** Windows file sharing without Administrator rights. Also fixes CIFS remount hangs and adds a loopback TCP transport for the guest agent on Windows. + +See the [changelog](https://github.com/microsoft/quicksand/blob/main/CHANGELOG.md) for the full release history. ## Installation @@ -143,12 +151,15 @@ Sandbox( | Image | Type | Wheel size | Install command | What is it | |-------|------|-----------|-----------------|------------| -| `ubuntu` | Base | ~341 MB | `quicksand install ubuntu` | Ubuntu 24.04 headless | -| `alpine` | Base | ~78 MB | `quicksand install alpine` | Alpine 3.23 headless (faster boot) | -| `ubuntu-desktop` | Overlay (`ubuntu`) | ~263 MB | `quicksand install ubuntu-desktop` | Ubuntu 24.04 + Xfce4 + Firefox | -| `alpine-desktop` | Overlay (`alpine`) | ~310 MB | `quicksand install alpine-desktop` | Alpine 3.23 + Xfce4 + Chromium | -| `quicksand-agent` | Overlay (`ubuntu`) | ~304 MB | `quicksand install quicksand-agent` | Ubuntu + Python 3.12, uv, build-essential, requests, pyyaml, ddgs, markitdown | -| `quicksand-cua` | Overlay (`quicksand-agent`) | ~445 MB | `quicksand install quicksand-cua` | Agent Sandbox + Xvfb, x11vnc, noVNC, Playwright, Chromium | +| `ubuntu` | Base | ~309-357 MB | `quicksand install ubuntu` | Ubuntu 24.04 headless | +| `alpine` | Base | ~82-85 MB | `quicksand install alpine` | Alpine 3.23 headless (faster boot) | +| `ubuntu-desktop` | Overlay (`ubuntu`) | ~273-281 MB | `quicksand install ubuntu-desktop` | Ubuntu 24.04 + Xfce4 + Firefox | +| `alpine-desktop` | Overlay (`alpine`) | ~346-363 MB | `quicksand install alpine-desktop` | Alpine 3.23 + Xfce4 + Chromium | +| `quicksand-agent` | Overlay (`ubuntu`) | ~306-335 MB | `quicksand install quicksand-agent` | Ubuntu + Python 3.12, uv, build-essential, requests, pyyaml, ddgs, markitdown | +| `quicksand-cua` | Overlay (`quicksand-agent`) | ~489-500 MB | `quicksand install quicksand-cua` | Agent Sandbox + Xvfb, x11vnc, noVNC, Playwright, Chromium | + +Sizes are approximate full image-wheel downloads for the September 14, 2026 releases +and vary by architecture. Overlay sizes exclude their base images. ## Building from source diff --git a/docs/contributor-guide/04-releasing.md b/docs/contributor-guide/04-releasing.md index d527480..5a2659f 100644 --- a/docs/contributor-guide/04-releasing.md +++ b/docs/contributor-guide/04-releasing.md @@ -1,6 +1,6 @@ # Releasing -Releases are managed via the `/release` Claude Code skill. +Releases are managed by `uvr`, with the repository's `/release` skill as the workflow guide. ## Flow @@ -72,3 +72,9 @@ failure normally requires a fresh dispatch. ## Changelog Update `CHANGELOG.md` on the release branch before dispatch. Categories: Added, Changed, Deprecated, Removed, Fixed, Security. + +After publication, refresh the short **Recent releases** list before +**Installation** in the root `README.md`. Use the PyPI publication date, a +version-specific PyPI link, and one or two sentences about the release. +The `sync-readme` pre-commit hook copies the root README to +`packages/quicksand/README.md` for the package description. diff --git a/docs/packages/quicksand-core.md b/docs/packages/quicksand-core.md index 6ff4e7a..75069b1 100644 --- a/docs/packages/quicksand-core.md +++ b/docs/packages/quicksand-core.md @@ -2,7 +2,7 @@ This package provides the core implementation for the [quicksand](https://github.com/microsoft/quicksand) VM harness. -It includes the abstractions for running VMs that AI agents can interact with, including command execution, file operations, and state checkpointing. Most users should install `quicksand` instead, which includes pre-built images. +It includes the abstractions for running VMs that AI agents can interact with, including command execution, file operations, and state checkpointing. Most users should install `quick-sandbox` with QEMU and image extras instead. ## Installation @@ -15,7 +15,7 @@ pip install 'quick-sandbox[qemu,ubuntu]' For core-only (no bundled images): ```bash -pip install quick-sandbox +pip install quicksand-core ``` ## Core Exports @@ -26,6 +26,7 @@ This package exports the core building blocks: from quicksand_core import ( # Main classes Sandbox, + SandboxUser, Mount, ExecuteResult, # Save support @@ -69,6 +70,8 @@ asyncio.run(main()) - **Real VM isolation**: Hypervisor-level isolation (KVM, HVF, WHPX) - **Cross-platform**: Linux, macOS, Windows +- **Streaming commands**: Incremental stdin and output, with backpressure, EOF, and cancellation +- **Guest users**: Create/delete OS accounts and run commands with user-specific identity and home directories inside one VM - **Platform abstraction**: Automatic detection of accelerators and machine types - **Save and load**: Save VM disk state to a directory and load it on any machine - **File sharing**: CIFS mounts via `quicksand-smb` (pure-Python SMB3 server โ€” a subprocess via QEMU guestfwd on macOS/Linux, an in-process loopback TCP listener on Windows with no admin rights required) @@ -76,9 +79,13 @@ asyncio.run(main()) - io_uring disk AIO (~50% lower latency on Linux) - IOThreads for better concurrent disk I/O (all platforms) +Streaming stdin and guest-user APIs require `quicksand-ubuntu` or +`quicksand-alpine` 0.10.0 or newer, or a custom image rebuilt with the updated +guest agent. Updating the host package does not update saved guest images. + ## For Most Users -Install `quicksand` with a bundled image for zero-configuration usage: +Install `quick-sandbox` with a bundled image for zero-configuration usage: ```bash pip install 'quick-sandbox[qemu,ubuntu]' diff --git a/docs/under-the-hood/01-installation.md b/docs/under-the-hood/01-installation.md index 0397fe9..5b77893 100644 --- a/docs/under-the-hood/01-installation.md +++ b/docs/under-the-hood/01-installation.md @@ -24,9 +24,11 @@ The `-L` flag tells QEMU where to find firmware and keymap files. Without it, QE If the bundled package isn't installed, Quicksand falls back to system QEMU found on `PATH`. -### Windows ARM64 and fat wheels +### Windows ARM64 and interpreter architecture -On Windows ARM64, most users run x86_64 Python through Microsoft's transparent emulation layer. The user may not even know they're running emulated Python โ€” it's the default. This creates a conflict: +quicksand-qemu 0.5.12 packages are single-architecture wheels: `win_amd64` contains x86_64 +executables and `win_arm64` contains ARM64 executables, directly in `bin/`. +Windows ARM64 can run x86_64 Python through emulation, which affects wheel selection: | | Python arch | pip accepts | QEMU needed | |---|---|---|---| @@ -36,31 +38,15 @@ On Windows ARM64, most users run x86_64 Python through Microsoft's transparent e The third row is the problem. pip's wheel compatibility tags (PEP 425) match the Python interpreter's platform, not the hardware. An emulated x86_64 Python will only install `win_amd64` wheels โ€” but the machine needs ARM64 QEMU binaries for hardware acceleration (WHPX). -This problem is unique to Windows. Linux doesn't transparently emulate x86_64 on ARM64, and macOS users on Apple Silicon install ARM64 Python by default (Rosetta 2 exists but isn't the default Python experience). +Use native ARM64 Python on Windows ARM64 so pip selects the ARM64 QEMU and image +wheels. `quicksand install` delegates to pip; it does not override the +interpreter's platform tags. Installing a single-architecture x64 QEMU wheel +under emulated Python can produce an architecture-mismatch error at runtime. -**Our solution: fat `win_amd64` wheels.** The `win_amd64` quicksand-qemu wheel ships both x86_64 and ARM64 QEMU binaries: - -``` -quicksand_qemu/bin/ -โ”œโ”€โ”€ x86_64/ # x86_64 QEMU binaries -โ”‚ โ”œโ”€โ”€ qemu-system-x86_64.exe -โ”‚ โ”œโ”€โ”€ qemu-img.exe -โ”‚ โ””โ”€โ”€ ... -โ””โ”€โ”€ arm64/ # ARM64 QEMU binaries - โ”œโ”€โ”€ qemu-system-aarch64.exe - โ”œโ”€โ”€ qemu-img.exe - โ””โ”€โ”€ ... -``` - -At runtime, `_find_bundled_runtime()` reads the native CPU architecture from the Windows Registry (`HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\PROCESSOR_ARCHITECTURE`) โ€” this always reports the true hardware regardless of process emulation โ€” and selects the matching subdirectory. On a single-arch wheel (Linux, macOS, or `win_arm64`), binaries live directly in `bin/` with no subdirectories. - -**Build pipeline:** -1. The Windows x64 CI runner builds `win_amd64.whl` with x64 QEMU in `bin/` -2. The GitHub-hosted `windows-11-arm` runner builds `win_arm64.whl` with ARM64 QEMU in `bin/` -3. A `pre_release` hook (runs after all builds, before publishing) opens the `win_amd64` wheel, moves its binaries to `bin/x86_64/`, extracts ARM64 binaries from the `win_arm64` wheel into `bin/arm64/`, and rewrites the wheel -4. The `win_arm64` wheel ships unchanged (lean, single-arch) for the rare native ARM64 Python user - -This approach doubles the `win_amd64` wheel size (~44 MB โ†’ ~80 MB) but ensures `pip install quicksand-qemu` delivers hardware-accelerated QEMU on every Windows configuration without user intervention. +The current pipeline publishes both Windows wheels without merging them. +`_find_bundled_runtime()` still supports legacy combined wheels with +`bin/x86_64/` and `bin/arm64/` subdirectories, selecting by native hardware +architecture. That is backward compatibility, not the layout of the current release. ### Platform wheel matrix @@ -68,17 +54,19 @@ This approach doubles the `win_amd64` wheel size (~44 MB โ†’ ~80 MB) but ensures quicksand-qemu is in `_SKIP` โ€” never retagged. Each runner produces exactly one wheel. -| Runner | QEMU Binary | Wheel Tag | After `pre_release` merge | -|--------|-------------|-----------|--------------------------| -| `[linux, x64]` | qemu-system-x86_64 (Linux) | `manylinux___x86_64` | unchanged | -| `[linux, arm64]` | qemu-system-aarch64 (Linux) | `manylinux___aarch64` | unchanged | -| `[macos, arm64]` | qemu-system-aarch64 (macOS) | `macosx_11_0_arm64` | unchanged | -| `[windows, x64]` | qemu-system-x86_64.exe | `win_amd64` | โ†’ **fat**: x64 in `bin/x86_64/`, arm64 in `bin/arm64/` | -| `windows-11-arm` | qemu-system-aarch64.exe | `win_arm64` ยน | unchanged (consumed by merge into fat wheel) | +| Runner | QEMU Binary | Wheel Tag | +|--------|-------------|-----------| +| `[linux, x64]` | qemu-system-x86_64 (Linux) | `manylinux___x86_64` | +| `[linux, arm64]` | qemu-system-aarch64 (Linux) | `manylinux___aarch64` | +| `[macos, arm64]` | qemu-system-aarch64 (macOS) | `macosx_11_0_arm64` | +| `[windows, x64]` | qemu-system-x86_64.exe | `win_amd64` | +| `windows-11-arm` | qemu-system-aarch64.exe | `win_arm64` ยน | Linux manylinux versions are derived from versioned symbols in the bundled ELF binaries and libraries. They are not fixed at glibc 2.17; pip selects a wheel compatible with the host's glibc version. +The published quicksand-qemu 0.5.12 Linux wheels require glibc 2.38 or newer. +On older systems, use a compatible system QEMU instead. With quicksand-build-tools 0.6.0, custom Linux build hooks must pass the bundled binary directory as `bin_dir` to `BinaryBundler.set_platform_wheel_tag()` and @@ -89,14 +77,13 @@ applications using `Sandbox` do not need to change their build configuration. #### Image wheels (ubuntu, alpine, etc.): build runners โ†’ retag -Image wheels contain qcow2 files that are cross-platform. Retag runs only on `RETAG_RUNNERS`. +Image wheels contain architecture-specific VM data that is portable across host +operating systems. Retag runs only on `RETAG_RUNNERS`; these are the two image builders. | Runner | Builds | Retag produces | |--------|--------|----------------| -| `[linux, x64]` | `linux_x86_64` | + `macosx_10_13_x86_64`, `win_amd64` | -| `[macos, arm64]` | `macosx_11_0_arm64` | + `linux_aarch64`, `win_arm64` | -| `[linux, arm64]` | `linux_aarch64` | none (not in `RETAG_RUNNERS`) | -| `[windows, *]` | โ€” | not an image builder | +| `[linux, x64]` | `manylinux_2_17_x86_64` | + `macosx_10_13_x86_64`, `win_amd64` | +| `[macos, arm64]` | `macosx_11_0_arm64` | + `manylinux_2_17_aarch64`, `win_arm64` | #### quicksand-qemu: host โ†’ pip install @@ -107,14 +94,15 @@ Image wheels contain qcow2 files that are cross-platform. Retag runs only on `RE | macOS Intel | x86_64 | x86_64 | โ€” (no wheel) | system QEMU (Homebrew) | HVF โœ… | | macOS Apple Silicon | arm64 | arm64 | `macosx_11_0_arm64` | qemu-system-aarch64 | HVF โœ… | | macOS Rosetta | arm64 | x86_64 | โ€” (no wheel) | system QEMU (Homebrew) | TCG โŒ | -| Windows | x86_64 | x86_64 | `win_amd64` (fat) | picks `bin/x86_64/` | WHPX โœ… | -| Windows | arm64 | x86_64 (emulated) | `win_amd64` (fat) | picks `bin/arm64/` | WHPX โœ… | +| Windows | x86_64 | x86_64 | `win_amd64` | qemu-system-x86_64 | WHPX โœ… | +| Windows | arm64 | x86_64 (emulated) | `win_amd64` | architecture mismatch; use native Python | โ€” | | Windows | arm64 | arm64 (native) | `win_arm64` | qemu-system-aarch64 | WHPX โœ… | **Notes:** - **No macOS x86_64 runner** โ€” macOS Intel users fall back to system QEMU via Homebrew. - **Rosetta Python** โ€” rare; gets no bundled wheel, falls back to system QEMU with software emulation (TCG). -- **Fat wheel** โ€” only `win_amd64` is fat (~2x size). All other wheels are single-arch. +- **Acceleration** โ€” requires support in both the host and QEMU build. The table lists the preferred accelerator, not a guarantee that it is available on every host. +- **Single-architecture wheels** โ€” all current QEMU wheels contain one architecture. Large image wheels also use the term "fat", but that means they carry VM image data rather than being a small PyPI stub. ## `quicksand install ubuntu` diff --git a/docs/under-the-hood/index.md b/docs/under-the-hood/index.md index 6aabe92..a260e8a 100644 --- a/docs/under-the-hood/index.md +++ b/docs/under-the-hood/index.md @@ -494,7 +494,8 @@ quicksand install ubuntu # Ubuntu 24.04 headless quicksand install alpine # Alpine 3.23 headless quicksand install alpine-desktop # Alpine 3.23 + Xfce4 quicksand install ubuntu-desktop # Ubuntu 24.04 + Xfce4 -quicksand install all # everything (QEMU + all images + dev tools) +# QEMU + all images + dev tools +quicksand install qemu ubuntu alpine ubuntu-desktop alpine-desktop agent cua dev ``` Each image package provides: diff --git a/docs/user-guide/01-installation.md b/docs/user-guide/01-installation.md index 1cd5d96..164b7d8 100644 --- a/docs/user-guide/01-installation.md +++ b/docs/user-guide/01-installation.md @@ -8,7 +8,15 @@ pip install 'quick-sandbox[qemu,alpine,ubuntu]' ``` -This installs the core Python library, CLI, QEMU, and VM images. No native dependencies needed. +This installs the core Python library, CLI, QEMU, and image packages. On platforms +with a compatible bundled QEMU wheel, no system QEMU installation is needed. + +Large image packages are published to PyPI as small stubs. On first use, they +download the full platform-specific wheel from the +[Quicksand index](https://microsoft.github.io/quicksand/simple/). Both automatic +downloads and `quicksand install` require `pip` in that Python environment +(`uv venv --seed` when using uv). Use the CLI to fetch images before first use. Set +`QUICKSAND_AUTO_INSTALL=0` to disable automatic image downloads. To declare it as a dependency in your `pyproject.toml`: @@ -21,11 +29,12 @@ dependencies = [ ## Install QEMU and an image -Quicksand bundles its own QEMU, so no system install is needed. Use the `quicksand install` CLI to download platform-specific binaries and images. +Use the `quicksand install` CLI to download bundled QEMU binaries and images. +See [Requirements](#requirements) for platform compatibility. ```bash quicksand install qemu # Bundled QEMU (~15MB on macOS ARM64) -quicksand install ubuntu # Ubuntu 24.04 headless (~340MB) +quicksand install ubuntu # Ubuntu 24.04 headless (~309-357 MB) ``` That's enough to start using Quicksand: @@ -42,25 +51,28 @@ async with Sandbox(image="ubuntu") as sb: ### QEMU (`quicksand install qemu`) -| | macOS ARM64 | Linux ARM64 | Linux x86_64 | Windows x86_64 | -|---|---|---|---|---| -| Download | 14 MB | 15 MB | 15 MB | 43 MB | -| On disk | 58 MB | 60 MB | 53 MB | 124 MB | +| | macOS ARM64 | Linux ARM64 | Linux x86_64 | Windows x86_64 | Windows ARM64 | +|---|---|---|---|---|---| +| Download | 15 MB | 16 MB | 16 MB | 44 MB | 35 MB | ### Images -| Image | Depends on | Display | ARM64 download | ARM64 on disk | Boot p50 | Boot p95 | -|-------|------------|---------|----------------|---------------|----------|----------| -| `alpine` | โ€” | No | 73 MB | 74 MB | 0.37s | 0.45s | -| `ubuntu` | โ€” | No | 341 MB | 346 MB | 0.88s | 0.91s | -| `alpine-desktop` | `alpine` | Yes | 287 MB | 290 MB | 0.47s | 0.54s | -| `ubuntu-desktop` | `ubuntu` | Yes | 252 MB | 257 MB | 0.90s | 0.96s | -| `quicksand-agent` | `ubuntu` | No | ~304 MB | ~308 MB | 0.91s | 0.92s | -| `quicksand-cua` | `quicksand-agent` | No | ~445 MB | ~450 MB | 0.85s | 1.01s | +| Image | Depends on | Display | ARM64 download | Boot p50 | Boot p95 | +|-------|------------|---------|----------------|----------|----------| +| `alpine` | โ€” | No | 82 MB | 0.37s | 0.45s | +| `ubuntu` | โ€” | No | 357 MB | 0.88s | 0.91s | +| `alpine-desktop` | `alpine` | Yes | 346 MB | 0.47s | 0.54s | +| `ubuntu-desktop` | `ubuntu` | Yes | 273 MB | 0.90s | 0.96s | +| `quicksand-agent` | `ubuntu` | No | 306 MB | 0.91s | 0.92s | +| `quicksand-cua` | `quicksand-agent` | No | 489 MB | 0.85s | 1.01s | -Boot times measured on macOS ARM64 (Apple M3 Max, HVF) with `quicksand benchmark -n 5`. First boot is slower due to cold cache. +Download sizes are rounded decimal MB for the September 14, 2026 releases and +exclude dependencies. Boot times are historical measurements on macOS ARM64 +(Apple M3 Max, HVF) with `quicksand benchmark -n 5`, not a new benchmark of these +releases. First boot is slower due to cold cache. -`quicksand install all` installs QEMU and all images. +`quicksand install` accepts multiple names, for example +`quicksand install qemu ubuntu alpine`. Alpine is smaller and boots faster. Ubuntu has a larger package ecosystem. Desktop images are overlays on their base image and add a graphical environment for screenshot/keyboard/mouse interaction. The agent sandbox images are pre-configured agent environments with Python 3.12, browser automation tools, and common AI agent dependencies. @@ -87,6 +99,11 @@ If this prints a Linux kernel version, everything is working. - **No root/admin.** QEMU runs as a normal user process. - **No Docker.** Quicksand is not container-based (Docker is only needed for *building* new images, not running them). +Use native ARM64 Python on Windows ARM64. The current Windows QEMU wheels each +contain one architecture; emulated x86_64 Python selects the x64 wheel rather +than the ARM64 binaries needed by the host. Linux quicksand-qemu 0.5.12 wheels require +glibc 2.38 or newer; use a compatible system QEMU on older Linux distributions. + ## Using system QEMU If you already have QEMU installed, Quicksand will find it on `PATH` as a fallback. But the bundled QEMU (`quicksand install qemu`) is recommended. It's tested and includes the right firmware files. diff --git a/packages/quicksand-core/README.md b/packages/quicksand-core/README.md index 6ff4e7a..75069b1 100644 --- a/packages/quicksand-core/README.md +++ b/packages/quicksand-core/README.md @@ -2,7 +2,7 @@ This package provides the core implementation for the [quicksand](https://github.com/microsoft/quicksand) VM harness. -It includes the abstractions for running VMs that AI agents can interact with, including command execution, file operations, and state checkpointing. Most users should install `quicksand` instead, which includes pre-built images. +It includes the abstractions for running VMs that AI agents can interact with, including command execution, file operations, and state checkpointing. Most users should install `quick-sandbox` with QEMU and image extras instead. ## Installation @@ -15,7 +15,7 @@ pip install 'quick-sandbox[qemu,ubuntu]' For core-only (no bundled images): ```bash -pip install quick-sandbox +pip install quicksand-core ``` ## Core Exports @@ -26,6 +26,7 @@ This package exports the core building blocks: from quicksand_core import ( # Main classes Sandbox, + SandboxUser, Mount, ExecuteResult, # Save support @@ -69,6 +70,8 @@ asyncio.run(main()) - **Real VM isolation**: Hypervisor-level isolation (KVM, HVF, WHPX) - **Cross-platform**: Linux, macOS, Windows +- **Streaming commands**: Incremental stdin and output, with backpressure, EOF, and cancellation +- **Guest users**: Create/delete OS accounts and run commands with user-specific identity and home directories inside one VM - **Platform abstraction**: Automatic detection of accelerators and machine types - **Save and load**: Save VM disk state to a directory and load it on any machine - **File sharing**: CIFS mounts via `quicksand-smb` (pure-Python SMB3 server โ€” a subprocess via QEMU guestfwd on macOS/Linux, an in-process loopback TCP listener on Windows with no admin rights required) @@ -76,9 +79,13 @@ asyncio.run(main()) - io_uring disk AIO (~50% lower latency on Linux) - IOThreads for better concurrent disk I/O (all platforms) +Streaming stdin and guest-user APIs require `quicksand-ubuntu` or +`quicksand-alpine` 0.10.0 or newer, or a custom image rebuilt with the updated +guest agent. Updating the host package does not update saved guest images. + ## For Most Users -Install `quicksand` with a bundled image for zero-configuration usage: +Install `quick-sandbox` with a bundled image for zero-configuration usage: ```bash pip install 'quick-sandbox[qemu,ubuntu]' diff --git a/packages/quicksand/README.md b/packages/quicksand/README.md index ad797ee..56e720d 100644 --- a/packages/quicksand/README.md +++ b/packages/quicksand/README.md @@ -6,7 +6,15 @@ ![Quicksand](docs/banner-light.png) -Quicksand is an async Python API to launch, control, and snapshot [QEMU](https://www.qemu.org) virtual machines with a particular focus on sandboxing AI agents. Quicksand provides pre-built Linux VMs for Ubuntu and Alpine distros. It works on x86_64 and ARM64 across macOS, Linux, and Windows with no root privileges, no Docker, and no system dependencies. Just `pip install quick-sandbox`. +Quicksand is an async Python API to launch, control, and snapshot [QEMU](https://www.qemu.org) virtual machines with a particular focus on sandboxing AI agents. Quicksand provides pre-built Linux VMs for Ubuntu and Alpine distros and supports x86_64 and ARM64 across macOS, Linux, and Windows. Running sandboxes needs no root privileges or Docker; install the QEMU and image extras for a bundled runtime on supported platforms. + +## Recent releases + +- ๐Ÿš€ **2026-09-14 โ€” [quick-sandbox 0.12.0](https://pypi.org/project/quick-sandbox/0.12.0/):** Streaming `stdin`, guest-user accounts, and guest-local `flock`/SQLite locking. Includes refreshed Ubuntu and Alpine images; upgrade your images alongside the host package. +- ๐Ÿ”๏ธ **2026-09-09 โ€” [quicksand-alpine 0.9.12](https://pypi.org/project/quicksand-alpine/0.9.12/):** Rebuilt Alpine 3.23 images across the supported platforms and corrected the minimal-image package documentation. +- ๐ŸชŸ **2026-07-07 โ€” [quick-sandbox 0.11.15](https://pypi.org/project/quick-sandbox/0.11.15/):** Windows file sharing without Administrator rights. Also fixes CIFS remount hangs and adds a loopback TCP transport for the guest agent on Windows. + +See the [changelog](https://github.com/microsoft/quicksand/blob/main/CHANGELOG.md) for the full release history. ## Installation @@ -143,12 +151,15 @@ Sandbox( | Image | Type | Wheel size | Install command | What is it | |-------|------|-----------|-----------------|------------| -| `ubuntu` | Base | ~341 MB | `quicksand install ubuntu` | Ubuntu 24.04 headless | -| `alpine` | Base | ~78 MB | `quicksand install alpine` | Alpine 3.23 headless (faster boot) | -| `ubuntu-desktop` | Overlay (`ubuntu`) | ~263 MB | `quicksand install ubuntu-desktop` | Ubuntu 24.04 + Xfce4 + Firefox | -| `alpine-desktop` | Overlay (`alpine`) | ~310 MB | `quicksand install alpine-desktop` | Alpine 3.23 + Xfce4 + Chromium | -| `quicksand-agent` | Overlay (`ubuntu`) | ~304 MB | `quicksand install quicksand-agent` | Ubuntu + Python 3.12, uv, build-essential, requests, pyyaml, ddgs, markitdown | -| `quicksand-cua` | Overlay (`quicksand-agent`) | ~445 MB | `quicksand install quicksand-cua` | Agent Sandbox + Xvfb, x11vnc, noVNC, Playwright, Chromium | +| `ubuntu` | Base | ~309-357 MB | `quicksand install ubuntu` | Ubuntu 24.04 headless | +| `alpine` | Base | ~82-85 MB | `quicksand install alpine` | Alpine 3.23 headless (faster boot) | +| `ubuntu-desktop` | Overlay (`ubuntu`) | ~273-281 MB | `quicksand install ubuntu-desktop` | Ubuntu 24.04 + Xfce4 + Firefox | +| `alpine-desktop` | Overlay (`alpine`) | ~346-363 MB | `quicksand install alpine-desktop` | Alpine 3.23 + Xfce4 + Chromium | +| `quicksand-agent` | Overlay (`ubuntu`) | ~306-335 MB | `quicksand install quicksand-agent` | Ubuntu + Python 3.12, uv, build-essential, requests, pyyaml, ddgs, markitdown | +| `quicksand-cua` | Overlay (`quicksand-agent`) | ~489-500 MB | `quicksand install quicksand-cua` | Agent Sandbox + Xvfb, x11vnc, noVNC, Playwright, Chromium | + +Sizes are approximate full image-wheel downloads for the September 14, 2026 releases +and vary by architecture. Overlay sizes exclude their base images. ## Building from source From aadbb46a645dec37ac234e8050556044da9f9c75 Mon Sep 17 00:00:00 2001 From: Tyler Payne Date: Mon, 14 Sep 2026 15:27:27 -0400 Subject: [PATCH 2/5] Add guest-user example and changelog badge to README Replace the recent-release list with a GitHub release badge linking to the changelog, retain the guest-account usage example, and synchronize the package README. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- README.md | 28 ++++++++++++++++++-------- docs/contributor-guide/04-releasing.md | 5 ++--- packages/quicksand/README.md | 28 ++++++++++++++++++-------- 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 56e720d..921a411 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Quicksand [![PyPI](https://img.shields.io/pypi/v/quick-sandbox)](https://pypi.org/project/quick-sandbox/) +[![Changelog](https://img.shields.io/github/v/release/microsoft/quicksand?label=changelog&logo=github)](https://github.com/microsoft/quicksand/blob/main/CHANGELOG.md) [![Docs](https://img.shields.io/badge/docs-quicksand-blue)](https://microsoft.github.io/quicksand/) [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE) @@ -8,14 +9,6 @@ Quicksand is an async Python API to launch, control, and snapshot [QEMU](https://www.qemu.org) virtual machines with a particular focus on sandboxing AI agents. Quicksand provides pre-built Linux VMs for Ubuntu and Alpine distros and supports x86_64 and ARM64 across macOS, Linux, and Windows. Running sandboxes needs no root privileges or Docker; install the QEMU and image extras for a bundled runtime on supported platforms. -## Recent releases - -- ๐Ÿš€ **2026-09-14 โ€” [quick-sandbox 0.12.0](https://pypi.org/project/quick-sandbox/0.12.0/):** Streaming `stdin`, guest-user accounts, and guest-local `flock`/SQLite locking. Includes refreshed Ubuntu and Alpine images; upgrade your images alongside the host package. -- ๐Ÿ”๏ธ **2026-09-09 โ€” [quicksand-alpine 0.9.12](https://pypi.org/project/quicksand-alpine/0.9.12/):** Rebuilt Alpine 3.23 images across the supported platforms and corrected the minimal-image package documentation. -- ๐ŸชŸ **2026-07-07 โ€” [quick-sandbox 0.11.15](https://pypi.org/project/quick-sandbox/0.11.15/):** Windows file sharing without Administrator rights. Also fixes CIFS remount hangs and adds a loopback TCP transport for the guest agent on Windows. - -See the [changelog](https://github.com/microsoft/quicksand/blob/main/CHANGELOG.md) for the full release history. - ## Installation ```bash @@ -52,6 +45,25 @@ result = await sb.execute("apt update && apt install -y python3") print(result.stdout, result.exit_code) ``` +### Create guest users + +Give workloads their own Linux accounts and home directories inside one VM. +Commands run with the user's identity and default to their home directory. + +```python +async with Sandbox(image="ubuntu") as sb: + alice = await sb.create_user("alice") + await alice.execute("cat > hello.txt", stdin="Hello from Alice!\n") + + result = await alice.execute("whoami && pwd && cat hello.txt") + print(result.stdout) + + await sb.delete_user("alice") # Also removes the user's home directory +``` + +Users share one VM, not separate VM isolation boundaries. Requires Ubuntu or +Alpine image packages 0.10.0 or newer, or a custom image with the updated guest agent. + ### Mount host directories Share host directories into the VM at boot or on the fly. diff --git a/docs/contributor-guide/04-releasing.md b/docs/contributor-guide/04-releasing.md index 5a2659f..403d6a9 100644 --- a/docs/contributor-guide/04-releasing.md +++ b/docs/contributor-guide/04-releasing.md @@ -73,8 +73,7 @@ failure normally requires a fresh dispatch. Update `CHANGELOG.md` on the release branch before dispatch. Categories: Added, Changed, Deprecated, Removed, Fixed, Security. -After publication, refresh the short **Recent releases** list before -**Installation** in the root `README.md`. Use the PyPI publication date, a -version-specific PyPI link, and one or two sentences about the release. +The root README's GitHub release badge links to the changelog and updates its +version automatically after publication. The `sync-readme` pre-commit hook copies the root README to `packages/quicksand/README.md` for the package description. diff --git a/packages/quicksand/README.md b/packages/quicksand/README.md index 56e720d..921a411 100644 --- a/packages/quicksand/README.md +++ b/packages/quicksand/README.md @@ -1,6 +1,7 @@ # Quicksand [![PyPI](https://img.shields.io/pypi/v/quick-sandbox)](https://pypi.org/project/quick-sandbox/) +[![Changelog](https://img.shields.io/github/v/release/microsoft/quicksand?label=changelog&logo=github)](https://github.com/microsoft/quicksand/blob/main/CHANGELOG.md) [![Docs](https://img.shields.io/badge/docs-quicksand-blue)](https://microsoft.github.io/quicksand/) [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE) @@ -8,14 +9,6 @@ Quicksand is an async Python API to launch, control, and snapshot [QEMU](https://www.qemu.org) virtual machines with a particular focus on sandboxing AI agents. Quicksand provides pre-built Linux VMs for Ubuntu and Alpine distros and supports x86_64 and ARM64 across macOS, Linux, and Windows. Running sandboxes needs no root privileges or Docker; install the QEMU and image extras for a bundled runtime on supported platforms. -## Recent releases - -- ๐Ÿš€ **2026-09-14 โ€” [quick-sandbox 0.12.0](https://pypi.org/project/quick-sandbox/0.12.0/):** Streaming `stdin`, guest-user accounts, and guest-local `flock`/SQLite locking. Includes refreshed Ubuntu and Alpine images; upgrade your images alongside the host package. -- ๐Ÿ”๏ธ **2026-09-09 โ€” [quicksand-alpine 0.9.12](https://pypi.org/project/quicksand-alpine/0.9.12/):** Rebuilt Alpine 3.23 images across the supported platforms and corrected the minimal-image package documentation. -- ๐ŸชŸ **2026-07-07 โ€” [quick-sandbox 0.11.15](https://pypi.org/project/quick-sandbox/0.11.15/):** Windows file sharing without Administrator rights. Also fixes CIFS remount hangs and adds a loopback TCP transport for the guest agent on Windows. - -See the [changelog](https://github.com/microsoft/quicksand/blob/main/CHANGELOG.md) for the full release history. - ## Installation ```bash @@ -52,6 +45,25 @@ result = await sb.execute("apt update && apt install -y python3") print(result.stdout, result.exit_code) ``` +### Create guest users + +Give workloads their own Linux accounts and home directories inside one VM. +Commands run with the user's identity and default to their home directory. + +```python +async with Sandbox(image="ubuntu") as sb: + alice = await sb.create_user("alice") + await alice.execute("cat > hello.txt", stdin="Hello from Alice!\n") + + result = await alice.execute("whoami && pwd && cat hello.txt") + print(result.stdout) + + await sb.delete_user("alice") # Also removes the user's home directory +``` + +Users share one VM, not separate VM isolation boundaries. Requires Ubuntu or +Alpine image packages 0.10.0 or newer, or a custom image with the updated guest agent. + ### Mount host directories Share host directories into the VM at boot or on the fly. From 271381a739960024bcbfe9d5a3a0c2da35e65410 Mon Sep 17 00:00:00 2001 From: Tyler Payne Date: Mon, 14 Sep 2026 15:34:01 -0400 Subject: [PATCH 3/5] Refine and relocate the multiple Linux users example Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- README.md | 37 ++++++++++++++++++------------------ packages/quicksand/README.md | 37 ++++++++++++++++++------------------ 2 files changed, 36 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 921a411..bf17b86 100644 --- a/README.md +++ b/README.md @@ -45,25 +45,6 @@ result = await sb.execute("apt update && apt install -y python3") print(result.stdout, result.exit_code) ``` -### Create guest users - -Give workloads their own Linux accounts and home directories inside one VM. -Commands run with the user's identity and default to their home directory. - -```python -async with Sandbox(image="ubuntu") as sb: - alice = await sb.create_user("alice") - await alice.execute("cat > hello.txt", stdin="Hello from Alice!\n") - - result = await alice.execute("whoami && pwd && cat hello.txt") - print(result.stdout) - - await sb.delete_user("alice") # Also removes the user's home directory -``` - -Users share one VM, not separate VM isolation boundaries. Requires Ubuntu or -Alpine image packages 0.10.0 or newer, or a custom image with the updated guest agent. - ### Mount host directories Share host directories into the VM at boot or on the fly. @@ -95,6 +76,24 @@ async with Sandbox( ... ``` +### Multiple linux users + +Give multiple agents independent linux user accounts in a single sandbox VM. + +```python +async with Sandbox(image="ubuntu") as sb: + alice = await sb.create_user("alice") + await alice.execute("cat > hello.txt", stdin="Hello from Alice!\n") + + result = await alice.execute("whoami && pwd && cat hello.txt") + print(result.stdout) + + await sb.delete_user("alice") # Also removes the user's home directory +``` + +Users share one VM, not separate VM isolation boundaries. Requires Ubuntu or +Alpine image packages 0.10.0 or newer, or a custom image with the updated guest agent. + ### Save and load Save the VM's disk state to a directory. Load it later, even on a different machine. diff --git a/packages/quicksand/README.md b/packages/quicksand/README.md index 921a411..bf17b86 100644 --- a/packages/quicksand/README.md +++ b/packages/quicksand/README.md @@ -45,25 +45,6 @@ result = await sb.execute("apt update && apt install -y python3") print(result.stdout, result.exit_code) ``` -### Create guest users - -Give workloads their own Linux accounts and home directories inside one VM. -Commands run with the user's identity and default to their home directory. - -```python -async with Sandbox(image="ubuntu") as sb: - alice = await sb.create_user("alice") - await alice.execute("cat > hello.txt", stdin="Hello from Alice!\n") - - result = await alice.execute("whoami && pwd && cat hello.txt") - print(result.stdout) - - await sb.delete_user("alice") # Also removes the user's home directory -``` - -Users share one VM, not separate VM isolation boundaries. Requires Ubuntu or -Alpine image packages 0.10.0 or newer, or a custom image with the updated guest agent. - ### Mount host directories Share host directories into the VM at boot or on the fly. @@ -95,6 +76,24 @@ async with Sandbox( ... ``` +### Multiple linux users + +Give multiple agents independent linux user accounts in a single sandbox VM. + +```python +async with Sandbox(image="ubuntu") as sb: + alice = await sb.create_user("alice") + await alice.execute("cat > hello.txt", stdin="Hello from Alice!\n") + + result = await alice.execute("whoami && pwd && cat hello.txt") + print(result.stdout) + + await sb.delete_user("alice") # Also removes the user's home directory +``` + +Users share one VM, not separate VM isolation boundaries. Requires Ubuntu or +Alpine image packages 0.10.0 or newer, or a custom image with the updated guest agent. + ### Save and load Save the VM's disk state to a directory. Load it later, even on a different machine. From 5b358f819df587bd690b21383119e42b186cdf40 Mon Sep 17 00:00:00 2001 From: Tyler Payne Date: Mon, 14 Sep 2026 15:37:12 -0400 Subject: [PATCH 4/5] Demonstrate multiple guest users in README Show Alice and Bob using separate home-directory files in one VM and remove the extra paragraph after the example. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- README.md | 14 +++++++------- packages/quicksand/README.md | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index bf17b86..0ad471b 100644 --- a/README.md +++ b/README.md @@ -83,17 +83,17 @@ Give multiple agents independent linux user accounts in a single sandbox VM. ```python async with Sandbox(image="ubuntu") as sb: alice = await sb.create_user("alice") - await alice.execute("cat > hello.txt", stdin="Hello from Alice!\n") + bob = await sb.create_user("bob") - result = await alice.execute("whoami && pwd && cat hello.txt") - print(result.stdout) + await alice.execute("cat > hello.txt", stdin="Hello from Alice!\n") + await bob.execute("cat > hello.txt", stdin="Hello from Bob!\n") - await sb.delete_user("alice") # Also removes the user's home directory + for user in (alice, bob): + result = await user.execute("whoami && pwd && cat hello.txt") + print(result.stdout) + await sb.delete_user(user.name) ``` -Users share one VM, not separate VM isolation boundaries. Requires Ubuntu or -Alpine image packages 0.10.0 or newer, or a custom image with the updated guest agent. - ### Save and load Save the VM's disk state to a directory. Load it later, even on a different machine. diff --git a/packages/quicksand/README.md b/packages/quicksand/README.md index bf17b86..0ad471b 100644 --- a/packages/quicksand/README.md +++ b/packages/quicksand/README.md @@ -83,17 +83,17 @@ Give multiple agents independent linux user accounts in a single sandbox VM. ```python async with Sandbox(image="ubuntu") as sb: alice = await sb.create_user("alice") - await alice.execute("cat > hello.txt", stdin="Hello from Alice!\n") + bob = await sb.create_user("bob") - result = await alice.execute("whoami && pwd && cat hello.txt") - print(result.stdout) + await alice.execute("cat > hello.txt", stdin="Hello from Alice!\n") + await bob.execute("cat > hello.txt", stdin="Hello from Bob!\n") - await sb.delete_user("alice") # Also removes the user's home directory + for user in (alice, bob): + result = await user.execute("whoami && pwd && cat hello.txt") + print(result.stdout) + await sb.delete_user(user.name) ``` -Users share one VM, not separate VM isolation boundaries. Requires Ubuntu or -Alpine image packages 0.10.0 or newer, or a custom image with the updated guest agent. - ### Save and load Save the VM's disk state to a directory. Load it later, even on a different machine. From a321d6d44f4901bc072c8f706900826d2fd9aad8 Mon Sep 17 00:00:00 2001 From: Tyler Payne Date: Mon, 14 Sep 2026 15:38:55 -0400 Subject: [PATCH 5/5] Capitalize Linux in the multi-user README section Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- README.md | 4 ++-- packages/quicksand/README.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0ad471b..9a9da12 100644 --- a/README.md +++ b/README.md @@ -76,9 +76,9 @@ async with Sandbox( ... ``` -### Multiple linux users +### Multiple Linux users -Give multiple agents independent linux user accounts in a single sandbox VM. +Give multiple agents independent Linux user accounts in a single sandbox VM. ```python async with Sandbox(image="ubuntu") as sb: diff --git a/packages/quicksand/README.md b/packages/quicksand/README.md index 0ad471b..9a9da12 100644 --- a/packages/quicksand/README.md +++ b/packages/quicksand/README.md @@ -76,9 +76,9 @@ async with Sandbox( ... ``` -### Multiple linux users +### Multiple Linux users -Give multiple agents independent linux user accounts in a single sandbox VM. +Give multiple agents independent Linux user accounts in a single sandbox VM. ```python async with Sandbox(image="ubuntu") as sb: