Repository navigation
feat(computer): Windows 11 computers, composed and deployed with cua-driver on local Docker with KVM - #525
Merged
earakely-scale merged 32 commits intoNov 7, 2026
Conversation
…s Docker (WIP) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e's Docker (WIP) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…apability Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…boots it without a pull Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ndows keeps them Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t-effort The previous commit's edit replaced an empty match and multiplied the script; this is the script before it with that change made as meant. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s evaluation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… task in the Windows bundle Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… Windows mounts Windows mounts a FAT filesystem with no partition table only on removable media, so the seed on an IDE disk never got a letter and agentenv-session never found CIDATA. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… its manifest as UTF-8 On Windows, Python reads a file in the code page by default, so the manifest's non-ASCII schema text read back differently from what the daemon lists. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ows it, its extension hidden Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ose commands fit it run_in_session and write_files default on Windows too: a command in a process group of its own with no console window, killed with its children by taskkill on a timeout. The probe runs its commands on Windows as Python one-liners that write bytes, taskkill and an account check by name and group, leaving Linux's and macOS's as they were. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…gh computer-exec Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s has Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed as Windows 11 on dwm Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… what a killed build left Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the probe reads a file's owner on Windows Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nt pipe instance The C runtime's open reports a busy pipe as EINVAL, not ERROR_PIPE_BUSY, and between one instance taken and the next made the pipe is briefly absent (ENOENT). 20 bursts of 32 concurrent clicks: none refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ent pipe, and fails soon on none Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…is a known failure on Windows Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…known failure, as gate 3 does Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, quoted commands, display size, supervision - A Windows disk whose evaluation has fewer than 7 days left is composed again, so its base is installed afresh. - A machine image is of its disk image's id, so a base installed afresh under its tag gets a machine of its own rather than the old one's. - A Windows service's command splits as Windows quotes it. - The launcher sizes a Windows guest's display from its resolution setting at each boot. - agentenv-session keeps supervising when a service can't start, saying why in its log. - Named polling intervals; an integration test of the reset task. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, as the state fixture moves the cwd Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the step's id Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…erwise before it boots Sizing the VGA from the resolution setting didn't change it: on a live boot at 1280x800, with the VGA's maximum capped there too, Windows kept the 1920x1080 it was installed at. So the launcher keeps 1920x1080, and a resolution or display of another size is refused when the env or the deploy is checked, rather than after the boot. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
earakely-scale
deleted the
edgararakelyan/fd-5311-windows-computers-compose-and-deploy
branch
November 7, 2026 14:54
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Adds Windows 11 computers.
agent-env runwith a computer env onwindows-11andcua-drivercomposes, probes and deploys a Windows desktop on a Linux machine with KVM, using local Docker. An agent drives it through cua-driver's own tools.[install.windows]says, shuts it down, and packs the result onto the base image, so every disk on a base shares one copy of it. Windows images stay on the machine that built them, the way a macOS VM bundle stays on its Mac: agent-env never pushes Windows anywhere.agentenv-session(pythonw, windowless) starts each layer's services when the session user signs in. It reads the deploy's settings from the NoCloud seed the launcher attaches.Changes
WindowsOS(os.type = "windows", version, edition, displaydwm). A Windows computer has the disk form only, on amd64 only. A disk's init issupervisordon Linux andagentenv-sessionon Windows.windows-11, with its alias.computers/disk/windows/):autounattend.xml,setup.ps1andagentenv-session.py.setup.ps1installs OpenSSH first, so a failed setup can be read back over SSH, and reports failures through asetup-failedmarker.resolutionsetting or envdisplayof any other size is refused when the env or the deploy is checked, before anything boots. On a live boot, Windows kept the size it was installed at whatever size the VGA offered, so changing it needsChangeDisplaySettingsExat sign-in, which is a follow-up.VM_KEEPkeeps the overlay across reboots and after power-off.VM_MEDIAattaches the installer ISO, booted first, and presses Enter past its prompt.VM_FILESattaches the answers as a removable FAT drive.windows_disk: installs the base, composes layers over SSH, and packs both. The composer gets a Windows disk path (_composed_windows_disk).agentenv-sessionkeeps supervising when a service can't start, and writes the reason to that service's log.boot.native_linksandfirst_nativenow take the computer's OS type into account. Local Docker with KVM bootswindows/amd64on an amd64 host. A Windows boot defaults to 4 CPUs and 8 GB.[install.windows](WindowsInstall) takes files, downloads checked by sha256, a requirements file for the layer's venv, PowerShell run scripts (run elevated) and session services. It has no apt.\\.\pipe\agentenv-cua-driver); the wire format is the same line-delimited JSON as on Linux.EINVAL) and the moment between instances.known_failures.windowsP4: cua-driver refuses a few clicks in the first burst on a just-opened window (foreground_unavailable).mcp-windows.jsonwas generated fromcua-driver mcprunning in a signed-in Windows session: 63 tools and 11 skill resources.platform.detect()reportswindows, version11and displaydwmon Windows.run_in_sessionandwrite_filesdefault on Windows too, so computer-exec and data/add work there. A command runs in a process group of its own with no console window, and a timeout kills it and its children with taskkill.test_computer_windows.py(compose, reuse, recompose once the image is gone, refusals, base rules, install models) and the launcher's build-mode tests.tst/integration/computer/windows/andwindows_test.py, behind a new capability,windows_media(the ISO is in this machine's cache). It is allowed as a skip in the slow job, so CI doesn't download 7 GB and install Windows on every PR.Not in this PR
disk.img, somodal_vmdoesn't listwindows/amd64.--windows-iso PATH. For now, put the ISO in the cache folder.discard=unmap,rotation_rate=1,Optimize-Volume -ReTrim) and thenqemu-img convertwould cut it.hello.txtas "hello". Whether the base should show them is for review.Where this differs from FD-5311's plan (for review)
SandboxProvider.windows_diskdrives this machine's Docker directly (launcher containers with KVM), so the Lume builder methods weren't lifted ontoSandboxProvider.initisagentenv-session, notlogon, and there's noaccess = "ssh"field: composing over SSH is how Windows is built, not something the artifact declares.WindowsOStakesversion(11) and a requirededition; Server 2025 isn't modelled yet.Verified
All of this ran on an EC2 c8i.4xlarge with nested KVM (agent-environments-admin, us-east-2), on this branch.
agent-env run tst/integration/computer/windows:--task probe: deploys in 25–33 s, the probe passes, and the sandbox is torn down.--task reset: the probe passes before and after a reset in place.--task notepad, Claude Code with Sonnet 5.5: the agent opens Notepad, types the line and savesDocuments\hello.txt, and the verifier reads the file back. The last two trials passed (84 s and 70 s, $1.66–$2.96 each). Three earlier trials also saved the file; my first verifier, which read Notepad's UI, missed it.tst/integration/computer/windows_test.py, run with pytest on the box: probe passed and reset passed. Notepad's agent saved the file and its verifier passed (72 s); the test's assertion named the wrong label, which I fixed afterwards. The run took 40 min, including a fresh base install of 16 min.tst/unitand the protocol's tests, on the box). CI is green.Seen and left as follow-ups:
foreground_lost).env_outcome_verifierhas no timeout. This isn't Windows-specific.🤖 Generated with Claude Code