Restore and harden pager suppression for wait-mode commands (APP-5310) - #14946
Draft
warp-agent-staging[bot] wants to merge 2 commits into
Draft
Restore and harden pager suppression for wait-mode commands (APP-5310)#14946warp-agent-staging[bot] wants to merge 2 commits into
warp-agent-staging[bot] wants to merge 2 commits into
Conversation
The server always sets wait_until_completion=false for the modern run_shell_command tool call, in both 'wait' and 'interact' modes. The client only decorated pager-prone commands (piping through `cat` to suppress the pager) when uses_pager && wait_until_completion, so the decoration silently never ran even when the model correctly flagged a command as using a pager. This let commands like `gh pr view` or `git log` drop into the user's configured pager and hang. Base pager decoration purely on uses_pager, since wait_until_completion is no longer a reliable signal for this tool. Add a regression test that exercises uses_pager && !wait_until_completion. Co-Authored-By: Warp Agent <agent@warp.dev>
…edoc handling (APP-5310) Revision based on review findings on this PR. Findings 1-3 showed the "decorate whenever uses_pager is set" approach from the previous commit was wrong: it also decorated `interact`-mode commands, which need live PTY control (REPLs, dev servers, or a pager the subagent means to page through itself), and the decoration itself lost the wrapped command's exit status and could corrupt a command ending in a heredoc. The real, more surgical fix (companion change on warpdotdev/warp-server) was to stop the server from unconditionally reporting wait_until_completion=false for both 'wait' and 'interact' modes. Now that the server reports it correctly (true for 'wait', false for 'interact'), this commit: - Reverts the client's pager-decoration predicate to `uses_pager && wait_until_completion`, so only 'wait'-style commands are decorated (finding 1). - Hardens `turn_off_pager_for_command`: - Splits the combined Bash/Zsh arm, since they use different pipeline-status variables (`PIPESTATUS` vs `pipestatus`), and re-asserts the wrapped command's real exit status via a trailing `(exit "$...")` subshell instead of letting `cat`'s own exit status win the pipe (finding 2). - Puts the closing group syntax (`)`, `end`) on its own line so a command ending in a bare heredoc terminator isn't corrupted (finding 3 / CSAT-10167 class). - Fish has no safe bare `exit`/PIPESTATUS-equivalent to use from the live shell, so it re-asserts the exit status via a nested `fish -c` process instead. - Replaces the previous (now-invalidated) regression test with: - wait-vs-interact gating tests (finding 1). - Real Bash-subprocess tests proving exit-status preservation (finding 2) and heredoc safety, including a no-trailing-newline case (finding 3 / CSAT-10167). - Structural tests for Zsh/Fish/PowerShell decoration shape. On finding 4 (visual proof): I do not have computer-use tooling available in this environment to capture a recording. The regression tests above exercise the real, observable behavior end-to-end (actual shell processes, real exit codes, real heredoc parsing) as the strongest evidence available to me here. Co-Authored-By: Warp Agent <agent@warp.dev>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The agent stopped reliably suppressing pagers for
gh/VCS commands. Root cause:ShellCommandExecutor::executeonly decorates pager-prone commands (wrapping them so their output is piped throughcat, preventing the pager from activating) whenuses_pager && wait_until_completion. The server was unconditionally reportingwait_until_completion = falsefor the modernrun_shell_commandtool call, in bothwaitandinteractmodes — a bug now fixed in the companion PR warpdotdev/warp-server#14303. With that field alwaysfalse, the client's decoration gate never fired even when the model correctly setuses_pager: true, letting commands likegh pr vieworgit logdrop into the user's pager and hang or truncate.This PR restores the client's
uses_pager && wait_until_completiongate (now that the server reports the field correctly again —trueforwaitmode,falseforinteractmode), and hardens the decoration itself:wait-style commands are decorated.interact-mode commands (REPLs, dev servers, TUIs, or a pager the subagent means to page through itself) are left alone so the subagent keeps live PTY control.catused to mask the wrapped command's real exit status (catbeing the last stage of the pipe always exits 0). The decoration now re-asserts the original exit status viaPIPESTATUS/pipestatus(Bash/Zsh) or a nestedfish -cprocess (Fish).),end) now lands on its own line, so a command ending in a bare heredoc terminator (e.g.EOF) isn't corrupted by trailing characters on that line.Linked Issue
Linear: APP-5310
Testing
execute_decorates_pager_command_when_waiting_for_completion/execute_does_not_decorate_pager_command_in_interact_mode: prove the wait-vs-interact gate.turn_off_pager_for_command_preserves_nonzero_exit_status_in_bash: spawns a realbashsubprocess to prove a failing command's exit code survives decoration.turn_off_pager_for_command_preserves_heredoc_in_bash/turn_off_pager_for_command_handles_command_without_trailing_newline_in_bash: spawn realbashsubprocesses to prove heredoc-ending and no-trailing-newline commands aren't corrupted.turn_off_pager_for_command_zsh_uses_pipestatus_and_safe_closer,..._fish_uses_nested_process_for_exit_status,..._powershell_closer_on_own_line: structural checks for the other shells (not run as real subprocesses, since Zsh/Fish/PowerShell aren't guaranteed present in CI).Ran to completion locally:
cargo fmt -- --checkcargo clippy -p warp --tests -- -D warningscargo test -p warp --lib shell_command(11/11 passing)On visual proof: I don't have computer-use tooling available in this environment to capture a screen recording of Agent Mode. The tests above exercise the real, observable behavior end-to-end (actual shell processes, real exit codes, real heredoc parsing), which is the strongest evidence I can produce here. If a recording is still required before merge, it needs a human or a computer-use-capable agent to capture it.
./script/runAgent Mode
Conversation: https://staging.warp.dev/conversation/cbb2de15-6edb-4bc9-851e-3876c7b523f3
Run: https://oz.staging.warp.dev/runs/019ff1c9-37d2-7b36-bc92-33f392a1c482
This PR was generated with Oz.