fix(review): gate re-review prompt on command stdin · Entire
fix(review): gate re-review prompt on command stdin
e2bd6e0→main·
dipree·3d ago·2 files·+27 added/-6 removed
Sessions
01KXGTKA4VF60BYNEPDWQQ3NNCView transcript
[?
Fix Review Interactive Setup and DefaultsPi·GPT-5.6-sol·1 step](/content/gh/entireio/cli/session/019f60f0-7ee7-73b0-b787-4c8cbc646802#timeline-01KXGTKA4VF60BYNEPDWQQ3NNC/index.html)
Changes
2
cmd/entire/cli/review
Mcmd.go+7/-6
Mconfigure_test.go+20
976 unmodified lines
977
978
979
980
980
981
982
983
984
985
985
986
987
988
55 unmodified lines
1044
1045
1046
1047
1047
1048
1049
1050
1051
47 unmodified lines
1099
1100
1101
1101
1102
1103
1104
83 unmodified lines
1188
1189
1190
1191
1191
1192
1193
1194
1195
75 unmodified lines
1271
1272
1273
1273
1274
1275
1276
1277
976 unmodified lines
// (true, nil). In a non-interactive context it cannot prompt, so it proceeds
// (the user explicitly invoked `entire review`) after printing a note rather
// than blocking on a confirm form that would error out.
func confirmReReviewOrProceed(ctx context.Context, out io.Writer, deps Deps) (bool, error) {
func confirmReReviewOrProceed(ctx context.Context, out io.Writer, deps Deps, canPrompt bool) (bool, error) {
reviewed, meta := deps.HeadHasReviewCheckpoint(ctx)
if !reviewed {
return true, nil
}
if !interactive.CanPromptInteractively() {
if !canPrompt {
fmt.Fprintf(out, "Note: HEAD was already reviewed (%s); re-running.\n", meta)
return true, nil
}
55 unmodified lines
}
// 4. Re-run guard: check if HEAD's checkpoint already has a review.
if proceed, guardErr := confirmReReviewOrProceed(ctx, out, deps); guardErr != nil {
canPrompt := reviewCommandIsInteractive(cmd)
if proceed, guardErr := confirmReReviewOrProceed(ctx, out, deps, canPrompt); guardErr != nil {
fmt.Fprintln(out, "prompt cancelled")
return silentErr(guardErr)
} else if !proceed {
47 unmodified lines
defer cancelRun()
runCfg.EnrichSummary = reviewSummaryTokenEnricher(worktreeRoot, headSHA)
canPrompt := reviewCommandIsInteractive(cmd)
sinks := composeSingleAgentSinks(singleAgentSinkInputs{
out: out,
isTTY: canPrompt,
83 unmodified lines
return fmt.Errorf("resolve HEAD: %w", shaErr)
}
if proceed, guardErr := confirmReReviewOrProceed(ctx, out, deps); guardErr != nil {
canPrompt := reviewCommandIsInteractive(cmd)
if proceed, guardErr := confirmReReviewOrProceed(ctx, out, deps, canPrompt); guardErr != nil {
fmt.Fprintln(out, "prompt cancelled")
return deps.NewSilentError(guardErr)
} else if !proceed {
75 unmodified lines
masterLabel := judgeLabel(judge)
sinks := composeMultiAgentSinks(multiAgentSinkInputs{
out: out,
isTTY: reviewCommandIsInteractive(cmd),
isTTY: canPrompt,
agentNames: agentNames,
cancelRun: cancelRun,
runContext: runCtx,
Mcmd/entire/cli/review/cmd.go+7/-6
87 unmodified lines
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
87 unmodified lines
}
func TestConfirmReReviewOrProceed_NonInteractiveDoesNotPrompt(t *testing.T) {
t.Parallel()
out := &bytes.Buffer{}
proceed, err := confirmReReviewOrProceed(context.Background(), out, Deps{
HeadHasReviewCheckpoint: func(context.Context) (bool, string) {
return true, "existing review"
},
}, false)
if err != nil {
t.Fatalf("confirmReReviewOrProceed: %v", err)
}
if !proceed {
t.Fatal("non-interactive re-review should proceed")
}
if !strings.Contains(out.String(), "already reviewed") {
t.Fatalf("missing non-interactive re-review note: %q", out.String())
}
}
func TestReviewInteractivityHardDisabled(t *testing.T) {
t.Parallel()