Fix Review Interactive Setup and Defaults

Pi·GPT-5.6-sol·dipree·2mo ago·3hr 22min·6 Checkpoints·15 file changes·+317/-66·270.9K tokens

wtf happened to the interactive configuration of entire review? entire review --configure Available review agents: claude-code hooks installed codex hooks installed gemini not installed; run entire configure --agent gemini pi not installed; run entire configure --agent pi

Configured profiles: (none yet)

Configure "general" non-interactively, e.g.: entire review --configure --profile general --set-agents claude-code,codex --set-judge <agent>

2mo ago·3.8s

Nothing was removed. You ran it from inside Pi, which exports:

CanPromptInteractively() intentionally treats agent subprocesses as non-interactive, so --configure falls back to the catalog/scriptable instructions.

Run this directly in a normal terminal:

If your shell inherited Pi’s environment:

Pi’s captured shell/tool output is also not a TTY, so the wizard cannot safely run through it.

:wat: that was my console output when running it!

2mo ago·11.4s

You’re right—I jumped to the wrong conclusion. I’ll trace the actual TTY detection and command output wiring in the CLI.

You’re right—sorry. The wizard still exists, but the CLI incorrectly classified your console as non-interactive.

That exact output only occurs when one of these gates fails:

  • stdout isn’t detected as a TTY
  • CI is set
  • GIT_TERMINAL_PROMPT=0
  • PI_CODING_AGENT, GEMINI_CLI, or COPILOT_CLI is inherited
  • ENTIRE_TEST_TTY is set to something other than 1

Please run in that same console:

The regression is the overly broad interactive guard in cmd/entire/cli/review/cmd.go:332; it silently falls back to the non-interactive catalog instead of explaining which check failed.

Where is the interactive mode of entire review! Why was it removed and when!

2mo ago·12.7s

It was not removed. There are three interactive paths still in the current code:

  • entire review --configureRunReviewGuidedSetup
    cmd/entire/cli/review/cmd.go:332, picker.go:88
  • Bare entire review → interactive profile picker
    cmd/entire/cli/review/cmd.go:836
  • entire review --edit → advanced profile picker
    cmd/entire/cli/review/cmd.go:224, picker.go:753

The catalog output you received was added on June 2, 2026, in commit:

That commit made --configure behave as:

  • detected interactive terminal → wizard
  • otherwise → agent/profile catalog and non-interactive instructions

The wizard itself was added on June 1, 2026 in:

So this is not a removal. The interactive-terminal detection is incorrectly routing your real console into the June 2 non-interactive fallback. That is the bug.

Does this look like it would work?

dip@dip entire-api-2 % entire review No review profiles configured. Run entire review --configure in a terminal first. dip@dip entire-api-2 % entire review --configure Available review agents: claude-code hooks installed codex hooks installed gemini not installed; run entire configure --agent gemini pi not installed; run entire configure --agent pi

Configured profiles: (none yet)

Configure "general" non-interactively, e.g.: entire review --configure --profile general --set-agents claude-code,codex --set-judge <agent>

2mo ago·22.8s

No. That is plainly broken.

The CLI tells you to run --configure “in a terminal,” then fails to recognize the terminal and prints a non-interactive workaround. That’s a dead-end, not functioning interactive configuration.

The wizard wasn’t removed; the TTY/prompt detection is suppressing it incorrectly. This needs fixing in the CLI—not another workaround from you.

Surprise, we are in the CLI repo...

2mo ago·3.0s

Fair point. I’ll fix the routing instead of narrating the bug.

Fixed.

A real terminal on both stdin and stdout now takes precedence over inherited agent sentinels and GIT_TERMINAL_PROMPT=0. Pipes, CI, and explicitly forced non-interactive mode remain non-interactive.

Changed:

  • cmd/entire/cli/review/cmd.go
  • cmd/entire/cli/review/fix.go
  • cmd/entire/cli/interactive/interactive.go
  • Added regression coverage in configure_test.go

Tests pass:

