fix: don't capture stdout in interactive mode — run claude directly so UI renders

This commit is contained in:
2026-03-27 13:34:54 -04:00
parent 994908aed2
commit 18d95fed0d

43
loop.sh
View File

@@ -348,13 +348,17 @@ while [ "$ITERATION" -lt "$MAX_ITERATIONS" ]; do
exit 0 exit 0
fi fi
GENERATOR_OUTPUT=$(run_agent "$GENERATOR_PROMPT" "generator") if [ "${LOOP_HEADLESS:-false}" != "true" ]; then
# Interactive: run directly, no capture. User sees full CC UI.
# In interactive mode, generator output is empty (displayed in terminal, not captured). run_agent "$GENERATOR_PROMPT" "generator"
# State is tracked via prd.json — the generator updates it directly. GENERATOR_OUTPUT=""
if [ "${LOOP_HEADLESS:-false}" = "true" ] && [ -z "$GENERATOR_OUTPUT" ]; then else
log "WARNING: Generator produced empty output (timeout or crash). Skipping to next iteration." # Headless: capture output for parsing.
continue GENERATOR_OUTPUT=$(run_agent "$GENERATOR_PROMPT" "generator")
if [ -z "$GENERATOR_OUTPUT" ]; then
log "WARNING: Generator produced empty output (timeout or crash). Skipping to next iteration."
continue
fi
fi fi
# --- Scope budget check --- # --- Scope budget check ---
@@ -377,8 +381,14 @@ while [ "$ITERATION" -lt "$MAX_ITERATIONS" ]; do
export SCOPE_FILES_MODIFIED SCOPE_LINES_WRITTEN export SCOPE_FILES_MODIFIED SCOPE_LINES_WRITTEN
fi fi
# Check for completion sentinel # Check for completion — in interactive mode, check prd.json directly
if echo "$GENERATOR_OUTPUT" | grep -q "<promise>COMPLETE</promise>"; then if all_stories_pass 2>/dev/null; then
log_header "All Stories Complete! ($(story_counts))"
snapshot_for_archive
exit 0
fi
# Headless mode: also check output sentinel
if [ -n "$GENERATOR_OUTPUT" ] && echo "$GENERATOR_OUTPUT" | grep -q "<promise>COMPLETE</promise>"; then
log_header "Generator signaled COMPLETE ($(story_counts))" log_header "Generator signaled COMPLETE ($(story_counts))"
snapshot_for_archive snapshot_for_archive
exit 0 exit 0
@@ -394,14 +404,21 @@ while [ "$ITERATION" -lt "$MAX_ITERATIONS" ]; do
fi fi
EVAL_PROMPT=$(build_prompt "evaluator" "$MODE") EVAL_PROMPT=$(build_prompt "evaluator" "$MODE")
EVAL_OUTPUT=$(run_agent "$EVAL_PROMPT" "evaluator")
if [ -z "$EVAL_OUTPUT" ]; then if [ "${LOOP_HEADLESS:-false}" != "true" ]; then
# In interactive mode, check the verdict file # Interactive: run directly, read verdict from file.
run_agent "$EVAL_PROMPT" "evaluator"
if [ -f "$LOOP_DIR/.verdict" ]; then if [ -f "$LOOP_DIR/.verdict" ]; then
EVAL_OUTPUT=$(cat "$LOOP_DIR/.verdict") EVAL_OUTPUT=$(cat "$LOOP_DIR/.verdict")
else else
log "WARNING: Evaluator produced no output and no verdict file. Treating as REJECT." log "WARNING: No verdict file found. Treating as REJECT."
EVAL_OUTPUT="<verdict>REJECT</verdict><rejection_reason>Evaluator produced no verdict file</rejection_reason>"
fi
else
# Headless: capture output for parsing.
EVAL_OUTPUT=$(run_agent "$EVAL_PROMPT" "evaluator")
if [ -z "$EVAL_OUTPUT" ]; then
log "WARNING: Evaluator produced empty output. Treating as REJECT."
EVAL_OUTPUT="<verdict>REJECT</verdict><rejection_reason>Evaluator produced no output</rejection_reason>" EVAL_OUTPUT="<verdict>REJECT</verdict><rejection_reason>Evaluator produced no output</rejection_reason>"
fi fi
fi fi