@@ -92,7 +92,7 @@ func New(ctx context.Context, conn *sql.DB, cfg *config.Config) (*App, error) {
9292}
9393
9494// RunNonInteractive handles the execution flow when a prompt is provided via CLI flag.
95−func (a *App) RunNonInteractive(ctx context.Context, prompt string, outputFormat string, quiet bool) error {
95+func (a *App) RunNonInteractive(ctx context.Context, prompt string, quiet bool) error {
9696 slog.Info("Running in non-interactive mode")
9797
9898 // Start spinner if not in quiet mode
@@ -100,8 +100,15 @@ func (a *App) RunNonInteractive(ctx context.Context, prompt string, outputFormat
100100 if !quiet {
101101 spinner = format.NewSpinner(ctx, "Generating")
102102 spinner.Start()
103− defer spinner.Stop()
104103 }
104+ // Helper function to stop spinner once
105+ stopSpinner := func() {
106+ if !quiet && spinner != nil {
107+ spinner.Stop()
108+ spinner = nil
109+ }
110+ }
111+ defer stopSpinner()
105112
106113 const maxPromptLengthForTitle = 100
107114 titlePrefix := "Non-interactive: "
@@ -128,35 +135,42 @@ func (a *App) RunNonInteractive(ctx context.Context, prompt string, outputFormat
128135 return fmt.Errorf("failed to start agent processing stream: %w", err)
129136 }
130137
131− result := <-done
138+ messageEvents := a.Messages.Subscribe(ctx)
139+ readBts := 0
132140
133− // Stop spinner before printing output
134− if !quiet && spinner != nil {
135− spinner.Stop()
136− }
141+ for {
142+ select {
143+ case result := <-done:
144+ stopSpinner()
145+
146+ if result.Error != nil {
147+ if errors.Is(result.Error, context.Canceled) || errors.Is(result.Error, agent.ErrRequestCancelled) {
148+ slog.Info("Agent processing cancelled", "session_id", sess.ID)
149+ return nil
150+ }
151+ return fmt.Errorf("agent processing failed: %w", result.Error)
152+ }
153+
154+ part := result.Message.Content().String()[readBts:]
155+ fmt.Println(part)
137156
138− if result.Error != nil {
139− if errors.Is(result.Error, context.Canceled) || errors.Is(result.Error, agent.ErrRequestCancelled) {
140− slog.Info("Agent processing cancelled", "session_id", sess.ID)
157+ slog.Info("Non-interactive run completed", "session_id", sess.ID)
141158 return nil
142− }
143− return fmt.Errorf("agent processing failed: %w", result.Error)
144− }
145159
146− // Get the text content from the response
147− content := "No content available"
148− if result.Message.Content().String() != "" {
149− content = result.Message.Content().String()
150− }
160+ case event := <-messageEvents:
161+ msg := event.Payload
162+ if msg.SessionID == sess.ID && msg.Role == message.Assistant && len(msg.Parts) > 0 {
163+ stopSpinner()
164+ part := msg.Content().String()[readBts:]
165+ fmt.Print(part)
166+ readBts += len(part)
167+ }
151168
152− out, err := format.FormatOutput(content, outputFormat)
153− if err != nil {
154− return err
169+ case <-ctx.Done():
170+ stopSpinner()
171+ return ctx.Err()
172+ }
155173 }
156−
157− fmt.Println(out)
158− slog.Info("Non-interactive run completed", "session_id", sess.ID)
159− return nil
160174}
161175
162176func (app *App) UpdateAgentModel() error {