Skip to content

feat(scm): generate commit messages from the Source Control panel - #1218

Open
Rafael-Silva-Oliveira wants to merge 1 commit into
Zoo-Code-Org:mainfrom
Rafael-Silva-Oliveira:feat/auto-commit-button
Open

feat(scm): generate commit messages from the Source Control panel#1218
Rafael-Silva-Oliveira wants to merge 1 commit into
Zoo-Code-Org:mainfrom
Rafael-Silva-Oliveira:feat/auto-commit-button

Conversation

@Rafael-Silva-Oliveira

@Rafael-Silva-Oliveira Rafael-Silva-Oliveira commented Aug 10, 2026

Copy link
Copy Markdown

Related GitHub Issue

Part of: #145

This PR implements most of the #145 sub-issue tree in one piece:

Issue Status in this PR
#282 Git context collector Closes -- getCommitContext() in src/utils/git.ts
#283 Commit-message support prompt type Closes -- COMMIT_MESSAGE in src/shared/support-prompt.ts
#284 Commit-message generator service Closes -- src/services/commit-message/
#285 Dedicated API profile setting Closes -- commitMessageApiConfigId
#286 Register command in VS Code SCM Closes -- zoo-code.generateCommitMessage + scm/title
#287 Resolve Git repository from SCM context Closes -- matches SourceControl.rootUri against the git API
#288 Insert message into commit input box Closes -- writes repository.inputBox.value
#289 Progress, cancellation, and error UX Partial -- progress and error handling done; no cancel button (see Additional Notes)
#290 Commit-message prompt settings UI Closes -- inherited from the support-prompt system
#291 Commit-message API profile settings UI Closes -- CommitMessageModelSelect in Providers
#292 Privacy-safe telemetry Not addressed -- left for a follow-up

Happy to split this along those lines if that's easier to review -- see "Relationship
to the existing stack" below.

Description

Adds a Zoo Code button to the Source Control title bar. Click it and the current
changes are summarized into a commit message, written straight into the commit
input box.

The implementation leans on things Zoo Code already has, so the new surface area is
small: one git helper, one ~110-line service, one React <Select>.

Where the changes come from. getCommitContext() in src/utils/git.ts reads
staged changes first, since that's what a commit will actually contain. When nothing
is staged it falls back to the whole working tree, so the button still does something
useful before you've staged. The fallback path uses git status --short rather than a
diff, because untracked files don't appear in any diff and would otherwise be
invisible to the model. Oversized diffs go through the existing truncateOutput
helper, and --unified=1 keeps the prompt lean without hiding what changed.

The prompt is editable. COMMIT_MESSAGE is registered in
src/shared/support-prompt.ts alongside ENHANCE and the rest, which means it picks
up the existing Prompts settings UI for free -- textarea, reset button, and
customSupportPrompts persistence, with no new UI code. The default asks for
Conventional Commits and explicitly tells the model to account for every changed file
rather than letting the largest file speak for the rest. That instruction is load
bearing: without it, models happily describe one file and silently drop the others.

Model selection. commitMessageApiConfigId mirrors the existing
enhancementApiConfigId pattern exactly, including the listApiConfigMeta.find(...)
guard before getProfile() so a deleted profile falls back to the active one instead
of throwing. Summarizing a diff doesn't need a frontier model, and pointing this at a
small fast profile is the single biggest lever on how quickly the button responds.

One change outside the feature. packages/build/src/types.ts declared
icon: z.string().optional(), allowing only a codicon string. The themed
{light, dark} icon this feature needs would have thrown in contributesSchema.parse()
during the nightly manifest build -- a failure invisible in normal dev, since only
vsix:nightly exercises that path. I widened the field to a union.

Reviewer focus:

  • Whether the staged-first/working-tree fallback is the behavior you want, and whether
    surfacing untracked files via git status --short in the fallback is right.
  • Whether commitMessageApiConfigId belongs in Providers (where it is now, next to the
    profile it selects) or in Prompts next to the enhancement picker.
  • The packages/build schema widening.

