Skip to content

feat(ai-ide): add AI-generated commit message button#17669

Open
sgraband wants to merge 2 commits into
masterfrom
sg/commit-agent
Open

feat(ai-ide): add AI-generated commit message button#17669
sgraband wants to merge 2 commits into
masterfrom
sg/commit-agent

Conversation

@sgraband

Copy link
Copy Markdown
Contributor

What it does

Adds an AI-powered "generate commit message" button to the SCM commit widget.
The work spans two packages.

@theia/ai-terminal gets a new PredefinedShellTool base class. It is an
abstract ToolProvider for tools that run a fixed, hardcoded shell command.
Subclasses declare a typed parameter schema and a buildCommand(args) method
that assembles the exact command. The LLM only supplies typed arguments, so the
command itself is fully controlled by the subclass. Unlike shellExecute,
instances do not consult ShellCommandPermissionService and do not need to
appear on the user's allow/deny lists. The tool itself participates in the
regular ToolConfirmationMode flow.

@theia/ai-ide uses that to add the commit-message generator:

  • GetGitChangesTool (getGitChanges) returns the repository's git diff.
    With stagedOnly = true it runs git diff --cached. With stagedOnly = false
    it combines git diff HEAD with the contents of untracked, non-ignored files
    (rendered as addition diffs via git diff --no-index) so brand-new files
    reach the model. It is scoped to the selected SCM repository's root.
  • CommitMessageAgent is an AbstractStreamParsingChatAgent with its own
    prompt template. It is intentionally not registered as a ChatAgent: it does
    not appear in the @-mention list and is not invokable from the chat panel.
  • CommitMessageRunner drives the agent silently against a private
    MutableChatModel (no chat-panel session), writes the resulting message into
    the SCM commit input, and handles cancellation, the overwrite-confirm prompt,
    and a one-time tool-allow gate that asks the user to flip getGitChanges to
    ALWAYS_ALLOW when it is currently on CONFIRM or DISABLED. The dialog
    copy differs between the two cases.
  • AiAwareScmCommitWidget rebinds the SCM commit widget to overlay two sparkle
    buttons (staged / all). It is gated on AIActivationService.isActive, so
    users with AI globally disabled keep the stock SCM input with no overlay and
    no extra padding. While one scope is generating, the other scope's button is
    disabled with a tooltip explaining the situation.
  • CommitMessageCommandContribution exposes two commands that toggle
    run / cancel; the buttons fire them.

How to test

Workspace root is a git repo, AI features enabled, working model behind the default/universal alias, SCM view open.

  • Toggle AI features off: SCM input matches the stock Theia widget (no extra padding, no buttons).
  • Turn AI on with no repo changes: no buttons appear.
  • Stage one file, leave another modified but unstaged: both sparkle buttons (staged / all) appear.
  • Disable the Commit Message agent in AI Configuration → Agents: buttons stay visible but disabled, with a tooltip pointing to the AI configuration view.
  • Type @ in the chat view: CommitMessage does not show up in the mention list.
  • With getGitChanges on the default Confirm mode, click a sparkle then pick Cancel: nothing runs, the tool stays on Confirm.
  • Click again and pick Allow: the run starts, the message is written into the input, and the tool is now Always allow; the next click runs with no dialog.
  • Set getGitChanges to Disabled and click a sparkle: the dialog text changes to mention the tool is currently disabled, picking Allow flips it back to Always allow and runs.
  • Create a single untracked file with meaningful content: only the "all" sparkle appears, and the generated message reflects the new file's content.
  • Add a .gitignore entry for some artefact: its content does not influence the generated message.
  • Empty input, click a sparkle: the message is written directly and focus moves into the textarea.
  • Non-empty input, click a sparkle: a Replace / Cancel prompt appears; Cancel keeps the original text, Replace overwrites it.
  • During a running generation, click the spinning sparkle: the run aborts with the input unchanged.
  • Click a sparkle while existing text is in the input, then click the spinner before responding to the Replace prompt: the agent is not invoked, regardless of whether the prompt is then dismissed via Replace or Cancel.
  • With both sparkles visible, start one: the other becomes disabled with a tooltip saying another generation is in progress; cancelling the running one re-enables it.
  • Multi-root workspace with two git repos: switching the selected repo updates which buttons are visible, and the generated message reflects that repo's diff.
  • Run "Generate Commit Message from Staged Changes" from the command palette with no repository selected: a warning appears, no agent is invoked.

Breaking changes

  • This PR introduces breaking changes and requires careful review. If yes, the breaking changes section in the changelog has been updated.

Attribution

Review checklist

Reminder for reviewers

sgraband added 2 commits June 17, 2026 09:27
… with hardcoded commands

Introduces a generic abstract `PredefinedShellTool` base class for tools that
run a fixed, hardcoded shell command. Subclasses declare a typed parameter
schema and a `buildCommand(args)` method that assembles the exact shell
command from the typed arguments — the LLM only supplies the typed arguments,
so the command itself is fully controlled by the subclass.

Unlike the general-purpose `shellExecute` tool, instances of
`PredefinedShellTool` do not consult `ShellCommandPermissionService` and do
not need to appear on the user shell allow/deny lists: the safety boundary
is the subclass-controlled `buildCommand`, which must not be coercible into
running arbitrary commands. The tool participates in the regular
`ToolConfirmationMode` flow; callers driving an agent without a UI (where
the per-call confirmation modal has nowhere to render) are responsible for
arranging the appropriate confirmation via `ToolConfirmationManager`.

Re-exported from the ai-terminal browser entry point for consumption by
other packages.
Adds an AI-powered commit message generator to the SCM commit widget:

- `GetGitChangesTool`, a `PredefinedShellTool` exposing the repository git
  diff (staged or all changes vs HEAD, plus untracked files as addition
  diffs for the all-changes case) to the agent.
- `CommitMessageAgent` and `CommitMessageRunner` that drive a silent agent
  invocation against a private `MutableChatModel` to produce a commit
  message from the current changes, without surfacing a chat session in
  the panel.
- `CommitMessageCommandContribution` and command wiring.
- `AiAwareScmCommitWidget` rebinding the SCM commit widget to render the
  generate button, gated on `AIActivationService`, plus the prompt template
  and styles.
- A one-time tool-allow gate in the runner that asks the user to flip
  `getGitChanges` to `ALWAYS_ALLOW` when it is currently on `CONFIRM` or
  `DISABLED`, with differentiated dialog copy for each case.
@sgraband sgraband requested a review from sdirix June 17, 2026 07:30
@github-project-automation github-project-automation Bot moved this to Waiting on reviewers in PR Backlog Jun 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Waiting on reviewers

Development

Successfully merging this pull request may close these issues.

1 participant