{ bubblewrap, coreutils, lib, pi-coding-agent, python3, runCommand, symlinkJoin, writeShellScriptBin, }: let # Patch away the new distracting block-art logo. We're patching dist/ # rather than src to avoid downloading >600MB of npm-deps. pi-coding-agent-patched = runCommand "${pi-coding-agent.name}-no-logo" { } '' cp -a ${pi-coding-agent} "$out" chmod -R u+w "$out" substituteInPlace "$out/lib/node_modules/pi-monorepo/dist/modes/interactive/components/pi-logo.js" \ --replace-fail 'return !isAppleTerminalSession();' 'return false;' \ --replace-fail 'return `''${foregroundAnsi(CORAL, mode)}P''${RESET}''${foregroundAnsi(YELLOW, mode)}i''${RESET}`;' \ 'return theme.bold(theme.fg("accent", "pi"));' substituteInPlace "$out/lib/node_modules/pi-monorepo/dist/bundle/chunks/chunk-66G7ITPS.js" \ --replace-fail 'function supportsPiLogo(){return!isAppleTerminalSession()}' \ 'function supportsPiLogo(){return false}' \ --replace-fail 'function piWordmark(){let mode=theme.getColorMode();return`''${foregroundAnsi(CORAL,mode)}P''${RESET}''${foregroundAnsi(YELLOW,mode)}i''${RESET}`}' \ 'function piWordmark(){return theme.bold(theme.fg("accent","pi"))}' substituteInPlace "$out/bin/pi" "$out/bin/.pi-wrapped" \ --replace-fail '${pi-coding-agent}' "$out" ''; sbox = writeShellScriptBin "sbox" '' set -euo pipefail ${coreutils}/bin/mkdir -p /tmp/pi "$HOME/.local/share/cargo-pi" bwrap_args=( --die-with-parent --unshare-pid --unshare-uts --unshare-cgroup --tmpfs / --dev /dev --proc /proc --bind /tmp/pi /tmp --ro-bind /etc /etc --bind /nix/store /nix/store --ro-bind /usr/bin/env /usr/bin/env --setenv NIX_REMOTE daemon --bind-try /nix/var/nix/daemon-socket /nix/var/nix/daemon-socket --dir /run --ro-bind-try /run/current-system /run/current-system --ro-bind /doc /doc --ro-bind "$HOME/.config/git" "$HOME/.config/git" --ro-bind "$HOME/.config/jj" "$HOME/.config/jj" --ro-bind "$HOME/repos/config" "$HOME/repos/config" # jj must be able to write to ~/.config/jj/repos: https://github.com/jj-vcs/jj/issues/8841 --overlay-src "$HOME/.config/jj" --tmp-overlay "$HOME/.config/jj" --setenv CARGO_HOME "$HOME/.local/share/cargo" --bind "$HOME/.local/share/cargo-pi" "$HOME/.local/share/cargo" ) exec ${bubblewrap}/bin/bwrap "''${bwrap_args[@]}" "$@" ''; pi = writeShellScriptBin "pi" '' set -euo pipefail physical_pwd="$(${coreutils}/bin/pwd -P)" exec ${sbox}/bin/sbox \ --setenv PATH "${lib.makeBinPath [ python3 ]}:$PATH" \ --setenv PI_CODING_AGENT_DIR "$HOME/.config/pi" \ --bind "$HOME/.config/pi" "$HOME/.config/pi" \ --bind "$physical_pwd" "$physical_pwd" \ --chdir "$physical_pwd" \ ${pi-coding-agent-patched}/bin/pi \ --append-system-prompt "You're running in a sandbox with an ephemeral root filesystem and a separate PID namespace. The current working directory and a few configuration and cache paths are mounted from the host." \ --append-system-prompt "$HOME/.config/pi/APPEND_SYSTEM.md" \ "$@" ''; pit = writeShellScriptBin "pit" '' set -euo pipefail tmp_cwd="$(${coreutils}/bin/mktemp -d /tmp/pit.XXXXXX)" cleanup() { ${coreutils}/bin/rmdir "$tmp_cwd" 2>/dev/null || true } trap cleanup EXIT cd "$tmp_cwd" exec ${pi}/bin/pi "$@" ''; in symlinkJoin { name = "pi-sandboxed"; paths = [ sbox pi pit ]; }