Relationship to the existing stack

#145 has a split stack from @Mirrowel -- #298 (git context), #299 (generator), #300
(SCM integration), #301 (settings). Those PRs are still technically open but have had
no activity since 2026-06-30, and the feature has been unavailable to users the whole
time. I picked it up on that basis and built this independently, then found the stack
afterwards. Not a criticism of that work -- just an attempt to get the feature landed.

The honest comparison: that stack is more thorough where it overlaps. #298 alone is
~996 lines and handles rename/copy status codes, -z null-delimited parsing, synthetic
diffs for untracked files, and binary-file summarization. This PR does none of that --
it shells out to git diff and passes the output through. If those cases matter,
#298 is the better foundation and I'd happily see it revived instead.

What this offers is a smaller diff, a feature that works end to end in one piece, and
a branch that is current with main today.

If @Mirrowel wants to continue, I'll close this and offer review there instead. If not,
this is ready now, and I'm glad to reshape it into the same four-part split if the
maintainers prefer that granularity.

Test Procedure

Every job in code-qa.yml was run locally against this branch:

Check Result
pnpm lint 11/11 packages pass
pnpm check-types 11/11 packages pass
node scripts/find-missing-translations.js pass -- all 17 locales complete
pnpm knip no findings for new code
invisible/homoglyph Unicode scan no tracked files match
pnpm turbo run test:coverage --filter='!@roo-code/core' pass
pnpm turbo run test:coverage:unit --filter=@roo-code/core pass
pnpm turbo run test:coverage:integration --filter=@roo-code/core pass
pnpm --filter ./src vsix packages cleanly

Full src suite: 7387 passed, 37 skipped. New coverage:

  • src/utils/__tests__/git.spec.ts -- staged path, working-tree fallback, clean-tree
    null, plus a test asserting diff commands contain no shell metacharacters (see below).
  • src/services/commit-message/__tests__/generateCommitMessage.spec.ts -- profile
    selection, stale-profile fallback, fence/quote stripping, multi-repo selection by
    SourceControl.rootUri, no-changes path, error path.
  • webview-ui/src/components/settings/__tests__/CommitMessageModelSelect.spec.tsx --
    rendering, sentinel handling, setCachedStateField wiring.
  • SettingsView.spec.tsx -- the setting survives the cachedState round trip into the
    updateSettings payload.

Translations for all 17 locales were written for the four new key groups, not left as
English fallbacks -- find-missing-translations.js gates on this and would have failed.

A note on the git tests. An earlier revision of this branch used :(exclude)
pathspecs to skip lockfiles. The unit tests passed, because they mock exec. Real git
rejected the command outright: exec runs through cmd.exe on Windows, which does not
strip the single quotes those pathspecs require. I found it only by running against a
real repository. The exclusions are gone, and there's now a test asserting the diff
argument string stays free of shell metacharacters -- but the general caveat stands
that the mocked git tests cannot validate git syntax.

Manual verification, in a scratch repo with one staged change, one unstaged change,
and one untracked file:

  1. Open Source Control -- the Zoo Code icon appears in the title bar.
  2. Click it -- status bar shows progress, message lands in the commit input box.
  3. Unstage everything -- click again, fallback path produces a message covering the
    untracked file.
  4. Commit everything -- click again, "No changes to commit", input box untouched.
  5. Settings -> Providers -> Commit Message Model -> pick a profile -> Save -> reload
    the window -- selection persists.
  6. Settings -> Prompts -> Commit Message -> edit -> regenerate -> edited prompt takes
    effect; reset button restores the default.

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and/or updated tests have been added to cover my changes (if applicable).
  • Visual Snapshot (UI changes only): see below.
  • Documentation Impact: I have considered if my changes require documentation updates.
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Screenshots below are a review aid, not a substitute.

image

The model picker in Settings -> Providers:

image

Documentation Updates

  • No documentation updates are required.
  • Yes, documentation updates are required.

