Files

3.7 KiB

APP-4188: Tech Spec

Context

The git-ops dialog spawns git and gh subprocesses through run_git_command (app/src/util/git.rs:12) and run_gh_command (app/src/util/git.rs:663). Neither sets PATH on the child — run_gh_command has a macOS-only hardcoded /opt/homebrew/bin:/usr/local/bin: prefix, which only helps Homebrew users and misses MacPorts/Nix/etc. On Finder/Dock launches, Warp inherits launchd's minimal PATH. git itself still works (Apple ships /usr/bin/git), but hooks git invokes — notably LFS pre-pushgit-lfs — fail. gh also fails outside Homebrew-default layouts. LocalShellState::get_interactive_path_env_var (app/src/terminal/local_shell/mod.rs:145) already captures the user's real interactive-shell PATH (runs zsh -i -l / bash / fish, caches the result). This is how LSP resolves binaries today (persisted_workspace.rs:1119), so it's already the repo's idiom.

Proposed changes

  1. util/git.rs: add run_git_command_with_env(repo, args, path_env: Option<&str>) that sets PATH on the child when path_env is Some. Keep run_git_command(repo, args) as a thin wrapper passing None — no ripple on existing call sites.
  2. Grow run_gh_command, run_commit, run_push, create_pr, get_pr_for_branch to take path_env: Option<&str> and forward. Only hook-firing and gh-spawning wrappers touched; pure read-only git wrappers (get_unpushed_commits, get_branch_commit_messages, get_diff_for_pr, get_branch_diff_entries) are left alone.
  3. Remove the hardcoded Homebrew prefix from run_gh_command. Callers that need gh findable now pass a captured interactive PATH. HOMEBREW_NO_AUTO_UPDATE=1 stays.
  4. git_dialog/{push,commit,pr}.rs::start_confirm capture the PATH before spawning:
    let path_future = interactive_path_future(ctx);
    ctx.spawn(async move {
        let path_env = path_future.await;
        run_push(&repo_path, &branch, path_env.as_deref()).await
    }, ...);
    
    Commit's start_confirm forwards through the commit → push → create_pr_with_ai_content chain; PR's start_confirm forwards into create_pr_with_ai_content, which forwards path_env into create_pr only. Pattern matches persisted_workspace.rs::execute_lsp_task.
  5. diff_state.rs::refresh_pr_info captures PATH via a local interactive_path_future helper (same shape, ModelContext<DiffStateModel>-flavored) and forwards into get_pr_for_branch so the PR #N header badge works from Finder launches.

Fallbacks

  • Capture returns None (wasm / LocalShellState not loaded / shell errored) → callers forward None → subprocess uses inherited PATH. Behavior no worse than today.
  • On Linux/Windows the same code path runs; no special-casing.

Testing and validation

No unit tests — the plumbing is a thin Option<&str> forward and the real-world condition (launchd minimal PATH) isn't reproducible in a test harness. Manual validation per PRODUCT.md "Validation". UI regression coverage via verify-ui-change-in-cloud.

Risks

  • First-click latency: first git-op in a session awaits the shell capture (<1s typical). Absorbed by existing loading state. Prewarming on panel mount is an easy follow-up if it's ever user-visible.
  • Hook behavior change: LFS hooks that silently no-op today (because git-lfs is missing) will actually run for Finder-launched Warp. Intended per PRODUCT.md.

Follow-ups

  • Prewarm get_interactive_path_env_var at code-review panel mount if first-click latency becomes a complaint.
  • Plumb path_env through other run_git_command call sites (repo_metadata, drive sync, etc.) if they start hitting the same class of failure.