Skip to content

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

Draft
GordonBeeming wants to merge 3 commits into
mainfrom
gb/commit-selection-browse-difftabs
Draft

Remember commit selection, close stale diff tabs, and add ide browse#57
GordonBeeming wants to merge 3 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 an ide browse <path> command to open a repository in the default browser.
    • Supports background browsing: reuses an existing session to avoid focus theft, and keeps the browse session running even if a visible IDE window is closed.
  • Bug Fixes
    • Git commit-mode restores prior file selections (including correct fallback when nothing was previously selected).
    • After a successful Git commit, diff tabs are closed even if a diff tab was pinned, preventing stale views.
  • Documentation
    • Documented the new browse command behavior under Local Run.

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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 45e7660b-9cc5-4138-86e9-7b5258e4c30d

📥 Commits

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

📒 Files selected for processing (2)
  • scripts/install-cli-command.sh
  • src/App.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • scripts/install-cli-command.sh
  • src/App.tsx

📝 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

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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 and is specific and concise.
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.
✨ 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

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
Comment on lines +1795 to +1806
setOpenFiles((current) => {
const kept = current.filter((file) => !file.diff);
if (kept.length === current.length) return current;
// Deferred so this updater stays pure — no nested setState calls during render.
queueMicrotask(() => {
setActivePath((currentActivePath) =>
currentActivePath && kept.some((file) => file.path === currentActivePath)
? currentActivePath
: kept.at(-1)?.path,
);
});
return kept;
Comment thread src-tauri/src/lib.rs
Comment on lines +2897 to +2904
/// Whether this cold start is `ide browse <path>` (`IDE_BROWSE_PATH` set, or a
/// leading `browse` argv token) — `run()` uses this to keep the auto-created `main`
/// window hidden. The browsed path itself doesn't need extracting here:
/// `resolve_explicit_launch_target`'s existing `IDE_OPEN_PATH`/argv scan already
/// finds the same path (the token after `browse` is just the first argv entry that
/// exists on disk) and roots `main`'s session in it, so hiding `main` is the only
/// extra work a browse cold start needs. `http_server.rs`'s `/browse` route handles
/// session creation for the warm (already-running) case.
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