feat(git): Add Claude as a TextGenerationProvider#1323
feat(git): Add Claude as a TextGenerationProvider#1323keyzou wants to merge 14 commits intopingdotgg:mainfrom
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
can we reuse the model picker from the chat UI? So it's a single select with provider top level, model submenu? |
|
yep, didn't think about that, what do you think ? (updated the screenshot in the PR aswell) Enregistrement.de.l.ecran.2026-03-23.a.19.37.28.mov |
|
looks good. resolve conflicts pls |
c9d1242 to
66463d1
Compare
|
done, rebased on main (updated the video to reflect the recent UI changes on main) |
| return { | ||
| branch: sanitizeBranchFragment(generated.branch), | ||
| } satisfies BranchNameGenerationResult; | ||
| }); |
There was a problem hiding this comment.
Claude branch name generation silently drops image attachments
Medium Severity
The Claude generateBranchName implementation doesn't materialize or pass image attachments to the CLI, unlike the Codex implementation which calls materializeImageAttachments and passes imagePaths via --image flags. The prompt still tells the model to "use images as primary context for visual/UI issues," but the actual image files are never sent — only textual metadata about them is included. This means branch name generation with image attachments produces worse results on Claude compared to Codex.
Additional Locations (1)
There was a problem hiding this comment.
I believe out of scope for this PR ? Do we have cases where we infer the branch name / commit messages from images ?
| "--effort", | ||
| CLAUDE_REASONING_EFFORT, | ||
| "--dangerously-skip-permissions", | ||
| ], |
There was a problem hiding this comment.
Claude CLI JSON schema may break on Windows
Medium Severity
The Claude CLI receives the JSON schema as an inline command-line argument via --json-schema jsonSchemaStr, while on Windows shell is set to true. The JSON string contains double quotes and braces that cmd.exe may interpret or mangle. The Codex implementation avoids this by writing the schema to a temp file and passing the file path instead.
There was a problem hiding this comment.
I think this can be dismissed: the schema should always be simple enough to never cause issues (for now), there should never be any special character outside the quotes and braces from the json in this case? which should already be properly handled by cmd.exe
dbe7e77 to
cb76bce
Compare
|
Left a few items from bugbot, should be fine if left as-is but leaving the last call to the maintainers |
cb76bce to
e30f4b6
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 3 total unresolved issues (including 2 from previous reviews).
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Move limitSection, sanitizeCommitSubject, and sanitizePrTitle into a dedicated textGenerationUtils module so they can be reused by multiple text generation providers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the single DEFAULT_GIT_TEXT_GENERATION_MODEL constant with a DEFAULT_GIT_TEXT_GENERATION_MODEL_BY_PROVIDER map keyed by provider kind, enabling per-provider default models. Update all consumers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nterfaces Introduce a standalone TextGenerationProvider union type and add an optional provider field to all text generation input interfaces, allowing callers to select which backend generates the content. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ClaudeTextGeneration layer that spawns `claude -p` with structured JSON output for commit messages, PR content, and branch names. Introduce a RoutingTextGeneration layer that dispatches to Codex or Claude based on the provider field, and wire it into the server DI graph. Thread the provider selection through GitManager to all text generation call sites. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a provider selector (Codex/Claude) to the git settings panel with dynamic model options per provider. Pass the selected provider through to the stacked action mutation. Also fix a pre-existing bug where the model field name was incorrect in the RPC call. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Match the pattern already used by Codex (CODEX_REASONING_EFFORT) to make the setting visible and easy to change. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract prompt construction logic into buildCommitMessagePrompt, buildPrContentPrompt, and buildBranchNamePrompt in new textGenerationPrompts.ts - Replace duplicate normalizeClaudeError and normalizeCodexError with shared normalizeCliError function parameterized by CLI name - Update Claude and Codex text generation layers to use shared utilities, reducing duplication - Add comprehensive tests for prompt builders and error normalization
- Consolidate provider and model selection into reusable component - Replace getAppModelOptions with getCustomModelOptionsByProvider - Simplifies settings UI and enables reuse across the app
Remove explicit result interfaces with incorrect type annotations (Schema.Struct.Type<any>) and let TypeScript infer return types. Split the ternary schema assignment into separate return branches so TypeScript preserves a proper union instead of widening to any. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Both ClaudeTextGeneration and CodexTextGeneration had identical logic to convert an Effect Schema into a flat JSON Schema object. Move it into textGenerationUtils.ts as a single shared helper. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pass selectedModel (scoped to the active provider) through to getAppModelOptions so non-built-in models appear in the dropdown. Restore the per-setting reset button on the git writing model row. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pass input.textGenerationProvider to runFeatureBranchStep so the routing layer respects the user's provider choice instead of always falling back to Codex. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
20a38c2 to
b141993
Compare


What Changed
I suggest reviewing commit-by-commit :)
I'm also not too familiar with Effect, so there might be some AI slop here and there, don't hesitate to flag it
I saw a similar PR at #1222 but since the change was not enough, I wanted to take a stab at the issue myself (not sure about the proper open-source etiquette here though)
Fixes #1221
Why
Pretty straightforward: I don't have Codex, so Git-related operations couldn't work for me :)
UI Changes
Here's the setting page with the Git section using Claude:
Enregistrement.de.l.ecran.2026-03-24.a.09.03.52.mov
Here's a demo of the branch name generation working (not sure I have the right flow) -- old model picker, see the video above for the updated version ^:
Enregistrement.de.l.ecran.2026-03-23.a.02.17.41.mp4
And here's a demo of committing and pushing (thus generating a commit message) -- old model picker, see the video above for the updated version:
Enregistrement.de.l.ecran.2026-03-23.a.02.15.14.mp4
Checklist
Note
Add Claude as a selectable text generation provider for git content generation
ClaudeTextGenerationLivelayer inClaudeTextGeneration.tsthat invokes the Claude CLI (claude -p --output-format json) with JSON schema validation to generate commit messages, PR content, and branch names.RoutingTextGenerationLiveinRoutingTextGeneration.tsto replace the single Codex provider; routes requests to Codex or Claude based on aproviderfield on each input.textGenerationPrompts.tsandtextGenerationUtils.ts, consumed by both providers.textGenerationProvidersetting ('codex' | 'claudeAgent', default'codex') in app settings and theGitRunStackedActionInputAPI contract; the settings UI gains a provider/model picker.claudeCLI binary being present at runtime; missing binary maps to aTextGenerationErrorvianormalizeCliError.Macroscope summarized ec38c62.
Note
Medium Risk
Adds a new Claude-backed text generation path and routes git commit/PR/branch generation between two CLIs based on user/config input, touching both server orchestration and web settings. Risk is mainly around provider selection/plumbing, CLI invocation/timeout handling, and keeping Codex behavior unchanged after the shared refactor.
Overview
Adds a new
ClaudeTextGenerationlayer that runs theclaudeCLI with JSON-schema–validated structured output (including timeouts/error normalization) for commit message, PR content, and branch name generation.Introduces
RoutingTextGenerationLiveand wires it into the server so each text-generation request can selectcodexvsclaudeAgentvia a newproviderfield;GitManagerand RPC inputs propagatetextGenerationProviderthrough stacked git actions.Refactors Codex text generation to reuse shared
textGenerationPrompts.tsandtextGenerationUtils.ts, adds tests for prompt building/error normalization, and updates contracts + web settings/UI to let users choose a Git writing provider and model (with per-provider default models viaDEFAULT_GIT_TEXT_GENERATION_MODEL_BY_PROVIDER).Written by Cursor Bugbot for commit ec38c62. This will update automatically on new commits. Configure here.