This adds a user-facing button and two settings, so the docs repo likely wants a short
page covering the Source Control button, the Commit Message Model picker, and the
editable prompt. Happy to open that PR if this direction is accepted.

Additional Notes

Aligns with the roadmap's Enhanced User Experience goal -- it removes a small,
repeated friction point and makes Zoo Code useful from a panel where it previously had
no presence.

Two limitations worth stating plainly, both relevant to #289:

#292 (telemetry) is untouched and remains open.

Summary by CodeRabbit

  • New Features
    • Added a Source Control command to generate commit messages from staged or working-tree changes.
    • Added progress and localized feedback for missing repositories, generation failures, and unchanged files.
    • Added an optional dedicated model configuration for commit-message generation.
    • Added support for light and dark command icons.
  • Localization
    • Added commit-message prompts, settings, command labels, and status messages across supported languages.
  • Tests
    • Added coverage for generation, repository states, model selection, error handling, and settings persistence.

Adds a Zoo Code button to the Source Control title bar that summarizes the
current changes into a commit message and writes it into the commit input box.

- Collects staged changes first, falling back to the whole working tree when
  nothing is staged so the button still works before staging. `git status
  --short` is used on the fallback path so untracked files stay visible.
- Registers COMMIT_MESSAGE as a support prompt, so the default Conventional
  Commits template is editable from Settings > Prompts with a reset button,
  reusing the existing customSupportPrompts plumbing.
- Adds a `commitMessageApiConfigId` setting in Settings > Providers to pick a
  small, fast profile for this one task, mirroring `enhancementApiConfigId`.
  Falls back to the active profile when unset or when the saved profile has
  since been deleted.

`packages/build` had to widen `commandsSchema.icon` to accept a themed
{light, dark} pair; it previously allowed only a codicon string, which would
have failed the nightly manifest build.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds AI-generated commit messages from Git Source Control. The change collects staged or working-tree context, selects a provider profile, inserts the generated message into the repository commit input, exposes a configurable model setting, registers the command, and adds tests and localization.

Changes

Commit-message generation flow