dip@dip entire-api-2 % entire review ┃ Which profile should review the branch? ┃ > general (default) - claude-code, claude-code, codex, codex ┃ ┃ AGENT STATUS DURATION TOKENS PREVIEW claude-code ⣾ running 3.9s claude-code:opus (… ⣾ running 3.9s

Ctrl+O: drill in · Ctrl+C: cancel

Why does codex not work here?

2mo ago·7.5s

The profile has four slots, but both Codex slots are being dropped before the TUI starts. The current default profile writes Codex with the obsolete "/review" skill, then runtime validation rejects that same skill. I’m fixing both profile creation and existing profiles.

Codex was being skipped before launch.

Root cause: guided setup incorrectly assigned Codex the Claude-only "/review" skill. Runtime validation then rejected both Codex slots, while the TUI hid the preceding stderr warning by entering the alternate screen.

Fixed:

  • New Codex profiles are prompt-only by default.
  • Existing generated Codex "/review" configurations are repaired in memory.
  • Explicit custom Codex skills remain unchanged.
  • Validation tests updated and passing.

After rebuilding/installing this CLI, both Codex rows should launch and appear.

This was all working before wtf happened 😳 write regression tests

2mo ago·13.5s

Agreed. The unit checks aren’t enough; I’ll add command-level regressions for both fresh defaults and legacy profiles reaching Codex launch.

Found the regression timeline:

  • July 7, ed5f528245: removed Codex’s curated "/review" builtin.
  • The default-profile generator still assigned "/review" to Codex.
  • July 8, 784fa6d61: added behavior/tests that treated skipping those Codex workers as expected instead of repairing the default.

Added regressions covering:

  1. New Codex defaults are prompt-only.
  2. Existing direct and aliased Codex slots using generated "/review" are repaired.
  3. A full command dispatch proves repaired Codex reaches Start() and is not silently skipped.
  4. Explicit custom missing skills are still rejected.

Targeted and package tests pass.

Give me the github commit links

2mo ago·3.4s

All right create a trail using "entire trail" CLI and commit/push the changes to the new branch

2mo ago·4.3s

Created and pushed:

Lint is failing fix it

2mo ago·7.5s

Fixed and pushed in 98f89895c.

  • Added the required //nolint:staticcheck justification for deprecated compatibility config.
  • Changed-lines lint: 0 issues
  • Review/interactive tests pass.
  • Branch is clean and synchronized with origin.

Note: full local lint also reports 82 pre-existing SA5011 issues in unrelated files; none are introduced by this branch.

Entire Trail review comment ID: 019f6194-4752-74f4-9e71-84d87bd409d8 URL: https://entire.io/gh/entireio/cli/trails/854/fix-review-interactive-setup-and-codex-defaults Severity: high Context: cmd/entire/cli/review/cmd.go:291 Selected context:

reviewTTYIsInteractive returns true when stdoutTTY && canPrompt, even if stdinTTY is false. But canPrompt (interactive.CanPromptInteractively) can be true purely from its /dev/tty probe (step 5) regardless of whether the process's actual os.Stdin is piped — and NewTUISink is constructed with os.Stdin directly (cmd.go:1378, cmd.go:1640), not a controlling-terminal fd. So an agent host that pipes stdin but still has an accessible controlling terminal (no recognized sentinel env var, no CI) will have stdinTTY=false yet canPrompt=true, satisfying stdinTTY || canPrompt and engaging the TUI sink — exactly the "terminal stdout with non-interactive stdin" case the adjacent multiAgentSinkInputs doc comment (lines 1333-1336) says must never use the TUI because its dismissal loop would block forever. The OR should likely require both signals to agree (i.e. stdinTTY specifically, not a fallback to canPrompt) to preserve that invariant.

2mo ago·20.0s

The review is correct. The /dev/tty fallback is unsafe for a TUI that reads actual stdin. I’ll require both stdin and stdout to be terminals while retaining the explicit CI/test disable gates.

Fixed and pushed in 1ac87bc8a.

  • Interactive review now requires both actual stdin and stdout TTYs.
  • /dev/tty availability cannot enable the TUI when stdin is piped.
  • Added regression coverage for that exact case.
  • Tests pass; changed-lines lint reports zero issues.
  • Trail finding marked resolved.

Entire Trail review comment ID: 019f619b-7a78-7981-8034-3048dfbb5361 URL: https://entire.io/gh/entireio/cli/trails/854/fix-review-interactive-setup-and-codex-defaults Severity: high Context: cmd/entire/cli/review/cmd.go:279 Selected context:

reviewCommandIsInteractive no longer checks testing.Testing() the way interactive.CanPromptInteractively() did — it derives interactivity purely from real TTY probes on cmd.InOrStdin()/cmd.OutOrStdout() plus the ENTIRE_TEST_TTY/CI hard-disable checks. Any go test run where a command's stdin/stdout aren't explicitly redirected (falling back to real os.Stdin/os.Stdout) will now be treated as interactive when run on a developer's real terminal, e.g. TestReviewEditNonInteractiveRefusesWithScriptedAlternatives in cmd_test.go only calls SetErr, not SetOut/SetIn, so it could take the interactive --edit branch and block on a huh/Bubble Tea keypress read instead of erroring as the test expects. The codebase-wide invariant (testing.Testing() forces non-interactive in-process) should be preserved in this new helper.

2mo ago·15.4s

Correct. The helper must preserve the test-process default while still allowing the explicit ENTIRE_TEST_TTY=1 override. I’ll add that gate and regression coverage.

Fixed and pushed in 114562ab9.

  • In-process Go tests remain non-interactive by default.
  • ENTIRE_TEST_TTY=1 still explicitly enables interaction.
  • CI and forced-off behavior are preserved.
  • Added precedence regression tests.
  • Tests and changed-lines lint pass.
  • Trail finding marked resolved.

Entire Trail review comment ID: 019f61a2-305d-775b-a04a-8d3c4c6bd51c URL: https://entire.io/gh/entireio/cli/trails/854/fix-review-interactive-setup-and-codex-defaults Severity: high Context: cmd/entire/cli/review/cmd.go:303 Selected context:

reviewCommandIsInteractive (and its helper reviewTTYIsInteractive here) decides interactivity purely from IsTerminalReader/IsTerminalWriter on stdin/stdout, with no check for isAgentSubprocessEnv() (GEMINI_CLI/COPILOT_CLI/PI_CODING_AGENT/GIT_TERMINAL_PROMPT=0). Those sentinels exist precisely because such agent shell tools can allocate a real pty on both stdin and stdout while no human is present to answer prompts (per the doc comment on isAgentSubprocessEnv); with this change, entire review/--edit/--configure invoked from such an agent shell would now launch the huh/Bubble Tea guided setup or TUI and block forever waiting for keypresses the agent can never send, whereas interactive.CanPromptInteractively() (still used elsewhere, e.g. confirmReReviewOrProceed) would have correctly refused to prompt in that same environment.

2mo ago·37.5s

The finding is valid: requiring real stdin fixes the piped-input case, but does not replace the agent-sentinel guard. I’ll require both real terminal stdio and CanPromptInteractively(), then add a regression for PTY-backed agent subprocesses.

Fixed and pushed in dfd203c9c.

Interactive mode now requires:

  • Actual terminal stdin
  • Actual terminal stdout
  • CanPromptInteractively() approval, including agent sentinel checks
  • No test/CI hard-disable

Added regression coverage for an agent subprocess with a real PTY. Tests and changed-lines lint pass; finding resolved.

Entire Trail review comment ID: 019f61a8-54a6-726b-8360-11ef812ce249 URL: https://entire.io/gh/entireio/cli/trails/854/fix-review-interactive-setup-and-codex-defaults Severity: medium Context: cmd/entire/cli/review/cmd.go:1101 Selected context:

canPrompt here now uses the stricter reviewCommandIsInteractive (requiring both stdin and stdout to be real terminals) to avoid hanging when an agent host inherits a controlling TTY but pipes stdin. However, confirmReReviewOrProceed (called just above, at line 1047, and similarly in runMultiAgentPath) still gates its huh.NewConfirm() prompt on the older interactive.CanPromptInteractively() alone. That call site reproduces the exact regression this PR fixes: in the same piped-stdin/inherited-TTY scenario, CanPromptInteractively() can still return true (via the /dev/tty probe), so the confirm form will attempt to read from non-terminal stdin. confirmReReviewOrProceed should use reviewCommandIsInteractive(cmd) for consistency.

2mo ago·5.2s

Correct. The re-review confirmation bypasses the stricter stdin check. I’ll pass the command-level prompt decision into that guard and cover its non-interactive behavior.

Fixed and pushed in e2bd6e015.

  • Re-review confirmation now uses reviewCommandIsInteractive.
  • Both single- and multi-agent paths pass the same prompt decision to confirmation and TUI setup.
  • Added regression coverage ensuring prior reviews do not prompt with non-interactive stdin.
  • Tests and changed-lines lint pass.
  • Finding resolved.