fix(pager): avoid less in captured text pagers#362
Conversation
Greptile SummaryThis PR fixes
Confidence Score: 4/5Safe to merge; the change is a small, well-tested guard that avoids launching an interactive pager in dumb-terminal contexts. The logic change is narrow and the new tests cover both target cases. The one notable point is that src/core/startup.ts — specifically the redundant OR condition on the new guard at line 147 Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[hunk pager invoked] --> B[read stdin text]
B --> C{looksLikePatchInput?}
C -- No --> D{isCapturedPagerHost OR TERM=dumb?}
D -- Yes --> E[passthrough: write text to stdout]
D -- No --> F[plain-text-pager: launch less]
C -- Yes --> G{stdoutIsTTY?}
G -- No --> E
G -- Yes --> H{TERM=dumb AND NOT capturedHost?}
H -- Yes --> E
H -- No --> I{isCapturedPagerHost?}
I -- Yes --> J[static-diff-pager: colored diff output]
I -- No --> K[openControllingTerminal]
K -- null --> J
K -- terminal --> L[app: interactive TUI]
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
src/core/startup.ts:146-147
The condition `isCapturedPagerHost(env) || env.TERM === "dumb"` is logically equivalent to just `env.TERM === "dumb"`, because `isCapturedPagerHost` itself requires `env.TERM === "dumb"` as its first operand — the captured-host check can never be true when the dumb-terminal check is false. The `isCapturedPagerHost` arm is therefore dead code here. This contrasts with the diff path (lines 167–178) where the two conditions produce different outcomes (`passthrough` vs `static-diff-pager`), making the distinction meaningful — but for non-diff input both arms return `passthrough`, collapsing the distinction entirely. The comment "Captured pager and dumb-terminal hosts" implies these are separate categories, which may mislead future readers.
```suggestion
// Dumb-terminal and captured pager hosts (which also advertise TERM=dumb) cannot safely own an interactive text pager.
if (env.TERM === "dumb") {
```
Reviews (1): Last reviewed commit: "fix(pager): avoid less in captured text ..." | Re-trigger Greptile |
| // Captured pager and dumb-terminal hosts cannot safely own an interactive text pager. | ||
| if (isCapturedPagerHost(env) || env.TERM === "dumb") { |
There was a problem hiding this comment.
The condition
isCapturedPagerHost(env) || env.TERM === "dumb" is logically equivalent to just env.TERM === "dumb", because isCapturedPagerHost itself requires env.TERM === "dumb" as its first operand — the captured-host check can never be true when the dumb-terminal check is false. The isCapturedPagerHost arm is therefore dead code here. This contrasts with the diff path (lines 167–178) where the two conditions produce different outcomes (passthrough vs static-diff-pager), making the distinction meaningful — but for non-diff input both arms return passthrough, collapsing the distinction entirely. The comment "Captured pager and dumb-terminal hosts" implies these are separate categories, which may mislead future readers.
| // Captured pager and dumb-terminal hosts cannot safely own an interactive text pager. | |
| if (isCapturedPagerHost(env) || env.TERM === "dumb") { | |
| // Dumb-terminal and captured pager hosts (which also advertise TERM=dumb) cannot safely own an interactive text pager. | |
| if (env.TERM === "dumb") { |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/core/startup.ts
Line: 146-147
Comment:
The condition `isCapturedPagerHost(env) || env.TERM === "dumb"` is logically equivalent to just `env.TERM === "dumb"`, because `isCapturedPagerHost` itself requires `env.TERM === "dumb"` as its first operand — the captured-host check can never be true when the dumb-terminal check is false. The `isCapturedPagerHost` arm is therefore dead code here. This contrasts with the diff path (lines 167–178) where the two conditions produce different outcomes (`passthrough` vs `static-diff-pager`), making the distinction meaningful — but for non-diff input both arms return `passthrough`, collapsing the distinction entirely. The comment "Captured pager and dumb-terminal hosts" implies these are separate categories, which may mislead future readers.
```suggestion
// Dumb-terminal and captured pager hosts (which also advertise TERM=dumb) cannot safely own an interactive text pager.
if (env.TERM === "dumb") {
```
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Good catch — simplified this to check TERM=dumb directly and updated the comment so it does not imply a separate captured-host branch in the non-diff path.
This comment was generated by Pi using OpenAI GPT-5.1 Codex
Summary
hunk pagerinput through when running under captured pager hosts like LazyGitTERM=dumbFixes #337
Testing
bun run typecheckbun test src/core/startup.test.ts src/core/pager.test.ts test/cli/entrypoint.test.tsHUNK_TEXT_PAGERpointed at a wrapper around realless -R; LazyGit invokedhunk pagerwhile advertisingTERM=dumb, thelesswrapper was invoked 0 times, and no livelessprocesses remained.This PR description was generated by Pi using OpenAI GPT-5.1 Codex