Skip to content

Remember commit selection, close stale diff tabs, and add ide browse#57

Merged
GordonBeeming merged 5 commits into
mainfrom
gb/commit-selection-browse-difftabs
Jul 12, 2026
Merged

Remember commit selection, close stale diff tabs, and add ide browse#57
GordonBeeming merged 5 commits into
mainfrom
gb/commit-selection-browse-difftabs

Conversation

@GordonBeeming

@GordonBeeming GordonBeeming commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Summary

Three changes to the commit flow and how a repo can be opened:

  • Commit-file selection is remembered across navigation. Entering the commit view still selects every changed file by default, but leaving it and coming back no longer wipes a manual selection. Re-entry only re-selects all when the remembered selection was empty or already the full set; a partial selection (say 14 of 15 after unchecking one) is preserved. The "all selected" test is derived from the current set, not a stored flag, so unchecking a file and re-checking it counts as all-selected again.
  • ide browse <path> opens a repo in the browser instead of a native window. If nothing is running yet it cold-starts the app headless — HTTP server up, main window kept hidden — and gives the repo its own hidden session; if an instance is already running it reuses it. Several repos can be browsed at once, each on its own /{hash}/ URL, and closing a visible window leaves the background sessions serving until the app is quit. A new loopback GET /browse?path= route ensures the session exists and redirects to the scoped SPA, so the launcher never has to reproduce the Rust workspace hash.
  • Diff tabs close after a successful commit. Every open working-tree diff reflects the pre-commit tree, so it goes stale the instant the commit lands. They used to linger showing "N unchanged lines" with no content; now they close on commit.

Implementation notes

  • Selection memory is a change to one reconciliation branch in refreshGitStatus — prune the remembered set to still-valid paths, then collapse to all only when it's empty or full. No new state.
  • Diff-tab cleanup reuses the existing leave-commit-mode setOpenFiles filter, minus the pinned exception — a post-commit diff is stale whether or not it's pinned.
  • Browse reuses the existing SPA-over-HTTP stack, per-/{hash}/ routing, and single-instance forwarding. open_launch_target_window gains a visible flag so browse sessions build hidden and never steal focus; window creation from the HTTP handler bridges to the main thread via run_on_main_thread.

Test plan

  • npm test (410) and cargo test (235) pass; cargo build, npm run build, and npm run launch:check are clean.
  • Driven live against a seeded scratch repo over the loopback browser endpoint:
    • Commit view opens all-selected; uncheck one → navigate away and back → partial preserved; deselect all → navigate away and back → re-selects all.
    • ide browse starts headless with no visible window; a second repo is browsable alongside the first; /browse?path= redirects to the scoped /{hash}/ and the repo lists once.
    • A pinned working-tree diff tab closes on a successful commit.

Summary by CodeRabbit

  • New Features
    • Added ide browse <path> to open a repository in the default browser, including headless cold-start when needed, URL-safe path handling, and reuse of an existing session to avoid focus theft. Background browse continues even if a visible IDE window is closed.
  • Bug Fixes
    • Git commit-mode now restores the prior partial file selection correctly, with proper fallback when nothing was selected.
    • After a successful Git commit, diff tabs are closed even when pinned, preventing stale post-commit views.
  • Documentation
    • Documented the ide browse behavior under Local Run.
  • Tests
    • Added coverage for git commit sidebar selection and post-commit tab closing behavior.

Entering the commit view still selects every changed file, but leaving and
coming back no longer wipes a manual selection. Re-entry only re-selects all
when the remembered selection was empty or already the full set; a partial
selection (say 14 of 15 after unchecking one) is preserved as-is. The all-or-
none test is derived from the current set, so uncheck-then-recheck counts as
'all' again.

After a successful commit, every open working-tree diff tab now closes. They
all reflect the pre-commit tree, so they go stale the instant the commit lands
and would otherwise linger showing 'N unchanged lines' with no content.
ide browse <path> opens a repo's web UI in the default browser instead of a
native window. If nothing is running yet it cold-starts the app headless (HTTP
server up, main window kept hidden) and gives the repo its own hidden session;
if an instance is already running it reuses it. Several repos can be browsed at
once, each on its own /{hash}/ URL, and closing a visible window leaves the
background sessions serving until the app is quit.

The launcher gains a browse subcommand that url-encodes the path and hands it to
a new loopback GET /browse?path= route, which ensures a (hidden) session exists
and 302-redirects to the repo's scoped SPA — so bash never has to reproduce the
Rust workspace hash. Window creation from the HTTP handler bridges to the main
thread via run_on_main_thread. open_launch_target_window gains a visible flag so
browse sessions build hidden and never steal focus.
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds ide browse <path> background repository browsing through the CLI and Tauri HTTP server. It also preserves Git commit selections across mode changes and closes stale diff tabs after successful commits, including pinned tabs.

Changes

Background repository browsing

Layer / File(s) Summary
Browse CLI command
scripts/install-cli-command.sh, scripts/validate-launch-runners.mjs, docs/development.md
The launcher adds path resolution, URL encoding, server readiness checks, and the browse subcommand, with validation and documentation updates.
Browse HTTP route
src-tauri/src/http_server.rs
GET /browse resolves the workspace, creates a hidden session when necessary, and redirects to the workspace URL.
Background window lifecycle
src-tauri/src/lib.rs
Cold-start detection and window opening now support hidden browse sessions without focusing or displaying the main window.

Git commit state

Layer / File(s) Summary
Commit selection and diff cleanup
src/App.tsx, src/App.test.tsx
Commit mode preserves valid prior selections, and successful commits close all diff tabs while tests cover partial, empty, pinned, and unpinned selections.

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

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant HTTPServer
  participant TauriApp
  participant Workspace
  CLI->>HTTPServer: Request encoded browse path
  HTTPServer->>Workspace: Resolve workspace and hash
  HTTPServer->>TauriApp: Create hidden session if absent
  TauriApp->>Workspace: Register workspace window
  HTTPServer-->>CLI: Redirect to workspace route
Loading

Possibly related PRs

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the three main changes in the pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch gb/commit-selection-browse-difftabs

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

@GordonBeeming

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces an ide browse <path> command that allows users to open a repository in the default browser, running the app headless in the background if it is not already active. It also updates the frontend to remember partial file selections when re-entering commit mode and to close stale diff tabs after a successful commit. The review feedback highlights a critical security vulnerability in the new /browse endpoint, which lacks authentication and could allow arbitrary file reads via CSRF. Additionally, it identifies a React anti-pattern in src/App.tsx where a state setter is called inside another state updater, recommending the use of queueMicrotask to defer the nested update.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src-tauri/src/http_server.rs
Comment thread src/App.tsx Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR enhances the commit workflow UX and adds a new “browse in browser” launch mode by reusing the existing HTTP+scoped-session architecture in the Tauri backend.

Changes:

  • Preserve commit-file selection across leaving/re-entering commit mode; add tests for partial/empty remembered selection.
  • Close all working-tree diff tabs after a successful commit (including pinned) and add a regression test.
  • Add ide browse <path> support: a /browse?path= loopback route that ensures a session exists (hidden window when needed) and redirects to the scoped /{hash}/ SPA; update CLI installer, runner validation, and docs.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/App.tsx Remembers commit selection on re-entry and closes diff tabs post-commit.
src/App.test.tsx Adds tests for selection memory and diff-tab cleanup after commit.
src-tauri/src/lib.rs Adds browse-launch detection and supports hidden (non-visible) workspace windows.
src-tauri/src/http_server.rs Adds /browse route to create/ensure sessions and redirect into scoped SPA.
scripts/validate-launch-runners.mjs Extends launcher validation for the new browse branch.
scripts/install-cli-command.sh Generates ide browse launcher logic and URL encoding utilities.
docs/development.md Documents ide browse behavior and lifecycle.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src-tauri/src/http_server.rs
Comment thread src-tauri/src/http_server.rs
Comment thread scripts/install-cli-command.sh

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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-tauri/src/http_server.rs`:
- Around line 331-339: Protect the /browse handler by requiring a
launcher-issued, unguessable short-lived capability and reject missing or
invalid capabilities before invoking browse. Pass the capability through the
existing BrowseQuery or request state, validate it at the route boundary, and
ensure only ide browse can issue valid capabilities while preserving normal
behavior for authorized requests.
🪄 Autofix (Beta)

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: 8fc7bcc4-ddbc-4be3-b030-09208169c463

📥 Commits

Reviewing files that changed from the base of the PR and between b526c62 and 293da41.

📒 Files selected for processing (7)
  • docs/development.md
  • scripts/install-cli-command.sh
  • scripts/validate-launch-runners.mjs
  • src-tauri/src/http_server.rs
  • src-tauri/src/lib.rs
  • src/App.test.tsx
  • src/App.tsx

Comment thread src-tauri/src/http_server.rs
Address reviewer comments:
- Defer setActivePath out of the setOpenFiles updater (queueMicrotask) so the post-commit diff-tab cleanup stays pure (gemini)
- Force byte-wise url_encode iteration (LC_ALL=C) and mask the signed-byte printf conversion (& 0xFF) so ide browse percent-encodes non-ASCII paths correctly under bash 3.2 (copilot)
@GordonBeeming

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@GordonBeeming GordonBeeming requested a review from Copilot July 12, 2026 14:07
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Comment thread src/App.tsx Outdated
Comment thread src-tauri/src/lib.rs Outdated
Address reviewer comments:
- Move both setOpenFiles/setActivePath calls out of the updater entirely (reading the pre-commit list from openFilesRef instead) so no state setter runs inside another's updater, even deferred (copilot)
- Skip a leading 'browse' argv token in resolve_explicit_launch_target before scanning for the target path, so a ./browse directory in cwd can't be mistaken for it (copilot)
@GordonBeeming GordonBeeming requested a review from Copilot July 12, 2026 22:01
@GordonBeeming

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment thread src-tauri/src/http_server.rs Outdated
Address reviewer comments:
- Reject a non-absolute path in the /browse handler before resolving it, matching the documented <abs> contract (copilot)
@GordonBeeming GordonBeeming requested a review from Copilot July 12, 2026 22:10
@GordonBeeming

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@GordonBeeming GordonBeeming marked this pull request as ready for review July 12, 2026 22:19
@GordonBeeming GordonBeeming merged commit d212cba into main Jul 12, 2026
4 of 6 checks passed
@GordonBeeming GordonBeeming deleted the gb/commit-selection-browse-difftabs branch July 12, 2026 22:19

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a786f2ad8f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/App.tsx
Comment on lines +1454 to +1455
if (pruned.size === 0 || pruned.size === validPaths.size) return validPaths;
return pruned;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve select-all when new changed files appear

When commit mode is left with all current files selected and another changed file appears before the next status refresh/re-entry, pruned contains the old full set but pruned.size !== validPaths.size, so this returns pruned and silently leaves the new file unchecked. That regresses the default “all changes selected” behavior for users who never opted into a partial selection, and the next commit can omit newly changed files unless they notice the count.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants