Address Greptile review on sandbox install fixes

Two findings from the Greptile pass on PAPA-316:

1. sandbox-install-command: the export PATH and PAPERCLIP_NPM_BOOTSTRAPPED=1
   were separated from the curl && tar && rm chain by ; so the bootstrap
   marker would be set even if the tarball download or extraction failed,
   leading to a misleading "npm: command not found" error on the install
   step instead of surfacing the original curl/tar failure. Switch those
   delimiters to && so the marker is only set after a successful bootstrap.

2. opencode-local: $HOME/.local/bin is on the default PATH on the exe.dev
   image but not universally on bare Debian/Ubuntu non-login sh -c shells.
   Prefer /usr/local/bin (always on the default PATH on Linux) when running
   as root or with passwordless sudo, and only fall back to $HOME/.local/bin
   when neither is available. Mirrors the sudo-aware pattern that
   buildSandboxNpmInstallCommand already uses.
This commit is contained in:
Devin Foley committed 2026-05-11 14:17:07 -07:00
1 parent 90a90637f5
commit 4c72f02a06
2 files changed
+14 -5

No files matched your search

@@ -24,8 +24,8 @@ const ENSURE_NPM_PREAMBLE =
'mkdir -p "$HOME/.local"; ' +
'curl -fsSL "https://nodejs.org/dist/${NODE_VERSION}/${NODE_TARBALL}" -o "/tmp/${NODE_TARBALL}" && ' +
'tar -xJf "/tmp/${NODE_TARBALL}" -C "$HOME/.local" --strip-components=1 && ' +
'rm -f "/tmp/${NODE_TARBALL}"; ' +
'export PATH="$HOME/.local/bin:$PATH"; ' +
'rm -f "/tmp/${NODE_TARBALL}" && ' +
'export PATH="$HOME/.local/bin:$PATH" && ' +
"PAPERCLIP_NPM_BOOTSTRAPPED=1; " +
"fi;";
+12 -3
View File
@@ -12,8 +12,11 @@ export const label = "OpenCode (local)";
// `$HOME/.opencode/bin` and tries to add it to PATH via `~/.bashrc`. That
// rc-file path is only sourced by interactive/login shells, so non-login
// `sh -c` probe invocations (used by the runtime PATH check) cannot find the
// binary. We fix that by symlinking the installed binary into
// `$HOME/.local/bin`, which is on the default PATH on every distro we target.
// binary. We fix that by symlinking the installed binary into a directory on
// the non-login `sh -c` PATH: prefer `/usr/local/bin` (universally on the
// default PATH on Linux distros) when root or passwordless sudo is available,
// otherwise fall back to `$HOME/.local/bin` (which is on the default PATH on
// the exe.dev sandbox image and most modern home-managed Linux images).
//
// Security tradeoff: this is `curl | bash` without a SHA-256 verification of
// the install script. We accept this because:
@@ -30,9 +33,15 @@ export const label = "OpenCode (local)";
// a versioned tarball + verifying the digest before exec.
export const SANDBOX_INSTALL_COMMAND =
'curl -fsSL https://opencode.ai/install | bash && ' +
'mkdir -p "$HOME/.local/bin" && ' +
'if [ -x "$HOME/.opencode/bin/opencode" ]; then ' +
'if [ "$(id -u)" -eq 0 ]; then ' +
'ln -sf "$HOME/.opencode/bin/opencode" /usr/local/bin/opencode; ' +
'elif command -v sudo >/dev/null 2>&1 && sudo -n true >/dev/null 2>&1; then ' +
'sudo ln -sf "$HOME/.opencode/bin/opencode" /usr/local/bin/opencode; ' +
'else ' +
'mkdir -p "$HOME/.local/bin" && ' +
'ln -sf "$HOME/.opencode/bin/opencode" "$HOME/.local/bin/opencode"; ' +
'fi; ' +
'fi';
export const DEFAULT_OPENCODE_LOCAL_MODEL = "openai/gpt-5.2-codex";