You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Manage named OpenCode connections in Settings → Servers: None, Browser-Session, Basic and Bearer authentication. Saving a connection retains the current workspace.
Use a simple active-server selector: top of the project sidebar, including collapsed/mobile views; bottom of Home beside Terminal and Settings. No cross-server session tab strip.
Restore each server's workspace/project route. Switching servers inside Settings retains the selected settings tab and scopes providers/MCP to the target server and its project; Back to workspace restores that server's workspace.
Show New Session immediately as a removable local sidebar draft, reuse empty drafts and promote the same entry in place on first send. Preserve typing during pending creation and recover failed creation.
Keep provider credentials, OAuth completion, model preferences, background SSE and terminal connections server-scoped. Detached provider requests cannot refresh/dispose another active scope.
Address review findings: disable unsupported remote MCP removal, purge removed connections' remembered routes/composers, retire promoted draft keys, add draft option/keyboard semantics, restore routes through all project pickers, preserve newer typing on first-prompt failure, and reject credential-bearing PTY ticket redirects.
Authentication and provenance
Imports the approved Browser-Session layer and notebook Makefile from the original feature/browser-session sibling, preserved untouched at base e234d7475 with its original content hashes.
Browser-Session uses existing same-origin browser login directly for HTTP/SSE/PTY, without relay credentials or tickets. Expired/denied sessions prompt sign-in; cross-origin cookie authentication is rejected.
Basic/Bearer transports retain the prefix-aware, credential-isolating same-origin relay and single-use PTY tickets. Remote connections never fall back to the local backend; local-only filesystem settings remain unavailable remotely.
Connection metadata lives in localStorage; Basic/Bearer secrets stay in sessionStorage. Provider credentials belong to the selected backend.
Validation
Final head 24937c43187bb3cf812c2957194b9c72af76970b: 264 unit tests, 60 browser tests, TypeScript typecheck and production build pass; ESLint 0 errors / 58 warnings. CI successful.
Browser coverage includes root and notebook-prefix routes, Home/project selector placement on desktop/mobile, same-tab Settings switching, provider/MCP response races, OAuth lifecycle, model preferences, local drafts/promotion, auth rejection, Browser-Session HTTP/SSE/PTY and cookie isolation.
Publication checks: clean explicit-path commits, git diff --check, remote ancestry verification, Makefile build/push from an exact committed Git archive. Original Browser-Session sibling diff and complete inventory hashes remain unchanged.
Fresh linux/amd64 image deployed through the owning Helm release to tight-ermine, developer1/opencode-browser-session, revision 10, Ready with zero restarts. Notebook spec and Helm values preserved except image.
Tag: dev-approved-ux-20261005T081232Z-24937c43187b in europe-west3-docker.pkg.dev/prokube-internal/prokube-customer/pk-opencode-webui.
Deployed digest: sha256:628c1e46c30da12f2f040b1e8b5977948793604cd79bcfd348e9af6a2d2976ae. Live imageID matches; hashes of 708 deployed UI/shared files match the freshly built image.
Final review follow-up retains the existing bounded five-retry terminal reconnect policy through transient ticket failures; browser regressions prove recovery and the retry limit.
Live backend health passes (OpenCode 1.18.23). Isolated live browser verifies Home bottom / project top selectors on desktop and mobile, immediate draft/reuse/removal and Browser-Session controls. Deployed-bundle browser fixtures verify Providers/MCP/Appearance same-tab switching, target project scope, Back to workspace, and remote MCP removal disabled. Zero page errors or backend mutations.
Copilot requested natively with gh pr edit --add-reviewer @copilot; all actionable findings received have fixes and regression coverage. Final-head re-review is running as of publication.
Known limits and live-test boundaries
Composer contents remain in memory with the existing 40-draft limit and are not reload-persistent.
Mock gateway/browser fixtures prove remote Browser-Session and provider flows; they are not a claim of real authenticated remote sandbox testing. Live checks use isolated browser storage and disclose intercepted responses separately from real backend health.
The reason will be displayed to describe this comment to others. Learn more.
Copilot review overview
🔵 Needs a closer look
Remote MCP removal remains misleadingly enabled, and duplicate tab titles produce ambiguous accessible close controls.
Review effort: Balanced Findings: None
Previously missed (2)
In code that hasn't changed since last review
Include server name in close button accessible label
app-prefixable/src/app.tsx:266
The close button's accessible name omits the server, so two common tabs such as “New session” on Alpha and Beta both expose exactly “Close New session”. Screen-reader users cannot distinguish which server tab will be closed. Include the connection name in this label, as the adjacent tab button already does visually.
Disable MCP removal for remote servers
app-prefixable/src/context/mcp.tsx:196
On remote connections this guard only fails after the user has clicked the still-enabled “Remove server” action and confirmed it (pages/settings.tsx:1693 and components/mcp-dialog.tsx:249). The action is therefore guaranteed to end in an error instead of being marked unavailable as described by the PR. Disable or hide MCP removal for remote servers and direct users to Disconnect before opening the confirmation dialog.
Import the approved Browser-Session HTTP/SSE/PTY transport and Makefile from the preserved browser-session worktree. Combine the tested server selector, scoped provider OAuth/model preferences, immediate sidebar draft promotion, and same-tab settings server navigation.
Addressed the remaining actionable prior Copilot feedback: remote MCP removal is now disabled in Settings and the session dialog, with guidance to disconnect instead. Two new browser checks (root and notebook prefix) verify both remote-disabled and local-enabled behavior; typecheck, production build and changed-file lint passed (zero errors). The prior ambiguous cross-server tab close controls were removed by the approved simple-selector UX.
Addressed all three new Copilot findings: removing a connection now forgets workspace/project routes and its module-level composer/version keys; promotion retires the temporary draft key and coordinates the route-change saver; draft rows now expose option/selection semantics and participate in arrow/Home/End/Enter/Space navigation while remaining outside backend bulk selection. Eight focused browser checks passed across root and notebook prefix (including removal/re-add/history, pending continuation/history, keyboard draft activation and in-place promotion); typecheck/build and changed-file lint passed with zero errors. Re-requested Copilot on the follow-up head.
The project entry in the command palette still opens /<dir>/session directly. Even with this server-aware navigator, that discards the per-server route recorded by rememberProject, so a selected local draft (including its composer) is not restored when the project is reopened from the palette. Use connections.projectRoute(server.id, project.worktree) with the current URL as the fallback, as the Home project selectors do.
Route project selections through the connection registry
app-prefixable/src/pages/project-picker.tsx:2
Project navigation from this picker is only server-scoped; both project handlers still navigate to /<dir>/session directly. That bypasses connections.projectRoute(...), so returning to a project from Home loses its remembered draft/session route and composer, unlike the Home sidebar paths in home-layout.tsx:133-138. Route project selections through the connection registry before falling back to the plain session URL.
Follow-up review fixes: Home recent-project selections, the project dialog and command palette now restore remembered server/project routes. Added root/prefix coverage for all three entry points. Newer typing was already protected against create failure by draft versions; promotion now preserves that version protection when the first prompt fails too. Both create-failure and prompt-failure continuation cases pass, alongside the unchanged no-newer-text restore case. Eight focused browser checks, typecheck/build and changed-file lint passed. The keyboard browser focus race is resolved; CI on ac71b58 passed all 50 browser tests before these six new scenarios.
Selecting a project from the command palette still builds a bare /<dir>/session URL; this wrapper only adds the active server ID. As a result, this project-switch path bypasses connections.projectRoute and discards the remembered session/draft route that the sidebar selectors restore. Route project commands through the same registry lookup used by HomeLayout and Layout.
Project picker ignores remembered server project routes
app-prefixable/src/pages/project-picker.tsx:2
The server-aware navigator preserves the server query, but this picker’s handleProjectSelect and openRecentProject still navigate to a newly constructed /<dir>/session route. Unlike the sidebar project selectors, they never consult connections.projectRoute, so choosing a project here loses its remembered session/draft and composer route, contrary to project-route restoration elsewhere in this PR.
Fixed the ticket-redirect finding: terminal ticket fetch now rejects redirects and explicitly retains same-origin credential policy. A real HTTP redirect regression verifies that no request or credential reaches the redirect target. Browser-Session direct PTY and Basic/Bearer terminal scenarios remain passing. Also made the Home recent-project test accept its legitimate home-relative display (~) after the path response arrives. All actionable feedback received so far has corresponding fixes/tests; latest review re-requested.
Reconnect loop stops permanently after connect-ticket failure
app-prefixable/src/components/terminal.tsx:140
If connect-ticket times out or returns a transient 429/5xx during a reconnect, this branch stops without scheduling another attempt, so the terminal's existing reconnect loop is permanently abandoned after one ticket failure. Please route this failure through the same bounded backoff used for abnormal WebSocket closes (while still stopping after the retry limit).
Published and deployed final committed head 4c68057. CI SUCCESS: 264 unit / 56 browser tests, typecheck/build, lint 0 errors / 58 warnings. Fresh Makefile linux/amd64 tag dev-approved-ux-20261005T080305Z-4c680570bda7; deployed digest sha256:329d2f6ecc6d7e6a9d24a863da47279d9391c6a318a9beb63fdb662ff9a12eb2. Owning Helm release developer1/opencode-browser-session on tight-ermine is revision 9, Ready, zero restarts; Notebook spec/values preserved except image. Live backend health and desktop/mobile Home-bottom/project-top controls, local draft reuse/removal and auth controls pass. Deployed-bundle fixture checks cover settings same-tab target scope/back navigation; real remote browser login was not available. Live pod hashes of 708 UI/shared files match the built image. Source is clean/pushed and original sibling hashes preserved. Immediate rollback revision 8 (image 1c97b15e...), original pre-task rollback revision 6 (67afac6b...). Final Copilot review is requested/running; PR remains unmerged.
Addressed the final re-review terminal finding: transient ticket acquisition failures now use the same five-retry exponential backoff as abnormal WebSocket closes. Added root/prefix browser scenarios proving recovery after an initial 503 and stopping after exactly five retries. All four scenarios pass; typecheck/build and changed-file lint pass. Re-requesting review on this follow-up head.
Final deployment supersedes revision 9: head 24937c4 is clean/pushed and deployed at Helm revision 10, Ready with zero restarts. CI SUCCESS: 264 unit tests / 60 browser tests, typecheck/build, lint 0 errors / 58 warnings. Makefile linux/amd64 tag dev-approved-ux-20261005T081232Z-24937c43187b; digest sha256:628c1e46c30da12f2f040b1e8b5977948793604cd79bcfd348e9af6a2d2976ae. Pod imageID and all 708 UI/shared file hashes match the built image. Live health/UI/isolated Settings-fixture checks pass, zero page errors/backend mutations. Notebook spec and Helm values preserved except image; original sibling hashes preserved. Immediate rollback is revision 9, image sha256:329d2f6ecc6d7e6a9d24a863da47279d9391c6a318a9beb63fdb662ff9a12eb2; pre-task rollback remains revision 6. All received actionable Copilot findings are fixed/tested; final re-review requested and still pending. No merge.
return response("This feature requires the local UI filesystem API and is unavailable on external servers", 501)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Authentication and provenance
feature/browser-sessionsibling, preserved untouched at basee234d7475with its original content hashes.Validation
24937c43187bb3cf812c2957194b9c72af76970b: 264 unit tests, 60 browser tests, TypeScript typecheck and production build pass; ESLint 0 errors / 58 warnings. CI successful.git diff --check, remote ancestry verification, Makefile build/push from an exact committed Git archive. Original Browser-Session sibling diff and complete inventory hashes remain unchanged.tight-ermine,developer1/opencode-browser-session, revision 10, Ready with zero restarts. Notebook spec and Helm values preserved except image.dev-approved-ux-20261005T081232Z-24937c43187bineurope-west3-docker.pkg.dev/prokube-internal/prokube-customer/pk-opencode-webui.sha256:628c1e46c30da12f2f040b1e8b5977948793604cd79bcfd348e9af6a2d2976ae. Live imageID matches; hashes of 708 deployed UI/shared files match the freshly built image.gh pr edit --add-reviewer @copilot; all actionable findings received have fixes and regression coverage. Final-head re-review is running as of publication.Known limits and live-test boundaries