Layer / File(s) Summary
Git context and generation service
src/utils/git.ts, src/services/commit-message/index.ts, src/shared/support-prompt.ts, src/services/commit-message/__tests__/generateCommitMessage.spec.ts, src/utils/__tests__/git.spec.ts
Git context now includes staged, working-tree, and untracked changes. The service resolves the repository, selects a provider, generates a Conventional Commits message, cleans the output, and writes it to the commit input. Tests cover repository selection, fallbacks, failures, progress, and empty changes.
Command and Source Control integration
packages/build/src/types.ts, packages/types/src/vscode.ts, src/activate/registerCommands.ts, src/package.json, src/package.nls*.json, src/i18n/locales/*/common.json
The generateCommitMessage command is registered and added to the Git Source Control menu. Command icons support light and dark image paths. Command titles and generation status messages are localized.
Provider configuration and settings UI
packages/types/src/global-settings.ts, packages/types/src/vscode-extension-host.ts, src/core/webview/ClineProvider.ts, webview-ui/src/components/settings/*, webview-ui/src/i18n/locales/*/prompts.json, webview-ui/src/i18n/locales/*/settings.json
commitMessageApiConfigId flows through global settings, extension state, provider state, and settings submission. CommitMessageModelSelect supports dedicated profiles and fallback to the active configuration. Tests cover selection and state persistence.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

Possibly related PRs

  • Zoo-Code-Org/Zoo-Code#281 — Shares command registration, manifest contribution, command IDs, and localization changes.
  • Zoo-Code-Org/Zoo-Code#904 — Shares dedicated provider-profile settings propagated through global settings, extension state, and the settings UI.
  • Zoo-Code-Org/Zoo-Code#277 — Shares global settings, extension state, and provider-state propagation patterns.

Suggested labels: enhancement, awaiting-review

Suggested reviewers: edelauna

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely describes the primary feature: generating commit messages from the VS Code Source Control panel.
Description check ✅ Passed The description covers the issue, implementation, testing, checklist, limitations, documentation impact, and reviewer focus in substantial detail.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.30159% with 8 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/services/commit-message/index.ts 82.35% 1 Missing and 5 partials ⚠️
src/activate/registerCommands.ts 0.00% 1 Missing ⚠️
...ebview-ui/src/components/settings/SettingsView.tsx 0.00% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@Mirrowel

Mirrowel commented Aug 10, 2026

Copy link
Copy Markdown

@Rafael-Silva-Oliveira If you want to join up on a PR or merge both - i don't mind. Funnily enough: PRs might need to be republished anyway as stacked PRs now to split the work correctly. As reviewing 4 separate PRs that all base on the previous one - is a lot of work. And it needs to be split, because there is a decent bit of code to catch edge cases, format better,etc.

I am very happy with what i accomplished, but my adhd means that when i lost focus - the pr kinda got left in the forever box.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (3)
src/utils/__tests__/git.spec.ts (1)

378-378: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Explain or replace the double assertions.

as unknown as typeof exec bypasses the overload checks for exec. The nearby comment explains the fake return value, but it does not explain why each callback implementation safely matches typeof exec.

Use a typed mock adapter where possible. If the cast is unavoidable, add a nearby comment that explains the overload mismatch. As per coding guidelines, “Use double assertions only as a last resort and explain them with a comment.”

Also applies to: 416-416

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/__tests__/git.spec.ts` at line 378, Update the mocked exec setup
around vitest.mocked(exec) at both occurrences to avoid the double assertion by
using a typed mock adapter compatible with exec overloads; if that is not
feasible, retain the cast only with a nearby comment explicitly documenting the
overload mismatch and why it is safe.

Source: Coding guidelines

webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx (1)

376-398: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test the unset save path.

This test covers a saved profile ID only. Add a test that selects “Use currently selected API configuration,” saves, and expects commitMessageApiConfigId: "" in updatedSettings.

This verifies that the unset value is not omitted during message serialization.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx` around
lines 376 - 398, Add a test alongside “includes the commit message model in the
saved settings” that selects “Use currently selected API configuration,” saves
the settings, and asserts the updateSettings message contains
commitMessageApiConfigId set to an empty string in updatedSettings. Ensure the
assertion verifies the unset value is serialized rather than omitted.

Source: Coding guidelines

webview-ui/src/components/settings/__tests__/CommitMessageModelSelect.spec.tsx (1)

12-28: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Type the Select test double.

The any props and event hide the onValueChange contract. In particular, getAttribute() can return null, although the production callback receives a string.

Define typed mock props and use dataset.nextValue with a null check before calling onValueChange.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@webview-ui/src/components/settings/__tests__/CommitMessageModelSelect.spec.tsx`
around lines 12 - 28, Type the Select test double’s props and click event
instead of using any, especially in Select and its onValueChange callback. Read
the value from dataset.nextValue, check that it is defined, then invoke
onValueChange with the resulting string to preserve the production contract;
apply suitable typed props to the related SelectTrigger, SelectValue,
SelectContent, and SelectItem mocks.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/i18n/locales/ca/common.json`:
- Line 48: Update the Catalan translation values for commit_message_failed and
the corresponding occurrence to replace “missatge de comissió” with the
established “missatge de confirmació” or “missatge de commit” terminology,
preserving the existing error placeholder.

In `@src/package.nls.ca.json`:
- Line 19: Update the Catalan value for command.generateCommitMessage.title to
use “commit” or the repository’s established Catalan Git terminology instead of
“comissió”; leave the command key and surrounding translations unchanged.

In `@src/services/commit-message/index.ts`:
- Line 87: Update getCommitContext to detect when HEAD is unborn before running
the working-tree fallback, and return usable status context or compare changes
against an empty baseline instead of invoking git diff HEAD. Preserve existing
behavior for repositories with an initial commit, and add a regression test
covering working-tree changes in an uncommitted repository.

In `@src/utils/git.ts`:
- Around line 398-400: Update the unstaged fallback’s git diff invocation in the
function containing the `status`, `diff`, and `truncateOutput` flow to remove
the `HEAD` argument and run `git diff` with only `COMMIT_DIFF_ARGS`, preserving
the existing output formatting and truncation.

In `@webview-ui/src/components/settings/CommitMessageModelSelect.tsx`:
- Around line 35-43: Update the label and SelectTrigger in
CommitMessageModelSelect to associate them accessibly: assign a unique id to the
setting label and reference that id via SelectTrigger’s aria-labelledby
attribute. Add or update the relevant component test to verify the
label-to-trigger relationship.

In `@webview-ui/src/i18n/locales/ca/prompts.json`:
- Around line 107-110: Correct the Catalan Git terminology in
webview-ui/src/i18n/locales/ca/prompts.json lines 107-110 by replacing
“comissió” in the COMMIT_MESSAGE label and description with “commit”
terminology; also update webview-ui/src/i18n/locales/ca/settings.json lines
359-363 by replacing “missatges de comissió” with the corresponding Git commit
wording.

---

Nitpick comments:
In `@src/utils/__tests__/git.spec.ts`:
- Line 378: Update the mocked exec setup around vitest.mocked(exec) at both
occurrences to avoid the double assertion by using a typed mock adapter
compatible with exec overloads; if that is not feasible, retain the cast only
with a nearby comment explicitly documenting the overload mismatch and why it is
safe.

In
`@webview-ui/src/components/settings/__tests__/CommitMessageModelSelect.spec.tsx`:
- Around line 12-28: Type the Select test double’s props and click event instead
of using any, especially in Select and its onValueChange callback. Read the
value from dataset.nextValue, check that it is defined, then invoke
onValueChange with the resulting string to preserve the production contract;
apply suitable typed props to the related SelectTrigger, SelectValue,
SelectContent, and SelectItem mocks.

In `@webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx`:
- Around line 376-398: Add a test alongside “includes the commit message model
in the saved settings” that selects “Use currently selected API configuration,”
saves the settings, and asserts the updateSettings message contains
commitMessageApiConfigId set to an empty string in updatedSettings. Ensure the
assertion verifies the unset value is serialized rather than omitted.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1ae74a4a-5156-4ee1-9dc9-51cd851467ef

📥 Commits

Reviewing files that changed from the base of the PR and between abaf732 and 9052dcb.

📒 Files selected for processing (88)
  • packages/build/src/types.ts
  • packages/types/src/global-settings.ts
  • packages/types/src/vscode-extension-host.ts
  • packages/types/src/vscode.ts
  • src/activate/registerCommands.ts
  • src/core/webview/ClineProvider.ts
  • src/i18n/locales/ca/common.json
  • src/i18n/locales/de/common.json
  • src/i18n/locales/en/common.json
  • src/i18n/locales/es/common.json
  • src/i18n/locales/fr/common.json
  • src/i18n/locales/hi/common.json
  • src/i18n/locales/id/common.json
  • src/i18n/locales/it/common.json
  • src/i18n/locales/ja/common.json
  • src/i18n/locales/ko/common.json
  • src/i18n/locales/nl/common.json
  • src/i18n/locales/pl/common.json
  • src/i18n/locales/pt-BR/common.json
  • src/i18n/locales/ru/common.json
  • src/i18n/locales/tr/common.json
  • src/i18n/locales/vi/common.json
  • src/i18n/locales/zh-CN/common.json
  • src/i18n/locales/zh-TW/common.json
  • src/package.json
  • src/package.nls.ca.json
  • src/package.nls.de.json
  • src/package.nls.es.json
  • src/package.nls.fr.json
  • src/package.nls.hi.json
  • src/package.nls.id.json
  • src/package.nls.it.json
  • src/package.nls.ja.json
  • src/package.nls.json
  • src/package.nls.ko.json
  • src/package.nls.nl.json
  • src/package.nls.pl.json
  • src/package.nls.pt-BR.json
  • src/package.nls.ru.json
  • src/package.nls.tr.json
  • src/package.nls.vi.json
  • src/package.nls.zh-CN.json
  • src/package.nls.zh-TW.json
  • src/services/commit-message/__tests__/generateCommitMessage.spec.ts
  • src/services/commit-message/index.ts
  • src/shared/support-prompt.ts
  • src/utils/__tests__/git.spec.ts
  • src/utils/git.ts
  • webview-ui/src/components/settings/CommitMessageModelSelect.tsx
  • webview-ui/src/components/settings/SettingsView.tsx
  • webview-ui/src/components/settings/__tests__/CommitMessageModelSelect.spec.tsx
  • webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx
  • webview-ui/src/i18n/locales/ca/prompts.json
  • webview-ui/src/i18n/locales/ca/settings.json
  • webview-ui/src/i18n/locales/de/prompts.json
  • webview-ui/src/i18n/locales/de/settings.json
  • webview-ui/src/i18n/locales/en/prompts.json
  • webview-ui/src/i18n/locales/en/settings.json
  • webview-ui/src/i18n/locales/es/prompts.json
  • webview-ui/src/i18n/locales/es/settings.json
  • webview-ui/src/i18n/locales/fr/prompts.json
  • webview-ui/src/i18n/locales/fr/settings.json
  • webview-ui/src/i18n/locales/hi/prompts.json
  • webview-ui/src/i18n/locales/hi/settings.json
  • webview-ui/src/i18n/locales/id/prompts.json
  • webview-ui/src/i18n/locales/id/settings.json
  • webview-ui/src/i18n/locales/it/prompts.json
  • webview-ui/src/i18n/locales/it/settings.json
  • webview-ui/src/i18n/locales/ja/prompts.json
  • webview-ui/src/i18n/locales/ja/settings.json
  • webview-ui/src/i18n/locales/ko/prompts.json
  • webview-ui/src/i18n/locales/ko/settings.json
  • webview-ui/src/i18n/locales/nl/prompts.json
  • webview-ui/src/i18n/locales/nl/settings.json
  • webview-ui/src/i18n/locales/pl/prompts.json
  • webview-ui/src/i18n/locales/pl/settings.json
  • webview-ui/src/i18n/locales/pt-BR/prompts.json
  • webview-ui/src/i18n/locales/pt-BR/settings.json
  • webview-ui/src/i18n/locales/ru/prompts.json
  • webview-ui/src/i18n/locales/ru/settings.json
  • webview-ui/src/i18n/locales/tr/prompts.json
  • webview-ui/src/i18n/locales/tr/settings.json
  • webview-ui/src/i18n/locales/vi/prompts.json
  • webview-ui/src/i18n/locales/vi/settings.json
  • webview-ui/src/i18n/locales/zh-CN/prompts.json
  • webview-ui/src/i18n/locales/zh-CN/settings.json
  • webview-ui/src/i18n/locales/zh-TW/prompts.json
  • webview-ui/src/i18n/locales/zh-TW/settings.json

"reset_support_prompt": "Ha fallat el restabliment del missatge de suport",
"enhance_prompt": "Ha fallat la millora del missatge",
"commit_message_no_repository": "No s'ha trobat cap repositori Git al plafó de control de codi font.",
"commit_message_failed": "No s'ha pogut generar el missatge de comissió: {{error}}",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the Catalan term for a Git commit.

missatge de comissió means “commission message.” Use missatge de confirmació or missatge de commit consistently.

Proposed fix
-		"commit_message_failed": "No s'ha pogut generar el missatge de comissió: {{error}}",
+		"commit_message_failed": "No s'ha pogut generar el missatge de confirmació: {{error}}",
...
-		"commit_message_generating": "Generant el missatge de comissió...",
+		"commit_message_generating": "Generant el missatge de confirmació...",

Also applies to: 169-169

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/i18n/locales/ca/common.json` at line 48, Update the Catalan translation
values for commit_message_failed and the corresponding occurrence to replace
“missatge de comissió” with the established “missatge de confirmació” or
“missatge de commit” terminology, preserving the existing error placeholder.

Comment thread src/package.nls.ca.json
"command.acceptInput.title": "Acceptar Entrada/Suggeriment",
"command.showRipgrepDiagnostic.title": "Mostra el diagnòstic de Ripgrep",
"command.toggleAutoApprove.title": "Alternar Auto-Aprovació",
"command.generateCommitMessage.title": "Genera missatge de comissió",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use correct Git terminology in the Catalan title.

comissió means “commission”, not a Git commit. Replace it with commit or the repository’s established Catalan term for Git commits.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/package.nls.ca.json` at line 19, Update the Catalan value for
command.generateCommitMessage.title to use “commit” or the repository’s
established Catalan Git terminology instead of “comissió”; leave the command key
and surrounding translations unchanged.

return
}

const gitContext = await getCommitContext(repository.rootUri.fsPath)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Support repositories without an initial commit.

Line 87 calls getCommitContext, whose working-tree fallback runs git diff HEAD. In an unborn repository, HEAD does not exist. The command rejects and commit-message generation fails instead of using the detected changes.

Detect an unborn HEAD in getCommitContext. Return usable status context or diff against an empty baseline. Add a regression test for an uncommitted repository with working-tree changes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/services/commit-message/index.ts` at line 87, Update getCommitContext to
detect when HEAD is unborn before running the working-tree fallback, and return
usable status context or compare changes against an empty baseline instead of
invoking git diff HEAD. Preserve existing behavior for repositories with an
initial commit, and add a regression test covering working-tree changes in an
uncommitted repository.

Comment thread src/utils/git.ts
Comment on lines +398 to +400
const { stdout: diff } = await execAsync(`git diff HEAD ${COMMIT_DIFF_ARGS}`, options)
const output = `Unstaged changes:\n\n${status.trim()}\n\n${diff.trim()}`.trim()
return truncateOutput(output, GIT_OUTPUT_LINE_LIMIT)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo="$(mktemp -d)"
trap 'rm -rf "$repo"' EXIT

git init -q "$repo"
printf 'example\n' > "$repo/file.txt"

if git -C "$repo" diff HEAD --unified=1 >/dev/null 2>&1; then
  echo "Expected git diff HEAD to fail before the first commit" >&2
  exit 1
fi

git -C "$repo" diff --unified=1 >/dev/null

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 159


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="$(fd -t f '^git\.ts$' . | head -n 1)"
printf '%s\n' "FILE=$file"
sed -n '1,45p' "$file"
sed -n '340,420p' "$file"
rg -n -C 5 'getCommitContext|COMMIT_DIFF_ARGS|STAGED|git diff' "$file"

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 430


🏁 Script executed:

#!/bin/bash
set -euo pipefail

mapfile -t files < <(fd -t f 'git\.ts$' .)
printf '%s\n' "${files[@]}"

target="$(printf '%s\n' "${files[@]}" | grep -E '(^|/)src/utils/git\.ts$' | head -n 1)"
test -n "$target"
printf '%s\n' "TARGET=$target"
wc -l "$target"
sed -n '1,55p' "$target"
sed -n '350,415p' "$target"
rg -n -C 8 'getCommitContext|COMMIT_DIFF_ARGS|git diff|staged|status' "$target"

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 211


🏁 Script executed:

#!/bin/bash
set -euo pipefail

target="src/utils/git.ts"
test -f "$target"
printf '%s\n' "TARGET=$target"
wc -l "$target"
sed -n '1,55p' "$target"
sed -n '350,415p' "$target"
rg -n -C 8 'getCommitContext|COMMIT_DIFF_ARGS|git diff|staged|status' "$target"

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 9425


Avoid requiring HEAD in the unstaged fallback.

In an unborn repository, git diff HEAD --unified=1 fails after git status --short detects changes. Use git diff ${COMMIT_DIFF_ARGS} to preserve tracked working-tree diffs without requiring an initial commit.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/git.ts` around lines 398 - 400, Update the unstaged fallback’s git
diff invocation in the function containing the `status`, `diff`, and
`truncateOutput` flow to remove the `HEAD` argument and run `git diff` with only
`COMMIT_DIFF_ARGS`, preserving the existing output formatting and truncation.

Comment on lines +35 to +43
<label className="block font-medium mb-1">{t("settings:providers.commitMessageModel.label")}</label>
<Select
value={commitMessageApiConfigId || USE_CURRENT_CONFIG}
onValueChange={(value) =>
setCachedStateField("commitMessageApiConfigId", value === USE_CURRENT_CONFIG ? "" : value)
}>
<SelectTrigger data-testid="commit-message-model-select" className="w-full">
<SelectValue placeholder={t("settings:providers.commitMessageModel.useCurrentConfig")} />
</SelectTrigger>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e
file="$(fd -t f 'CommitMessageModelSelect\.tsx$' . | head -n 1)"
printf '%s\n' "FILE: $file"
cat -n "$file"
printf '\n-- SelectTrigger and label patterns --\n'
rg -n -C 3 'SelectTrigger|aria-labelledby|htmlFor=|<label' webview-ui/src | head -n 240
printf '\n-- Radix Select dependency/source references --\n'
rg -n '"`@radix-ui/react-select`"|from "`@radix-ui/react-select`"|SelectTrigger' package.json webview-ui package-lock.json pnpm-lock.yaml yarn.lock 2>/dev/null | head -n 160

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 36050


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '-- shared Select implementation --'
cat -n webview-ui/src/components/ui/select.tsx | sed -n '1,80p'
printf '\n%s\n' '-- CommitMessageModelSelect test --'
cat -n webview-ui/src/components/settings/__tests__/CommitMessageModelSelect.spec.tsx
printf '\n%s\n' '-- related accessibility assertions and test tooling --'
rg -n -C 3 'toHaveAccessibleName|accessible name|aria-labelledby|axe|jest-axe|role="combobox"|getByRole\(.*combobox' webview-ui/src webview-ui/package.json | head -n 240

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 29400


Associate the setting label with SelectTrigger.

The sibling <label> does not label the Radix trigger. Add an ID to the label, set aria-labelledby on SelectTrigger, and test the relationship.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webview-ui/src/components/settings/CommitMessageModelSelect.tsx` around lines
35 - 43, Update the label and SelectTrigger in CommitMessageModelSelect to
associate them accessibly: assign a unique id to the setting label and reference
that id via SelectTrigger’s aria-labelledby attribute. Add or update the
relevant component test to verify the label-to-trigger relationship.

Comment on lines +107 to +110
"COMMIT_MESSAGE": {
"label": "Missatge de comissió",
"description": "Resumeix els teus canvis en un missatge de comissió. Disponible mitjançant la icona de Zoo Code al plafó de control de codi font, que escriu el resultat directament al camp del missatge de comissió."
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Correct the Catalan Git terminology.

comissió means “commission,” not a Git commit. Use commit in both strings.

  • webview-ui/src/i18n/locales/ca/prompts.json#L107-L110: replace “Missatge de comissió” and the description reference with Git commit terminology.
  • webview-ui/src/i18n/locales/ca/settings.json#L359-L363: replace “missatges de comissió” with Git commit terminology.
📍 Affects 2 files
  • webview-ui/src/i18n/locales/ca/prompts.json#L107-L110 (this comment)
  • webview-ui/src/i18n/locales/ca/settings.json#L359-L363
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webview-ui/src/i18n/locales/ca/prompts.json` around lines 107 - 110, Correct
the Catalan Git terminology in webview-ui/src/i18n/locales/ca/prompts.json lines
107-110 by replacing “comissió” in the COMMIT_MESSAGE label and description with
“commit” terminology; also update webview-ui/src/i18n/locales/ca/settings.json
lines 359-363 by replacing “missatges de comissió” with the corresponding Git
commit wording.

@github-actions github-actions Bot added the awaiting-review PR changes are ready and waiting for maintainer re-review label Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-review PR changes are ready and waiting for maintainer re-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants