Skip to main content
An agent runs shell commands with your user’s rights. A wrong command can change files outside the workspace, read your keys, or send data to any host. The agent sandbox limits what agent commands can do. It is off by default. The sandbox works only on macOS. It covers Local and Worktree workspaces. SSH, Coder, Docker, and Devcontainer workspaces are not covered: their commands run on another machine or in a container.

Turn on the sandbox

In Settings → Agents → Agent sandbox, turn on Run agent commands in a sandbox. Commands that start after that run in the sandbox. On another operating system, or on a Mac without /usr/bin/sandbox-exec, the section shows why the sandbox is not available and you cannot turn it on. If the setting is already on there (for example in a config.json copied from a Mac), the section says so, and you can only turn it off: with the switch, or with Global or Off for a project that is On. Until then:
  • On another operating system, commands run without the sandbox.
  • On a Mac without sandbox-exec, the commands that the sandbox covers fail. Xum does not run them without the sandbox that you turned on, unless you approve one command with Run outside once (see Approve one command outside the sandbox).
To use another setting for one project, select the project in Project and click:
  • Global: the project follows the switch.
  • On: the sandbox is on for this project, also when the switch is off.
  • Off: the sandbox is off for this project, also when the switch is on.
A sub-project has the setting of its parent project, because its workspaces work in the parent’s checkout. Project lists only parent projects, and Xum ignores an agentSandbox setting of a sub-project in config.json. A multi-project workspace uses the strictest setting of its projects, because its commands can change each checkout. The sandbox is on when it is on for one of the projects. Commands can then use only the network mode, hosts, and paths that the sandbox of each project with the sandbox on allows. Host names match in any case. Paths match where they really are, so a folder that two projects name through different symlinks stays open. When the sandbox of one of the projects fails to start, commands of the workspace fail to start too. Agent tools cannot change the sandbox setting. While the setting is on, globally or for one project, the agent’s config tool cannot write Xum’s config or providers at all, also on another operating system, where commands run without the sandbox.

What commands can write

Commands in the sandbox can write only to these folders:
  • The workspace and its scratch folder.
  • Temp folders: /private/tmp and $TMPDIR. The sandbox sets $TMPDIR to the system temp folder, also when a secret sets it to another folder.
  • Tool caches: ~/.npm, ~/.cache, ~/.cargo/registry, ~/.cargo/git, ~/go/pkg/mod, ~/.gradle/caches, ~/.m2/repository, ~/Library/pnpm/store, ~/.pnpm-store, ~/Library/Caches/go-build, ~/Library/Caches/pip, ~/Library/Caches/Yarn, ~/Library/Caches/ms-playwright, ~/Library/Caches/node-gyp, and ~/Library/Developer/Xcode/DerivedData.
  • For a worktree workspace, the .git folder of the main checkout, so that commits work.
A tool cache or $TMPDIR that is a symlink stays closed, because a command could replace it with a link to another folder. Add the folder that it links to to extraWritePaths. If Xum’s home folder (~/.xum, or XUM_ROOT) is inside a folder that commands can write, such as a temp folder, a tool cache or an extraWritePaths entry, commands in the sandbox fail to start, because a command could change Xum’s own settings there. They also fail to start when the workspace or another folder that they can write is inside ~/.config/git or a global skill or plugin folder, such as a plugin checkout in ~/.agents/plugins, or inside a folder that an entry of a global skill or plugin folder links to (~/.agents/plugins/demo linking to the workspace), because Xum runs the code there outside the sandbox. They also fail to start when the workspace, or an extraWritePaths entry, is reached through a link inside another folder that commands can write, such as a checkout in /tmp that a command replaced with a link to ~/.ssh, and when the scratch folder ($XUM_SCRATCH_DIR) is a link. The same applies to Xum’s home folder, the global git config (also where XDG_CONFIG_HOME, GIT_CONFIG_GLOBAL or GIT_CONFIG_SYSTEM moves it), ~/.bunfig.toml, ~/.ssh/config, the global instruction files, the npx, uv and Bun caches below (also where Xum’s environment or the project’s secrets move them), the credential and config files below where a variable names them (such as npm’s userconfig), the global skill and plugin folders and the links in them and in the global agent folder (~/.xum/agents), the git folders that a .git or commondir file names, the links in your home folder, the files that git and ssh config include, and the .git of the workspace: Xum, git, ssh, npx, uvx, bunx and your shell use them outside the sandbox through that link, which a command could replace. So a workspace whose .git is a symlink does not work in the sandbox. They also fail to start when Xum’s environment or the project’s secrets set one of the variables below that move the global git config, a tool cache or a credential file to a relative path, such as GIT_CONFIG_GLOBAL=my.gitconfig, because git, npm, uv and Bun resolve it from the folder they run in, and Xum runs its own git in the workspace. They also fail to start when the workspace, the scratch folder or another folder that they can read is inside one of the hidden credential paths below, such as Xum’s askpass folder, because the sandbox could not hide it there. They also fail to start when the project’s secrets set HOME to a folder other than your home folder, because git, npm and the MCP servers that Xum starts outside the sandbox with those secrets read their settings there. They also fail to start when the commondir file in the git folder of the workspace’s worktree names a folder other than the main checkout’s .git, because git outside the sandbox takes the config and hooks of the folder that it names. Some files stay read-only, also inside the workspace, where they link to and in any letter case, because a command could use them to run code later outside the sandbox:
  • .git/hooks, .git/config, .git/config.worktree, .git/commondir, .git/modules (the git folders of submodules), and .git itself where it is not a folder: the .git file of a worktree, or a .git that does not exist yet, so git init fails in the sandbox. In the .git folder of the main checkout, in the git folder that a .git file names (git init --separate-git-dir), and in the folder that the commondir file of either names, the same paths, and config.worktree, modules and commondir in the folder of each worktree. Also the files that the hooks in these hooks folders link to, such as scripts/post-checkout in the workspace for a .git/hooks/post-checkout link.
  • .xum/mcp.jsonc, .mux/mcp.jsonc, .xum/mcp.local.jsonc, .mux/mcp.local.jsonc, .xum/mcp.local.json, .mux/mcp.local.json, .mcp.json, .xum/plugins, .mux/plugins, and .agents/plugins.
  • .xum/tool_env and .mux/tool_env, which bash runs before each command in a trusted project, also before a command that you let run outside the sandbox.
  • ~/.npm/_npx (or where npm_config_cache moves the npm cache), the uv cache (~/.cache/uv, or where XDG_CACHE_HOME or UV_CACHE_DIR moves it), the Bun install and transpiler caches (~/.bun/install/cache and ~/Library/Caches/bun, or where BUN_INSTALL_CACHE_DIR, BUN_INSTALL, BUN_RUNTIME_TRANSPILER_CACHE_PATH or XDG_CACHE_HOME moves them), and the bunx-<uid>-* and .bunx-<uid> folders in the temp folders. npx, uvx and bunx keep what they run there, also for MCP servers that start outside the sandbox. Commands in the sandbox can still run what is there. uv and Bun in the sandbox use caches of their own in $TMPDIR.
  • .vscode, .idea, .envrc, and .gitmodules.
  • .devcontainer.json and .devcontainer, because devcontainer up runs their initializeCommand on your Mac.
  • Where links in your home folder point into a folder that commands can write (a dotfiles checkout): the dot entries of the home folder (such as ~/.gitconfig, ~/.zshrc or ~/.npmrc), the entries of ~/.config, ~/.ssh (such as ~/.ssh/config), ~/.claude and Xum’s home folder (such as a global CLAUDE.md or AGENTS.md), and the global skill and plugin folders, because git, ssh, npx, bunx and your shell outside the sandbox run what they name, and Xum reads the global instruction files into its prompt. A link to the whole folder that commands can write, or to a folder above it, does not make that folder read-only.
  • Where an entry of a global skill, plugin or agent folder links into a folder that commands can write (a plugin linked to its checkout), the folder that it links to. Links deeper inside the entry are not followed.
  • The global and system git config, also where Xum’s environment or the project’s secrets move them (XDG_CONFIG_HOME, GIT_CONFIG_GLOBAL or GIT_CONFIG_SYSTEM), where they are in a folder that commands can write. The system config is /etc/gitconfig, the etc/gitconfig of Homebrew or MacPorts, or the defaults that Apple’s git ships with in the Command Line Tools or in /Applications/Xcode.app; a git with its system config elsewhere is not covered.
  • ~/.ssh/config, where it is in a folder that commands can write (an extraWritePaths entry for ~/.ssh), because ssh runs its ProxyCommand for Xum’s own git fetch outside the sandbox.
  • The global instruction files (~/.claude/CLAUDE.md, and AGENTS.md, AGENT.md, CLAUDE.md and AGENTS.local.md in Xum’s home folder), where they are in a folder that commands can write, because Xum reads them into the prompt of every workspace, also one without the sandbox.
  • The files that git config includes (include.path and includeIf entries, in the global and system git config, in the config of the repository that the workspace is in, also when the workspace is a folder inside it, and of its submodules, and in the files they include), and the files that ~/.ssh/config and the system /etc/ssh/ssh_config include (Include), where they are in a folder that commands can write. For an Include with a wildcard in its last name, every name in that folder that starts like the pattern stays read-only, and so does where a link among them points. Commands fail to start when an include is in a form the sandbox does not read: a partly quoted or escaped git include path, ~user/ or %(prefix)/, an Include with a token, a variable or a wildcard in a folder name, or an Include argument with a backslash or quoted in part. They also fail to start when one of these config files is larger than 1 MiB.
Commands also fail to start when one of these files, or a git or ssh config file that the sandbox reads, has more than one hard link, because a write through the other name changes the same file and the sandbox cannot keep that name read-only. Replace the hard link with a copy or a symlink. Files inside a read-only folder, such as .xum/plugins or .git/hooks, are not checked for hard links. A command in the sandbox cannot make a hard link to them, but a program outside the sandbox can. For example, pnpm with package-import-method=hardlink links the files in a plugin’s node_modules to its store, which commands can write, so a command can change them there.

What commands can read

Commands in the sandbox can read:
  • The workspace and the folders they can write.
  • System files and folders outside /Users, /Volumes and your home folder.
  • Toolchains and tool settings in your home folder: ~/.gitconfig, ~/.config/git, ~/.bun, ~/.cargo, ~/.rustup, ~/go, ~/Library/Application Support/go, ~/.nvm, ~/.volta, ~/.pyenv, ~/.asdf, ~/.local/share/mise, ~/.local/share/uv, and ~/.sdkman. A link in a folder that commands can write is not followed from one of them, because a command could point it at ~/.ssh.
  • The global git config, also where Xum’s environment or the project’s secrets move it.
  • The global skill and plugin folders.
  • The folders in your PATH that are in your home folder. Only the folder itself opens: if a tool in it needs files next to it, add them to extraReadPaths. A PATH folder that a symlink in a writable folder links to stays closed.
  • For a tool hook, the payload files that XUM_TOOL_INPUT_PATH and XUM_TOOL_RESULT_PATH name.
  • For a Cursor plugin hook, the chat log that transcript_path names. The hook starts in the workspace, so the plugin folder stays read-only, and then changes to the plugin folder.
Everything else in /Users, /Volumes, your home folder (also when it is not in /Users) and Xum’s home folder (also when XUM_ROOT moves it outside your home folder) is hidden. Some credential files stay hidden and read-only, also inside folders that are open and when you add them to extraReadPaths or extraWritePaths. Where a variable moves one, the sandbox reads it from Xum’s environment and from the project’s secrets:
  • ~/.cargo/credentials and ~/.cargo/credentials.toml (or in CARGO_HOME).
  • ~/.config/git/credentials (or where XDG_CONFIG_HOME moves it).
  • ~/.cache/huggingface/token, and stored_tokens next to it, where hf auth login keeps every token it saved (or where XDG_CACHE_HOME, HF_HOME or HF_TOKEN_PATH moves them).
  • ~/.local/share/uv/credentials (or where XDG_DATA_HOME or UV_CREDENTIALS_DIR moves it), where uv auth login keeps its tokens, so uv in the sandbox cannot use them.
  • ~/Library/Application Support/go/env (or where GOENV moves it), where go env -w keeps its settings, which can hold a password in GOPROXY. Go in the sandbox runs without them, so set what a build needs, such as GOPRIVATE or GOFLAGS, in the environment instead.
  • The npm user and global config where a variable moves them, because they can hold registry tokens: npm_config_userconfig, npm_config_globalconfig, and npm_config_prefix or PREFIX, which move the global config to <prefix>/etc/npmrc. npm reads npm_config_ in any case. Without them, ~/.npmrc is only closed (see below). The global config of a Node in an open folder, such as ~/.nvm/versions/node/<version>/etc/npmrc, stays open, so keep registry tokens in ~/.npmrc.
  • The pip config that PIP_CONFIG_FILE names. pip in the sandbox runs without it.
  • The gradle.properties in the folder that GRADLE_USER_HOME names, because it can hold repository credentials. Gradle in the sandbox runs without it.
  • The config.json in the folder that DOCKER_CONFIG names, because it can hold registry logins and proxy passwords. ~/.docker is not open either.
  • The AWS files that AWS_SHARED_CREDENTIALS_FILE and AWS_CONFIG_FILE name (also with a leading ~/), the key files that GOOGLE_APPLICATION_CREDENTIALS and AZURE_CLIENT_CERTIFICATE_PATH name, the folders that CLOUDSDK_CONFIG and AZURE_CONFIG_DIR name, the hosts.yml in the folder that GH_CONFIG_DIR names, and each file that KUBECONFIG lists, because they hold cloud keys and tokens. Their default folders in your home folder are not open either.
  • The .netrc that NETRC names, because Python and Go read logins from it.
  • The files where more tools keep tokens, where a variable moves them: the Terraform CLI config that TF_CLI_CONFIG_FILE or TERRAFORM_CONFIG names, credentials.json in PULUMI_HOME, the configs that RCLONE_CONFIG, BOTO_CONFIG, OCI_CLI_CONFIG_FILE, DATABRICKS_CONFIG_FILE, HUB_CONFIG and HELM_REGISTRY_CONFIG name, auth.json in COMPOSER_HOME, config.yml in GLAB_CONFIG_DIR, kaggle.json in KAGGLE_CONFIG_DIR, and key.pem in DOCKER_CERT_PATH.
  • The file that a variable names when its name says it holds a secret: the name ends in TOKEN, CRED, CREDS, CREDENTIAL, CREDENTIALS, PASS, PASSWORD, SECRET, SECRETS, KEY or AUTH, then _FILE, FILE, _PATH or PATH, then an optional _OVERRIDE. Examples are AWS_WEB_IDENTITY_TOKEN_FILE, CLOUDSDK_AUTH_ACCESS_TOKEN_FILE, CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE, AZURE_FEDERATED_TOKEN_FILE, PGPASSFILE, SOPS_AGE_KEY_FILE and POSTGRES_PASSWORD_FILE. Only a value that is an absolute path or starts with ~/ counts.
  • Xum’s server.lock, providers.jsonc, secrets.json, mcp-oauth.json, and config.json, and its askpass folder, where your answers to SSH prompts pass. xum run and xum workflow keep their copy of config.json, providers.jsonc and secrets.json in a temp folder, and that copy is hidden too, with the files whose names start with one of these names and a dot, such as the temp file that Xum writes before it replaces one.
Commands fail to start when one of these files has more than one hard link, because the sandbox hides and protects names, not files, so the other name would open it. These files are not open, because they can hold tokens: ~/.npmrc, ~/.bunfig.toml, ~/.pypirc, ~/.gradle/gradle.properties, and ~/.m2/settings.xml. If a build needs one of them, add it to extraReadPaths (see Open more paths). Xum reads the instruction files of the workspace, such as AGENTS.md, its agent definitions in .xum/agents and its skills in .xum/skills or .agents/skills as a command in the sandbox would, with the project’s secrets, because a command could replace one with a link to a key or to a file that a secret names. An instruction file that links to a hidden file loads as empty. An agent definition or skill that links to one does not load, so the agent or skill of that name in Xum’s home folder, or the built-in one, loads in its place. agent_skill_read_file does not read a hidden file from a workspace skill, agent_skill_write and agent_skill_delete change a file of a workspace skill only where a command in the sandbox could, and mux_agents_read and mux_agents_write read and write the workspace’s AGENTS.md only where a command in the sandbox could. workflow_run runs a workflow script of the workspace or of a workspace skill, also one that another workflow starts, only where a command in the sandbox could read it. To load a file that links into your home folder, add its target to extraReadPaths. When Xum proposes the plan of plan mode, it reads the plan file the same way. Commands cannot change the plan file, because it is in Xum’s home folder. Unix sockets are closed in all network modes, for example the sockets of Docker, ssh-agent, 1Password, and gpg-agent. The macOS keychain is closed too, and open cannot start an app, which would run outside the sandbox.

Network

Commands in the sandbox reach the network through a local proxy. In Network, select one mode:
  • Allowed hosts only (the default): commands can reach only the hosts in the list. The default list has 16 package registries and git hosts: registry.npmjs.org, registry.yarnpkg.com, pypi.org, files.pythonhosted.org, crates.io, index.crates.io, static.crates.io, proxy.golang.org, sum.golang.org, github.com, api.github.com, codeload.github.com, objects.githubusercontent.com, raw.githubusercontent.com, gitlab.com, and bitbucket.org.
  • Any host: commands can reach all hosts.
  • Loopback only: commands can reach only localhost.
To change the list, click Edit hosts, enter one host on each line, and click Save hosts. To go back to the default list, click Edit hosts, then Use defaults. A list that you edited does not change when a later version of Xum changes the default list. In all modes, loopback stays open, so dev servers and their tests work. The proxy refuses an allowed host name that resolves to a private address range. In all modes, a command can also listen on every network interface, not only on loopback, so other computers on your network can connect to a dev server that listens on 0.0.0.0 or ::. The macOS sandbox cannot limit a listener to loopback: it treats a listener on every interface as a loopback listener.

Open more paths

To let commands write or read more paths, edit ~/.xum/config.json:
A path can start with ~/. A project can have its own agentSandbox with the same fields, in its entry in projects. Each field that the project sets replaces the global field. For example, a project extraReadPaths replaces the global extraReadPaths, it does not add to it. A repository cannot set the sandbox. The agent’s config tool cannot change agentSandbox, and while the sandbox is on, it cannot write Xum’s config or providers at all. In a system workspace that the sandbox covers, the agent’s skill and AGENTS.md tools cannot change the global skills or Xum’s global AGENTS.md, because every workspace loads them. In any workspace that the sandbox covers, the memory tool cannot change global memory, because every workspace with memory loads its index. For the same reasons, the refinement rollback tool cannot undo a change to global memory or a global skill in a workspace that the sandbox covers. Xum ignores a field that is not valid and keeps the valid fields, so a broken field next to "enabled": true does not turn the sandbox off. An agentSandbox value that is not an object is ignored as a whole. Xum shows no message for this, and the next save from Settings writes the value without the broken fields.

Approve one command outside the sandbox

When the sandbox blocks a command, the bash card shows a Sandbox badge and a line that names what the sandbox blocked. The agent can then ask to run the command once outside the sandbox, with a reason. The request shows as a card with the command and the reason. Click Run outside once to run that one call without the sandbox, or Deny to refuse it. The keyboard shortcuts answer the newest card (see Keyboard shortcuts). Each approval applies to one call. Xum never remembers it. Headless xum run, xum workflow, ACP clients, and sub-agents refuse such requests at once. A sub-agent cannot ask you anything, but the agent that started it can ask to run the command. An approved call starts without BASH_ENV and without the bash functions that Xum’s environment exports (BASH_FUNC_<name>%%), as do MCP servers and the commands that Xum runs for itself while the sandbox is on for any project, because a sandboxed command can change the file that BASH_ENV names, and bash runs an exported function in place of the program it names, which can run a file in the workspace. An approved call runs /bin/bash, which macOS protects, not the first bash on your PATH, so a script that needs a newer bash can fail there; an approved background call also starts /usr/bin/nohup. The scripts that Xum runs for itself also use /bin/bash and the folders that macOS protects (/usr/bin, /bin, /usr/sbin and /sbin) in place of your PATH, because a folder in your PATH, such as an activated .venv/bin, can be in the workspace.
An approved command runs with full access to your files, keys, and network. It could read the Xum server token, answer later approval cards, or turn the sandbox off. It also runs what it finds in the workspace, which sandboxed commands can change: a script, a git hook in the workspace, a file that NODE_OPTIONS or PYTHONPATH names, or a program in a folder of your PATH that is in the workspace, such as an activated .venv/bin, which runs in place of the git or python that the command names. Approve only commands that you read and trust.

