Add AI pull-request draft generation and consolidate AI settings UI #43

Merged
Christoph merged 1 commits from newAiFeatures into main 2026-09-11 20:35:34 +00:00
Owner

This change introduces an AI-powered pull request draft generator, consolidates AI settings into the application settings UI, and adds a few repository-status and parent-resolution test/optimizations.

What changed

  • Added commit_ai::generate_pull_request and PullRequestDraft parsing: the commit_ai crate can now call configured AI providers (Anthropic/OpenAI/custom) to produce a JSON pull request draft with a title and Markdown description. Responses are sanitized and validated (title trimmed, no newlines, <=250 chars; description non-empty). parse_pull_request_draft returns an error on invalid or non-JSON responses.
  • Exposed a new Tauri command pull_request_ai_generate that constructs a context from two published remote-tracking refs (target and source) and forwards the diff/commit summaries to the AI generator. If there are no changes in the published range an error is returned.
  • Implemented pull_request_ai_context: it uses only refs/remotes//... (published branch refs) and produces a compact textual context: "Source: \nTarget: \nCommit summaries:\n...\nChanges:\n..." for the AI call.
  • Front-end integration: App.svelte no longer opens a standalone AiSettingsDialog; AI settings are consolidated into the main AppSettingsDialog flow. A settingsInitialPage value drives which tab opens ("integrations" or "ai"); aiSettings are passed into the app settings dialog. Local storage persistence for AI settings now merges with existing saved object rather than replacing it outright.
  • Repository-status optimization: replaced status_for_file with file_status_index which builds a HashMap of path -> Option and preserves first-match and rename alias semantics. repository_files_with_status now queries this index. Tests were added to assert the index behaviour.
  • Added deterministic tests for visibleParentResolver under scripts/ (scripts/graph-parents.test.mjs) and unit tests in the commit_ai crate for pull request parsing. Also added tests exercising pull_request_ai_context and repository status behavior in the tauri crate.
  • Internal wording and message-building guidance in commit_ai::build_messages was updated (commit message system prompt rewritten) — this is an internal change to AI guidance text.

Concrete before / after examples supported by the diff

  • Before: no generate_pull_request export/command existed; after: commit_ai::generate_pull_request is exported and pull_request_ai_generate is available as a Tauri command that reads the diff and commit summaries between two remote-tracking branches and returns a PullRequestDraft structure.
  • Before: AI settings were opened via a dedicated aiSettingsOpen flag and a separate dialog; after: AI settings are shown inside the main app settings UI (settingsInitialPage = "ai" drives the view) and the old standalone conditional block was removed.

Tests

  • Tests and test files added or changed in the diff:
    • scripts/graph-parents.test.mjs (new JS tests for visibleParentResolver)
    • commit_ai::parse_pull_request_draft unit tests (cloud.rs #[cfg(test)] module)
    • tauri crate tests for file_status_index and pull_request_ai_context
  • No test execution results were provided.

Recommended reviewer checks

  1. Backend: run crate unit tests and exercise the new command:
    • cargo test in src-tauri/crates/commit_ai
    • cargo test in src-tauri (tauri crate) to validate file_status_index and pull_request context tests
    • Invoke the new Tauri command pull_request_ai_generate (or call commit_ai::generate_pull_request) with two published remote refs to confirm it returns a PullRequestDraft for a non-empty range and errors for an empty range.
  2. Front-end: check the AppSettingsDialog / Ai settings integration:
    • Open the app settings, navigate to the AI page via the settingsInitialPage mechanism and confirm save/persist behavior still works as before.
    • Confirm that the standalone AiSettingsDialog was intentionally removed/renamed and verify that the renamed component's props and event handlers match the new usage.

Compatibility / reviewer notes

  • The AI pull-request generator requires callers to supply provider/model and API key arguments (the code already validates presence for providers). Reviewers should confirm CI/packaging does not expect the old standalone AiSettingsDialog import/usage.
  • The new file_status_index preserves first-match semantics and maps rename aliases to the same status; tests were added to validate this behavior.

Files and changes of interest (high-level)

  • New/updated AI logic: src-tauri/crates/commit_ai/src/cloud.rs, src-tauri/crates/commit_ai/src/lib.rs
  • New Tauri command and context builder: src-tauri/src/git.rs (pull_request_ai_context, pull_request_ai_generate)
  • Front-end integration and settings changes: src/App.svelte and renamed src/lib/components/AiSettingsPage.svelte
  • Tests: scripts/graph-parents.test.mjs and added #[cfg(test)] modules in the tauri crates

If you want, I can suggest a minimal manual test script (commands and expected output) to exercise pull_request_ai_generate and the UI paths.

This change introduces an AI-powered pull request draft generator, consolidates AI settings into the application settings UI, and adds a few repository-status and parent-resolution test/optimizations. What changed - Added commit_ai::generate_pull_request and PullRequestDraft parsing: the commit_ai crate can now call configured AI providers (Anthropic/OpenAI/custom) to produce a JSON pull request draft with a title and Markdown description. Responses are sanitized and validated (title trimmed, no newlines, <=250 chars; description non-empty). parse_pull_request_draft returns an error on invalid or non-JSON responses. - Exposed a new Tauri command pull_request_ai_generate that constructs a context from two published remote-tracking refs (target and source) and forwards the diff/commit summaries to the AI generator. If there are no changes in the published range an error is returned. - Implemented pull_request_ai_context: it uses only refs/remotes/<remote>/... (published branch refs) and produces a compact textual context: "Source: <source>\nTarget: <target>\nCommit summaries:\n...\nChanges:\n..." for the AI call. - Front-end integration: App.svelte no longer opens a standalone AiSettingsDialog; AI settings are consolidated into the main AppSettingsDialog flow. A settingsInitialPage value drives which tab opens ("integrations" or "ai"); aiSettings are passed into the app settings dialog. Local storage persistence for AI settings now merges with existing saved object rather than replacing it outright. - Repository-status optimization: replaced status_for_file with file_status_index which builds a HashMap of path -> Option<FileStatusKind> and preserves first-match and rename alias semantics. repository_files_with_status now queries this index. Tests were added to assert the index behaviour. - Added deterministic tests for visibleParentResolver under scripts/ (scripts/graph-parents.test.mjs) and unit tests in the commit_ai crate for pull request parsing. Also added tests exercising pull_request_ai_context and repository status behavior in the tauri crate. - Internal wording and message-building guidance in commit_ai::build_messages was updated (commit message system prompt rewritten) — this is an internal change to AI guidance text. Concrete before / after examples supported by the diff - Before: no generate_pull_request export/command existed; after: commit_ai::generate_pull_request is exported and pull_request_ai_generate is available as a Tauri command that reads the diff and commit summaries between two remote-tracking branches and returns a PullRequestDraft structure. - Before: AI settings were opened via a dedicated aiSettingsOpen flag and a separate dialog; after: AI settings are shown inside the main app settings UI (settingsInitialPage = "ai" drives the view) and the old standalone conditional block was removed. Tests - Tests and test files added or changed in the diff: - scripts/graph-parents.test.mjs (new JS tests for visibleParentResolver) - commit_ai::parse_pull_request_draft unit tests (cloud.rs #[cfg(test)] module) - tauri crate tests for file_status_index and pull_request_ai_context - No test execution results were provided. Recommended reviewer checks 1) Backend: run crate unit tests and exercise the new command: - cargo test in src-tauri/crates/commit_ai - cargo test in src-tauri (tauri crate) to validate file_status_index and pull_request context tests - Invoke the new Tauri command pull_request_ai_generate (or call commit_ai::generate_pull_request) with two published remote refs to confirm it returns a PullRequestDraft for a non-empty range and errors for an empty range. 2) Front-end: check the AppSettingsDialog / Ai settings integration: - Open the app settings, navigate to the AI page via the settingsInitialPage mechanism and confirm save/persist behavior still works as before. - Confirm that the standalone AiSettingsDialog was intentionally removed/renamed and verify that the renamed component's props and event handlers match the new usage. Compatibility / reviewer notes - The AI pull-request generator requires callers to supply provider/model and API key arguments (the code already validates presence for providers). Reviewers should confirm CI/packaging does not expect the old standalone AiSettingsDialog import/usage. - The new file_status_index preserves first-match semantics and maps rename aliases to the same status; tests were added to validate this behavior. Files and changes of interest (high-level) - New/updated AI logic: src-tauri/crates/commit_ai/src/cloud.rs, src-tauri/crates/commit_ai/src/lib.rs - New Tauri command and context builder: src-tauri/src/git.rs (pull_request_ai_context, pull_request_ai_generate) - Front-end integration and settings changes: src/App.svelte and renamed src/lib/components/AiSettingsPage.svelte - Tests: scripts/graph-parents.test.mjs and added #[cfg(test)] modules in the tauri crates If you want, I can suggest a minimal manual test script (commands and expected output) to exercise pull_request_ai_generate and the UI paths.
Christoph added 2 commits 2026-09-11 20:35:00 +00:00
Introduce an iterative visibleParentResolver for commit-graph rendering,
replacing a recursive traversal. It preserves first-parent ordering,
deduplicates converging paths, and avoids stack overflows; a test suite
validates correctness and performance. Additionally, streamline background
fetch handling in the UI to reuse fetchRemote's returned status and avoid
unnecessary status reads and tab invalidation, and refactor Git status
handling in Rust to build a file_status_index that preserves rename and
first-match semantics while speeding lookups.

- Add visibleParentResolver + comprehensive tests for ancestry handling
- Reuse fetchRemote result to apply status and skip unchanged updates
- Replace status_for_file with file_status_index to improve performance
Add pull request draft generation to the commit_ai crate and expose it
via a new Tauri command. The backend builds a branch-range context from
published remote-tracking refs only, calls the chosen AI provider, and
parses a JSON {"title","description"} draft (with validation). Also
register the command in the app and add unit tests for parsing and the
branch-context behavior.

Consolidate AI settings in the frontend by renaming the dialog to an
AiSettingsPage and integrating AI options into the main AppSettings
dialog. Persisted AI preferences are merged with existing localStorage
rather than replacing it, and the settings UI now supports opening the
app settings to a specific initial page ("integrations" or "ai").

Other changes:
- Replace the commit-message system prompt used by build_messages with
  the updated, more detailed guidance text.
Christoph merged commit 98719bea4a into main 2026-09-11 20:35:34 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Christoph/GitLite#43