🤖 feat: add Docker runtime support - #1458
Conversation
1ad9f0f to
88bf08f
Compare
88bf08f to
4598abc
Compare
4598abc to
b15980b
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1ad9f0f8a4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dd9adb401e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
dd9adb4 to
14e3d06
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 19ac624272
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
3bd7f75 to
3711e5b
Compare
50e986a to
4667c32
Compare
b5f3362 to
7d7841f
Compare
7d7841f to
e19965e
Compare
|
@codex review |
e19965e to
db63885
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e19965eb4d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 23f3ff184c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: abfb5d5b4a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 07a79bdcf9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Also adds runtimeAvailability mock option and DockerUnavailable story
Docker containers store plan files at /var/mux instead of ~/.mux because: - /root has 700 permissions, inaccessible to VS Code Dev Containers (non-root user) - /var/mux is world-readable by default Changes: - Add getMuxHome() to Runtime interface (Docker returns /var/mux, others ~/.mux) - Pass muxHome to getPlanFilePath() throughout the codebase - Create /var/mux/plans directory during Docker workspace creation - Change default file permissions from 600 to 644 for new files - Open parent directory for Docker deep links (VS Code limitation) - Fix case-insensitive 'no such object' error detection --- _Generated with `mux` • Model: `anthropic:claude-opus-4-5` • Thinking: `high`_
Two fixes: 1. Restore PR #1483 functionality (SSH stderr in connection failure logs) - Add stderr capture to RemoteRuntime.exec() and pass to onExitCode() - SSHRuntime uses truncateSSHError() to include actual error messages - Before: "SSH connection failed (exit code 255)" - After: "Permission denied (publickey)" 2. Fix Docker deep links for workspace roots (Codex comment) - /src was incorrectly stripped to / (container root) - Now: root-level paths like /src open as-is - File paths still open parent directory (VS Code limitation) --- _Generated with `mux` • Model: `anthropic:claude-opus-4-5` • Thinking: `high`_
- Move stderr data listener AFTER Readable.toWeb() in RemoteRuntime.ts to avoid putting stream in flowing mode prematurely (caused integration test hangs on this branch) - Add missing logComplete(-1) calls in workspaceService.ts error paths to prevent waitForInit() from blocking on promises that never resolve --- _Generated with `mux` • Model: `anthropic:claude-opus-4-5` • Thinking: `high`_
This temporarily disables the new Docker integration tests to determine whether they are causing the CI integration test hang.
The sections test fails on this branch but passes on main. Skipping temporarily to verify the Docker test hang is fixed when all tests pass.
The 'starts stopped container' test was stopping the shared SSH container, but containers started with --rm are removed on stop (not just stopped). This broke subsequent SSH/Docker tests running in parallel. Skipped until we create a dedicated container for this specific test.
The 'starts stopped container' test was stopping the shared SSH container, but containers started with --rm are removed on stop. This broke subsequent SSH/Docker tests running in parallel, leaving orphan processes that caused Jest to hang. Fix: create a dedicated throwaway container for this test, so stopping it doesn't affect the shared fixture. Clean up in finally block.
Now that the Docker ensureReady test uses a dedicated container instead of stopping the shared SSH container, all other tests can run safely.
- Fix runtime.test.ts 'creates container and deletes it': add initWorkspace() call after createWorkspace() since container creation happens in init, and set up minimal git repo with 'main' branch for bundling - Fix dockerRuntime.integration.test.ts 'Docker runtime is disabled for non-git projects': add runtimeAvailability mock since button disabled state is driven by availability API, not just empty branches - Fix DockerRuntime.deleteWorkspace() container leak (Codex P2): when force=false, track if container was running before starting it for dirty checks, and stop it before returning errors if we started it - Extract noopInitLogger constant in test to reduce duplication --- _Generated with `mux` • Model: `anthropic:claude-opus-4-5` • Thinking: `high`_
Hardcoded /tmp path would fail on Windows hosts. Use os.tmpdir() for the host-side bundle path while keeping /tmp for the container path (containers are always Linux). Aligns with forkWorkspace which already uses os.tmpdir(). --- _Generated with `mux` • Model: `anthropic:claude-opus-4-5` • Thinking: `high`_
- Set this.containerName = destContainerName after fork succeeds so subsequent initWorkspace() targets the forked container, not source - Add Docker container creation to `mux run --runtime docker` so tools can execute (previously only metadata was saved, no container) --- _Generated with `mux` • Model: `anthropic:claude-opus-4-5` • Thinking: `high`_
Use SSH agent forwarding only (matching VS Code Dev Containers behavior). Mounting ~/.ssh causes conflicts with passphrase-protected keys since the container's SSH client may try to read keys directly instead of using the forwarded agent. --- _Generated with `mux` • Model: `anthropic:claude-opus-4-5` • Thinking: `high`_
- Add credential sharing section to docs/runtime/docker.mdx - Add DocsLink to share credentials checkbox in CreationControls --- _Generated with `mux` • Model: `anthropic:claude-opus-4-5` • Thinking: `high`_
6b83b52 to
c81ed9c
Compare
Mounting ~/.gitconfig read-only prevented gh auth setup-git from writing the credential helper config. Now we copy gitconfig into the container after creation, matching VS Code Dev Containers behavior. - Remove gitconfig mount from buildCredentialArgs() - Add docker cp for gitconfig in initWorkspace() - Remove debug logs from gh auth setup-git - Update docs to reflect copy vs mount
ffac462 to
80a0cc2
Compare
Run agent workspaces in isolated Docker containers. Each workspace gets its own container with project code synced via git bundle.
Features
--runtime "docker node:20")docker exec -itensureReady())~/.gitconfigcopy, andGH_TOKENpassthroughGH_TOKENis setmux run --runtime "docker node:20"creates and initializes Docker containersRobustness
docker inspectfailures treated as errors, not missing containersos.tmpdir()for host-side bundle files (fixes Windows)Refactors
loadNodePty(),createBufferedDataHandler())Credential Sharing Details
The
shareCredentialsoption (enabled by default) provides:/run/host-services/ssh-auth.sock; Linux forwards$SSH_AUTH_SOCK~/.gitconfiginto container so git commits have correct author (copy allowsgh auth setup-gitto modify it)GH_TOKENand runsgh auth setup-gitto configure credential helperTODO
git-credential-manager,git-credential-osxkeychain) to allow HTTPS auth withoutGH_TOKENGenerated with
mux• Model:anthropic:claude-opus-4-5• Thinking:high