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-push → git-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
util/git.rs: addrun_git_command_with_env(repo, args, path_env: Option<&str>)that setsPATHon the child whenpath_envisSome. Keeprun_git_command(repo, args)as a thin wrapper passingNone— no ripple on existing call sites.- Grow
run_gh_command,run_commit,run_push,create_pr,get_pr_for_branchto takepath_env: Option<&str>and forward. Only hook-firing andgh-spawning wrappers touched; pure read-onlygitwrappers (get_unpushed_commits,get_branch_commit_messages,get_diff_for_pr,get_branch_diff_entries) are left alone. - Remove the hardcoded Homebrew prefix from
run_gh_command. Callers that needghfindable now pass a captured interactive PATH.HOMEBREW_NO_AUTO_UPDATE=1stays. git_dialog/{push,commit,pr}.rs::start_confirmcapture the PATH before spawning:Commit'slet 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 }, ...);start_confirmforwards through the commit → push →create_pr_with_ai_contentchain; PR'sstart_confirmforwards intocreate_pr_with_ai_content, which forwardspath_envintocreate_pronly. Pattern matchespersisted_workspace.rs::execute_lsp_task.diff_state.rs::refresh_pr_infocaptures PATH via a localinteractive_path_futurehelper (same shape,ModelContext<DiffStateModel>-flavored) and forwards intoget_pr_for_branchso thePR #Nheader badge works from Finder launches.
Fallbacks
- Capture returns
None(wasm /LocalShellStatenot loaded / shell errored) → callers forwardNone→ subprocess uses inheritedPATH. 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-lfsis missing) will actually run for Finder-launched Warp. Intended per PRODUCT.md.
Follow-ups
- Prewarm
get_interactive_path_env_varat code-review panel mount if first-click latency becomes a complaint. - Plumb
path_envthrough otherrun_git_commandcall sites (repo_metadata, drive sync, etc.) if they start hitting the same class of failure.