@@ -54,79 +54,12 @@ func (a *AnthropicProvider) GenerateCommitMessages(ctx context.Context, diff str
5454 fullPrompt := fmt .Sprintf ("%s\n \n User request: %s\n \n IMPORTANT: Generate exactly %d commit messages, one per line. Do not include any other text, explanations, or formatting - just the commit messages." ,
5555 systemMsg , userPrompt , a .numSuggestions )
5656
57- // Execute claude CLI with haiku model
58- // Using -p flag for print mode and --model for model selection
59- // Pipe prompt via stdin to avoid Windows command line length limits (8191 chars)
60- cmd := exec .CommandContext (ctx , "claude" , "--model" , a .model , "-p" , "-" )
61-
62- stdin , err := cmd .StdinPipe ()
57+ output , err := a .runCLI (ctx , fullPrompt )
6358 if err != nil {
64- return nil , fmt .Errorf ("error creating stdin pipe: %w" , err )
65- }
66-
67- var outputBuf strings.Builder
68- cmd .Stdout = & outputBuf
69- cmd .Stderr = & outputBuf
70-
71- if err := cmd .Start (); err != nil {
72- return nil , fmt .Errorf ("error starting claude CLI: %w" , err )
73- }
74-
75- _ , writeErr := stdin .Write ([]byte (fullPrompt ))
76- stdin .Close ()
77-
78- waitErr := cmd .Wait ()
79-
80- if writeErr != nil {
81- return nil , fmt .Errorf ("error writing to claude CLI stdin: %w" , writeErr )
82- }
83-
84- if waitErr != nil {
85- return nil , fmt .Errorf ("error executing claude CLI: %w\n Output: %s" , waitErr , outputBuf .String ())
86- }
87-
88- output := []byte (outputBuf .String ())
89-
90- // Parse the output - split by newlines and clean
91- content := string (output )
92- lines := strings .Split (content , "\n " )
93-
94- var commitMessages []string
95- for _ , line := range lines {
96- trimmed := strings .TrimSpace (line )
97- // Skip empty lines and lines that look like explanatory text
98- if trimmed == "" {
99- continue
100- }
101- // Skip lines that are clearly not commit messages (too long, contain certain patterns)
102- if len (trimmed ) > 200 {
103- continue
104- }
105- // Skip markdown formatting or numbered lists
106- if strings .HasPrefix (trimmed , "#" ) || strings .HasPrefix (trimmed , "-" ) || strings .HasPrefix (trimmed , "*" ) {
107- // Try to extract the actual commit message
108- parts := strings .SplitN (trimmed , " " , 2 )
109- if len (parts ) == 2 {
110- trimmed = strings .TrimSpace (parts [1 ])
111- }
112- }
113- // Remove numbered list formatting like "1. " or "1) "
114- if len (trimmed ) > 3 {
115- if (trimmed [0 ] >= '0' && trimmed [0 ] <= '9' ) && (trimmed [1 ] == '.' || trimmed [1 ] == ')' ) {
116- trimmed = strings .TrimSpace (trimmed [2 :])
117- }
118- }
119-
120- if trimmed != "" {
121- commitMessages = append (commitMessages , trimmed )
122- }
123-
124- // Stop once we have enough messages
125- if len (commitMessages ) >= a .numSuggestions {
126- break
127- }
59+ return nil , err
12860 }
12961
62+ commitMessages := parseOutputLines (output , a .numSuggestions )
13063 if len (commitMessages ) == 0 {
13164 return nil , fmt .Errorf ("no valid commit messages generated from Claude output" )
13265 }
@@ -163,77 +96,50 @@ func (a *AnthropicProvider) GeneratePRTitles(ctx context.Context, diff string) (
16396 fullPrompt := fmt .Sprintf ("%s\n \n User request: %s\n \n IMPORTANT: Generate exactly %d pull request titles, one per line. Do not include any other text, explanations, or formatting - just the PR titles." ,
16497 systemMsg , userPrompt , a .numSuggestions )
16598
99+ output , err := a .runCLI (ctx , fullPrompt )
100+ if err != nil {
101+ return nil , err
102+ }
103+
104+ prTitles := parseOutputLines (output , a .numSuggestions )
105+ if len (prTitles ) == 0 {
106+ return nil , fmt .Errorf ("no valid PR titles generated from Claude output" )
107+ }
108+
109+ return prTitles , nil
110+ }
111+
112+ // runCLI executes the claude CLI with the given prompt via stdin and returns stdout.
113+ func (a * AnthropicProvider ) runCLI (ctx context.Context , prompt string ) (string , error ) {
114+ // Using -p flag for print mode and --model for model selection
166115 // Pipe prompt via stdin to avoid Windows command line length limits (8191 chars)
167116 cmd := exec .CommandContext (ctx , "claude" , "--model" , a .model , "-p" , "-" )
168117
169118 stdin , err := cmd .StdinPipe ()
170119 if err != nil {
171- return nil , fmt .Errorf ("error creating stdin pipe: %w" , err )
120+ return "" , fmt .Errorf ("error creating stdin pipe: %w" , err )
172121 }
173122
174- var outputBuf strings.Builder
175- cmd .Stdout = & outputBuf
176- cmd .Stderr = & outputBuf
123+ var stdoutBuf , stderrBuf strings.Builder
124+ cmd .Stdout = & stdoutBuf
125+ cmd .Stderr = & stderrBuf
177126
178127 if err := cmd .Start (); err != nil {
179- return nil , fmt .Errorf ("error starting claude CLI: %w" , err )
128+ return "" , fmt .Errorf ("error starting claude CLI: %w" , err )
180129 }
181130
182- _ , writeErr := stdin .Write ([]byte (fullPrompt ))
131+ _ , writeErr := stdin .Write ([]byte (prompt ))
183132 stdin .Close ()
184133
185134 waitErr := cmd .Wait ()
186135
187136 if writeErr != nil {
188- return nil , fmt .Errorf ("error writing to claude CLI stdin: %w" , writeErr )
137+ return "" , fmt .Errorf ("error writing to claude CLI stdin: %w" , writeErr )
189138 }
190139
191140 if waitErr != nil {
192- return nil , fmt .Errorf ("error executing claude CLI: %w\n Output: %s" , waitErr , outputBuf .String ())
193- }
194-
195- output := []byte (outputBuf .String ())
196-
197- // Parse the output - same logic as commit message generation
198- content := string (output )
199- lines := strings .Split (content , "\n " )
200-
201- var prTitles []string
202- for _ , line := range lines {
203- trimmed := strings .TrimSpace (line )
204- if trimmed == "" {
205- continue
206- }
207- if len (trimmed ) > 200 {
208- continue
209- }
210- // Skip markdown formatting or numbered lists
211- if strings .HasPrefix (trimmed , "#" ) || strings .HasPrefix (trimmed , "-" ) || strings .HasPrefix (trimmed , "*" ) {
212- parts := strings .SplitN (trimmed , " " , 2 )
213- if len (parts ) == 2 {
214- trimmed = strings .TrimSpace (parts [1 ])
215- }
216- }
217- // Remove numbered list formatting like "1. " or "1) "
218- if len (trimmed ) > 3 {
219- if (trimmed [0 ] >= '0' && trimmed [0 ] <= '9' ) && (trimmed [1 ] == '.' || trimmed [1 ] == ')' ) {
220- trimmed = strings .TrimSpace (trimmed [2 :])
221- }
222- }
223-
224- if trimmed != "" {
225- prTitles = append (prTitles , trimmed )
226- }
227-
228- // Stop once we have enough titles
229- if len (prTitles ) >= a .numSuggestions {
230- break
231- }
232- }
233-
234- if len (prTitles ) == 0 {
235- return nil , fmt .Errorf ("no valid PR titles generated from Claude output" )
141+ return "" , fmt .Errorf ("error executing claude CLI: %w\n Stderr: %s" , waitErr , stderrBuf .String ())
236142 }
237143
238- return prTitles , nil
144+ return stdoutBuf . String () , nil
239145}
0 commit comments