Skip to content

Route browser workspaces by path hash#12

Merged
GordonBeeming merged 4 commits into
mainfrom
gb/per-workspace-http-routing
Jun 11, 2026
Merged

Route browser workspaces by path hash#12
GordonBeeming merged 4 commits into
mainfrom
gb/per-workspace-http-routing

Conversation

@GordonBeeming

Copy link
Copy Markdown
Owner

Summary

  • The local HTTP server only ever held one shared workspace root, so opening the IDE in a browser always showed whichever window launched first. It now receives the per-window session registry and resolves a /{hash}/ URL prefix (a stable hash of the workspace folder path) to the matching open workspace.
  • A pre-routing middleware strips the prefix and scopes the request to that workspace; without a prefix, requests fall back to the shared root, so the dev server, /mcp, and Codex paths are unchanged.
  • A bare / now lists the open workspaces (single workspace redirects straight in), backed by a new /api/workspaces endpoint. The hosted frontend prepends its hash to every API call.

Notes

  • The native app is untouched, since it talks over Tauri IPC rather than HTTP.
  • Router::layer runs after routing in axum, so the URI-rewriting resolver wraps the whole router from the outside to run before route matching. The in-process router test is what caught this.

Test plan

  • cargo test — 134 passing, including a full-router integration test that drives /{hash}/api/..., /{hash}/, and / through the real axum stack
  • npm test — 275 passing, with a workspacePathPrefix case
  • cargo clippy clean, npm run build succeeds
  • Manual: open two folders as two windows, confirm each /{hash}/ shows its own tree in a browser

The single shared HTTP server only ever knew about one workspace root, so
opening the IDE in a browser always showed whichever window launched first.

Hand the per-window session registry to the HTTP server and resolve a
/{hash}/ URL prefix (a stable hash of the workspace folder path) to the
matching open workspace. A pre-routing middleware strips the prefix and
scopes the request; a bare / lists the open workspaces, and the hosted
frontend prepends its hash to every API call.

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitButler <gitbutler@gitbutler.com>
@GordonBeeming GordonBeeming marked this pull request as ready for review June 11, 2026 02:23
Copilot AI review requested due to automatic review settings June 11, 2026 02:23

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 updates the local HTTP server + hosted frontend so browser-served IDE sessions are routed to the correct open workspace using a stable /{hash}/ URL prefix derived from the workspace root path (fixing the prior “first window wins” behavior).

Changes:

  • Frontend: prepend the current /{hash} prefix to hosted API calls so requests stay scoped to the correct workspace.
  • Backend: add a pre-routing Axum middleware that resolves /{hash}/... to an open workspace session, strips the prefix, and injects the resolved workspace into request extensions.
  • Backend: add a /api/workspaces endpoint and a bare / chooser page (with redirect when only one workspace is open).

Reviewed changes

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

Show a summary per file
File Description
src/tauri.ts Adds workspacePathPrefix() and uses it to scope hosted HTTP API calls under /{hash}/.
src/tauri.test.ts Adds unit tests covering workspacePathPrefix() behavior for dev vs hosted routing.
src-tauri/src/lib.rs Exposes per-window session state for routing and adds workspace_root_hash() + tests.
src-tauri/src/http_server.rs Implements hash-based workspace resolver middleware, chooser UI, and /api/workspaces; updates handlers to use resolved workspace context.
src-tauri/Cargo.toml Adds tower dependency (util feature) for service helpers in routing/tests.
src-tauri/Cargo.lock Locks in tower dependency.

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

Comment thread src-tauri/src/http_server.rs Outdated
Comment thread src-tauri/src/lib.rs Outdated

@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 multi-workspace support to the HTTP server by adding a middleware that resolves and rewrites requests prefixed with a workspace hash to their corresponding workspace session. It also adds a workspace chooser landing page and updates the frontend to include the workspace path prefix in API calls. The review feedback focuses on performance optimizations on the hot path of HTTP requests, specifically recommending the removal of synchronous blocking filesystem I/O in workspace_root_hash and refactoring split_workspace_prefix to return string slices instead of allocating new Strings, along with the necessary updates to the middleware and unit tests.

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/lib.rs
Comment thread src-tauri/src/lib.rs Outdated
Comment thread src-tauri/src/http_server.rs Outdated
Comment thread src-tauri/src/http_server.rs Outdated
Comment thread src-tauri/src/http_server.rs Outdated
GordonBeeming and others added 2 commits June 11, 2026 12:36
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitButler <gitbutler@gitbutler.com>
- Drop per-request canonicalize() from workspace_root_hash; roots are
  already canonical at open time, so hash the stored string directly and
  soften the doc comment about cross-version stability.
- Return borrowed slices from split_workspace_prefix to avoid allocating
  on every request; format the rewritten path only when a rewrite happens.
- Strip a hash-shaped prefix even when it doesn't resolve, so stale
  /{hash}/ bookmarks fall back to the shared root and chooser instead of
  serving SPA HTML from /{hash}/api/... paths.

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitButler <gitbutler@gitbutler.com>
Copilot AI review requested due to automatic review settings June 11, 2026 02:41

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 5 out of 6 changed files in this pull request and generated 1 comment.

Comment thread src-tauri/src/http_server.rs Outdated
Borrow the request path and only allocate the candidate hash + rewritten
path when a hash-shaped prefix is actually present, so unscoped requests
(the hot path) allocate nothing.

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitButler <gitbutler@gitbutler.com>
@GordonBeeming GordonBeeming merged commit ac4eb8f into main Jun 11, 2026
3 of 4 checks passed
@GordonBeeming GordonBeeming deleted the gb/per-workspace-http-routing branch June 11, 2026 03:18
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