@@ -101,8 +101,8 @@ func (app *App) Config() *config.Config {
101101 return app.config
102102}
103103
104−// RunNonInteractive handles the execution flow when a prompt is provided via
105−// CLI flag.
104+// RunNonInteractive runs the application in non-interactive mode with the
105+// given prompt, printing to stdout.
106106func (app *App) RunNonInteractive(ctx context.Context, prompt string, quiet bool) error {
107107 slog.Info("Running in non-interactive mode")
108108
@@ -125,7 +125,7 @@ func (app *App) RunNonInteractive(ctx context.Context, prompt string, quiet bool
125125 defer stopSpinner()
126126
127127 const maxPromptLengthForTitle = 100
128− titlePrefix := "Non-interactive: "
128+ const titlePrefix = "Non-interactive: "
129129 var titleSuffix string
130130
131131 if len(prompt) > maxPromptLengthForTitle {
@@ -165,11 +165,19 @@ func (app *App) RunNonInteractive(ctx context.Context, prompt string, quiet bool
165165 messageEvents := app.Messages.Subscribe(ctx)
166166 messageReadBytes := make(map[string]int)
167167
168− defer fmt.Printf(ansi.ResetProgressBar)
168+ defer func() {
169+ _, _ = fmt.Printf(ansi.ResetProgressBar)
170+
171+ // Always print a newline at the end. If output is a TTY this will
172+ // prevent the prompt from overwriting the last line of output.
173+ _, _ = fmt.Print('\n')
174+ }()
175+
169176 for {
170− // HACK: add it again on every iteration so it doesn't get hidden by
171− // the terminal due to inactivity.
172− fmt.Printf(ansi.SetIndeterminateProgressBar)
177+ // HACK: Reinitialize the terminal progress bar on every iteration so
178+ // it doesn't get hidden by the terminal due to inactivity.
179+ _, _ = fmt.Printf(ansi.SetIndeterminateProgressBar)
180+
173181 select {
174182 case result := <-done:
175183 stopSpinner()