Repository navigation
fix(ui): phone pull request surfaces - #689
Merged
Merged
Conversation
…he pull request tools
…ir counts in view
…start_mcp_servers
…it works out of view
…bled trigger has none
Tryanks
marked this pull request as ready for review
October 11, 2026 00:19
Tryanks
enabled auto-merge (squash)
October 11, 2026 00:19
Tryanks
added a commit
that referenced
this pull request
Oct 11, 2026
Tryanks
added a commit
that referenced
this pull request
Oct 11, 2026
* feat: GitLab merge requests behind the pull request host boundary HostKind::Gitlab (gitlab.com by name or a "gitlab" DNS label; self-managed servers by configuration, with a port and no path) and GitLab's terms, which take glab's merge commands from GitHub's. services::gitlab reaches each server over REST v4 with its own token (saved, GITLAB_TOKEN for GITLAB_HOST's server or gitlab.com, glab's stored login per host) and reads discussions, awards, labels, permissions and blobs over GraphQL, which answers a public project anonymously where REST's notes and labels refuse. Writes cover comments, replies, resolution, awards, edits, labels by name, reviewers by id, the Draft: title prefix, close and reopen, rebase, merge with squash, a cleaned message and merge_when_pipeline_succeeds, and a review replayed as line discussions, a note and an approval. The conflict rule that holds a false for 30 seconds at one head, Tcode's viewed marks, write answers, media reads and the CLI runner move to forge so Forgejo and GitLab share them; one viewed-marks store serves both. Capabilities gain update_merge, which GitLab lacks, so its branch update is a rebase. * feat(ui): GitLab's mark, a rebase-only branch update and partial reviews The GitLab mark joins the icon assets. On a host without update_merge the behind chip and the menu offer only the rebase, and the primary update asks for it; a review a host stopped part way through says so in its own toast. * fix(services): GITLAB_TOKEN goes to the server any of glab's host variables names * fix(services): gitlab.com is listed once something names it, like codeberg.org * fix: GitLab merge requests carry GitLab's line counts, and a host without counts shows none * fix(services): GitLab bodies name their uploads on the server, so they draw and read * fix(services): GitLab reviewers change by append and remove, as far as GitLab's answer shows * fix(ui): a rebase GitLab only started says so, and the rebase-only update describes a rebase * test(services): the dispatcher refuses a merge-style update where the host only rebases * fix(services): a GitLab pipeline waiting on a manual job is pending, and auto-merge reads the one REST field * docs(protocol): note optional line counts and a pull request's RebaseStarted * fix(services): GitLab upload links in code stay as written * fix(services): a GitLab summary without line counts still syncs * merge: keep the compact row's stat optional after #689
This was referenced Oct 11, 2026
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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
#661, localized. The compact sheet renders "What the agent sees" from
SessionStatus.pull_request_tools, which the host sets only when it was started with the pull request MCP server. The desktop and headless roots each bound the MCP host and started the servers; the phone example's--localhost was spawned withHostServices::default(), so it never had the server. A phone paired to a desktop or headless host was not affected. The binding moves intoHostServices::start_mcp_servers(runtime), which all three roots now call; the headless root's note on why it serves preview moves there too. The app and headless crates drop their directmcp-host/*-mcpdependencies, exceptcomputer-use-mcpin the app for--cu-smoke;mcp-hostmoves from runtime's dev-dependencies to its dependencies.#662, every bullet:
dropdown_menunever passed the touch flag thatcontext_menuhas. It now does (.touch(compact)on the row's ⋯,.touch(true)on the phone page's ⋯).@@ -0,0 +1,N @@joined zero lines into"\n", a blank old line the line diff matched against a blank new line. A new file now has an empty old side ("+8 −0", no old line; a one-line new file no longer shows a removed blank line).ScrollHandleand draws again when the width or offset settles elsewhere. The path truncates instead of the counts.PopupMenuitem now exposes its label as its accessible name (all Tcode menus, not only these two). Follow-up, not done:menu_elementitems (custom-rendered rows such as the sidebar's Delete project / Delete thread) have no label to derive a name from and stay unnamed.Popover::render_sheethands its toggle to the trigger, andPopover::trigger(which now takes awidgets::Button) passes it toButton::press_action.on_clickhandler first (with a keyboardClickEvent), then the sheet's toggle. This is the same order a pointer click takes through the button and then the sheet's wrapper..open(..)(the compose editor row, the reviewers/labels picker) run their own handler and open as on a pointer click.[press], and pressing either through AX opens its sheet; the selector works while it is still off-screen. Every otherPopover::triggerbottom sheet gains the same press action (e.g. the composer's Permissions and Context Window pickers on phone). The pill's call-site listener is gone.max_w(50%)and its truncated text does not fill it.Evidence
menu_item×8 unnamed; no "What the agent sees" in the sheet (footer runs straight into "+ Link")After: 44pt rows with icons; AX names "Open on GitHub", "Copy link", "Watch for changes", "Merge stack (4)…", …
--local, "What the agent sees" expanded (tools and instruction block)After: at rest, trailing fade; scrolled, the whole conflict chip and "Layer 5 of 6", with a leading fade
src/cart.rsold line 1 against blank new line 4; the one-line new file shows a removed blank lineAfter: "+3 −1", "+8 −0", "+1 −0"; no old side for new files; the long path truncates before its counts
After, scrolled sideways to the end of the longest line: every header whole and pinned
All shots are from a throwaway
TCODE_DATA_DIRseeded with a syntheticacme-apirepository, one thread with a 6-layer native stack plus one single PR. English, light theme.Live AX tree (macOS, phone example
--local):button "4 linked pull requests, open" [press]; AX press opens the sheet.button "Stack #57, layer 5 of 6" [press]; AX press opens the stack sheet, including while the selector is clipped off-screen at rest."#415 checkout/cleanup, open, above, not linked"…"#410 checkout/base-types, merged, merged, not linked".Buttontrigger under the conversation's load failure on chore(deps): bump gpui-wry from 0.6.0 to 0.6.1 #414:button "Disabled sheet trigger"has no[press].button "Add a comment…" [press]: an AX press opened the "Comment on chore(deps): bump gpui-wry from 0.6.0 to 0.6.1 #414" editor sheet. It stayed open with its input focused, through the row's own handler then the toggle.Tests:
app::pull_requests::tests::the_agent_tools_are_disclosed_before_the_first_turnis moved to the boundary the roots use (CONTRIBUTING "When a test fails…" step 3: rewritten only to drive the code the way the app does). It now starts a host withHostServices::start_mcp_servers+spawn_hostinstead of pumping a hand-made server into anAppState. It fails withHostServices::default()(the old phone path) and passes with the fix.diff::model::tests::reconstruction_requires_matching_unambiguous_current_textgains a unified new-file case (@@ -0,0 +1,3 @@→ old""). It fails before the fix ("\n").widgets::menu::tests::a_touch_dropdown_menu_has_touch_sized_rows: a dropdown opened with.touch(true)has rows ≥ 44pt. It fails without passing the flag through.TestWindownever callsa11y_init, so no test window builds an accessibility tree, and crates/ui has no a11y-tree test to extend. They were verified in the live macOS AX tree.Checks (final commit 8fb1afd):
Not run locally: the iOS, Android and Web builds (CI); dark theme and narrow widths were looked at but are not attached.
Merge Danger
Door: two-way
Blast Radius: UI
PopupMenuitem now exposes its label as its accessible name, anddropdown_menugains an opt-intouchflag.widgets::Popover::triggernow takes awidgets::Button(the onlySelectablein the crate; every caller already passed one).trigger_with(the agents pill, menus) are unchanged.Closes #661
Closes #662