Known limits

  • Programs with a sandbox of their own, such as Chrome, Electron, Playwright, Codex, and Claude Code, cannot start it inside the agent sandbox. Start them with their no-sandbox flag. Codex and Claude Code also need their login folders in extraReadPaths.
  • Commands can read the global git config (~/.gitconfig and ~/.config/git), so that git keeps your name, settings, and aliases. A token in it, for example in http.extraHeader or in a remote URL, is readable to commands, and they can use it with an allowed host. Keep git tokens in a credential helper, such as the macOS keychain, which the sandbox closes.
  • git push over SSH fails, because the ssh-agent socket and the SSH keys are closed. gh with a stored login fails, because the keychain is closed. Approve the one push outside the sandbox.
  • A commit or git submodule update that changes the git folder of a submodule fails, because that folder is read-only. Approve the command outside the sandbox. Xum creates worktrees outside the sandbox: git worktree add and the submodule checkout after it run with your access, as they do with the sandbox off.
  • In a repository whose git folder is outside the workspace (git init --separate-git-dir), git cannot write the index, objects or refs, because commands can write .git files, so the sandbox does not open the folder that one names. Add that git folder to extraWritePaths: its hooks and config stay read-only. A linked worktree needs no entry.
  • An instruction file such as AGENTS.md, an agent definition or a project skill that links to a file in the workspace’s scratch folder ($XUM_SCRATCH_DIR) loads as empty, because Xum checks these files without the scratch folder, also outside a turn. Commands and file tools can still read the file.
  • File tools check the real path of a file and then open it. A sandboxed command that swaps a symlink between the check and the open can make a file tool read or edit a file that the sandbox hides.
  • The VS Code extension shows no approval card yet. A request to run a command outside the sandbox waits there until you stop the agent.
  • Project secrets and the bash AI proxy key are still in the environment of agent commands.
  • A file in an open folder, such as a toolchain folder or the workspace, is readable to commands, also when a variable names it as the config of a tool. The sandbox hides only the credential files listed in What commands can read. Some tools fail when they cannot read the config that a variable names (uv with UV_CONFIG_FILE), so the sandbox leaves those files as open as their folder. Keep files with tokens out of the open folders.
  • Commands can read the command line and the starting environment of your other programs that are not part of macOS, for example node or python processes, or Xum when you start xum server from a shell. macOS gives the sandbox no way to hide them. A secret in them is readable to commands: a key that your shell profile exports, or the token of xum server --auth-token or XUM_SERVER_AUTH_TOKEN, with which a command can call Xum’s API and turn the sandbox off. With the sandbox on, start xum server without a token on its command line or in its environment, so it makes its own.
  • The sandbox does not cover terminals that you open, MCP servers (they start outside the sandbox), and the Browser tab.
  • A project’s own network and allowedHosts are not a boundary between projects. While a sandboxed command of another project runs, a command can read that command’s proxy credential from its process environment and reach the hosts that the other project allows. Settings sets one network mode and host list for all projects, so this matters only when a project in config.json has its own network or allowedHosts.
  • In Allowed hosts only mode, a background process that xum run --keep-background-processes leaves running can reach only loopback after xum run exits, because the proxy to the allowed hosts runs in xum run.
  • With xum server --no-auth, a command in the sandbox can call Xum’s API on loopback like any other program on your Mac, so it can turn the sandbox off or change any other setting. Do not use --no-auth with the sandbox.
  • Commands can change the other files in the workspace. When you, your editor, or a Dev Container later runs one of them outside the sandbox, for example a script that initializeCommand names or a Dev Container config in another folder, the change runs with your full access. This includes the git hooks and config of a repository nested in the workspace, such as vendor/tool/.git: only the .git of the workspace itself stays read-only, so the next git command in the nested repository runs what they name. It also includes a hooks folder or program in the workspace that your git config or Xum’s environment names, for example with core.hooksPath, core.fsmonitor or GIT_SSH_COMMAND, and a file in the workspace that a link deeper inside a global skill or plugin entry points to, such as ~/.agents/skills/demo/scripts/run.sh.
  • Tool caches, temp folders and the workspace are writable, so a command can change a package that a program outside the sandbox runs later, for example a build in your terminal or editor, also in another project that uses the same cached package (a crate in ~/.cargo/registry, a Go module, a Maven or Gradle artifact, or a package in the pnpm store), or an MCP server that npx or bunx finds in the node_modules folder of the workspace or gets from a registry that a .npmrc, bunfig.toml or uv.toml in the workspace names. MCP servers and Xum’s own git, such as for git worktree add and the submodule checkout after it, start with your PATH, because they need npx, uvx, node or git-lfs from it. A command can change a program in a folder of your PATH that it can write, such as an activated .venv/bin, and an MCP server whose command names that program, or Xum’s own git, runs the change outside the sandbox.
  • Xum keeps the output and exit status of each background process in /private/tmp/mux-bashes, which commands can write. A command can change what another background process printed, also one of another workspace, or mark one that outlived a restart of Xum as ended, so that Xum archives its workspace while it still runs.
  • With Bun 1.4.3 or older, bunx fails in the sandbox, because it keeps what it runs in /private/tmp, where that stays read-only. Update Bun, or approve the call outside the sandbox.