Skip to content

🔀 feat: Show the Conversation Pull Request in the Sidebar List - #16815

Merged
berry-13 merged 10 commits into
devfrom
berry-13/pull-request-sidebar
Oct 7, 2026
Merged

berry-13 merged 10 commits into
devfrom
berry-13/pull-request-sidebar

Conversation

@berry-13

@berry-13 berry-13 commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

The pull request chip in the chat header only helps for the chat that is open, so finding which chats in the sidebar have a pull request, and whether it can merge, means opening each one. This adds the same signal to the conversation list: a conversation that opened a pull request gets the pull request icon and its CI dot at the end of its row, and hovering it opens the same card as the header, to the right, sliding in from the left. The row keeps the conversation's own AI-generated title; the pull request title appears only in the card.

A list of rows cannot ask for one pull request each, so this adds POST /api/convos/pull-requests, which takes up to 50 conversation ids and answers each one from a single owner-scoped read of the stored lanes. Rows mounted together are gathered by a small client batcher into one request. Each entry carries its own result or a stable failure code, so one repository's rate limit does not hide the others. The batch shares the single route's lookup, so its cache, in-flight sharing and rate-limit cooldown apply to both, and a conversation open in the header and visible in the list is fetched once. Row marks never poll: a list that polled once per row would multiply GitHub traffic by the number of rows, so a row is as fresh as the last time the list loaded, and the header chip keeps its own polling.

It builds on the header chip (#16794, merged). It does nothing until endpoints.agents.pullRequests is enabled, which the startup config advertises as pullRequestsEnabled, with pullRequestsBatchVersion beside it once this server has the batch route.

How it works

Sidebar rows mount
  PullRequestRowMark x N          # each asks for its own conversation
    createPullRequestBatcher      # gathers ids for 30 ms
      POST /api/convos/pull-requests { conversationIds }   # one request, at most 50 ids
        getConvosLaneGit(user, ids)          # one owner-scoped query
        for each stored lane (4 at a time)   # maxConcurrentLookups
          allowlist check -> shared lookup (cache, in-flight, cooldown)
      { results: [{ conversationId, pullRequest } | { conversationId, error: { code } }] }

The mark sits after the row's menu slot on purpose. That slot grows from zero width on hover, and anything placed before it slid left under the pointer, so the card never opened for a user arriving at the mark. After it, the mark stays put and only the title gives way.

Failure handling. A conversation whose lookup fails shows a warning mark with a retry instead of looking like a chat with no pull request. A missing token fails only the conversations that needed one. If a replica without the batch route answers 404 during a rolling upgrade, the client asks the single route for each conversation instead, at the limit the startup config advertises as pullRequestsMaxConcurrentLookups (one at a time when it is missing). The batch queue belongs to the signed-in user and is disposed when the user changes and when the session ends, and a request that times out or is disposed is aborted before the next one goes out. A row that unmounts withdraws its id: it leaves the queue, a queued request nobody waits for is skipped, and one already on the wire is aborted. Conversations on the same repository, branch and head share one lookup and one slot, within a request and across concurrent requests, and the batch has one deadline (batchTimeoutSeconds, default 20) that starts when the request arrives.

The lookup itself also closes the follow-ups from the #16793 review: the lane epoch is read in the same snapshot as the workspace, fork pull requests have their checks read from the fork when an administrator allowed that repository, GitHub requests go through the deployment proxy, a branch name reused many times can be searched past one page (maxCandidatePages), the subagent lane context is one tenant-scoped read, a headerless 429 gets the secondary-limit cooldown, a vanished head is an upstream error instead of no checks, an unborn lane matches nothing, shared-token cache capacity keeps the largest value, and open fork pull requests win over closed base ones.

Type of change

  • Feature

Testing

Tested environments/configuration:

  • Browser: headless Chromium (Playwright) against the dev server from lc run, 1280x720, light and dark, device scale factor 2.
  • Stubbed in the browser: the batch endpoint (every second saved conversation answered with a pull request, cycling through the states below) and the startup config's pullRequestsEnabled flag. No real worker or GitHub token was involved.

Checked in the browser:

  • One batch request for the whole list on load (21 ids in one request), not one per row.
  • The mark is outside the row's button, so it does not change the row's click target. The row's description names the pull request in words, for example "Pull request PR [Bug]: invalid paths return 200 instead of 404 #1201: Simplify Single Tool Execution Path, State: Open, Checks: Passing".
  • Hovering the row did not move the mark (0 px), and the pointer arriving at the mark opened the card in 5 of 5 runs. The first version placed the mark before the menu slot and moved it 28 px on hover, which opened the card in 0 of 5 runs; that is why it sits after the slot.
  • The card opens to the right of the mark and a click inside it does not navigate. Tab from the row's own menu button reaches the mark, which opens the card, and the next Tab reaches the GitHub link. With no click involved the card closes about 370 ms after the pointer leaves. After a click inside the card it was still open 700 ms after the pointer left; I did not find out why (most likely keyboard focus stays inside it), so that case is not verified.

Icon and dot colors, read from computed styles on the rendered rows:

State of the pull request Icon, light Icon, dark CI dot, light CI dot, dark
Open, no conflicts, checks passing #047857 green #6ee7b7 green #047857 green #6ee7b7 green
Open, merge conflicts, checks failing #b91c1c red #fca5a5 red #b91c1c red #fca5a5 red
Draft, checks running #424242 neutral #cdcdcd neutral #b45309 amber #fcd34d amber
Open, no conflicts, no checks #047857 green #6ee7b7 green none none
Merged #424242 neutral #cdcdcd neutral none none

The icon follows the pull request's state (green ready to merge, red merge conflicts, neutral draft, merged and closed) and the dot follows its checks (green passing, red failing, amber running, none when there are no checks or the pull request is finished).

Automated tests:

  • API: packages/api/src/pulls and src/code pass (993 tests across 27 suites), including the batch handler (order, allowlist, per-entry failures that expose only a code, the concurrency bound across requests and per credential, one deadline that covers the config and lane reads, identical lanes sharing one slot and one lookup across concurrent requests, a missing token failing only the entries that needed it, invalid bodies, and the same lookup input as the single route) and the capability resolver. packages/data-schemas (359 tests) covers the bulk lane read, the epoch returned with the admitted decision, and the single-aggregate subagent context with owner, tenant and expiry cases.
  • Client: 267 suites and 4221 tests under src/components/Chat, src/components/Conversations and src/data-provider pass with NODE_ENV=development (what CI runs) and test. They cover the batcher (one request per window, one at a time, per-entry failures, timeout, abort, disposal, malformed responses), the 404 fallback and its advertised limit, withdrawing unmounted rows, ending the queue with the session, the row mark (keyboard, failure and retry, refresh on focus, no polling, per-user queue) and the row itself.
  • Mutation checks on the handler, batcher, fetcher, query hook, row mark and row each fail a test. Three survived on first try (row polling, switching users, a redundant guard); the first two got new tests and the guard was dead code and was removed.
  • npx tsc --noEmit exits 0 in data-provider, data-schemas, api and client. lc lint is clean and npm run static-checks -- --against origin/dev passes. One string was added, com_ui_pr_load_failed, in the English locale file only.

Screenshots / recordings

Captured from the running app with the endpoint and flag stubbed. Each image shows real sidebar rows in the five states above, and the card open beside the first one.

Risk / compatibility

None for existing chats while endpoints.agents.pullRequests stays off: the flag is not advertised and the client never calls the new route. The route is owner-scoped and an id that is missing, expired or another user's looks the same as one without a lane. Adds config fields maxConcurrentLookups (default 4, 1 to 16), batchTimeoutSeconds and maxCandidatePages (default 1, 1 to 10), and one startup config field, pullRequestsMaxConcurrentLookups. Not checked: a real worker and token, a real proxy, fork check runs against live GitHub, a touch device, a long list under real GitHub latency, and the screenshots by eye (the numbers above come from computed styles and element boxes). Your mockup's draft icon is an empty circle and this one is a neutral draft icon.

Checklist

  • I reviewed my own changes
  • Relevant tests have been added or updated
  • Existing relevant tests pass
  • The change does not introduce new warnings or errors
  • User-facing or complex behavior is documented where necessary
  • Required dependency changes have been merged/published
  • Required documentation PR: N/A

Light: sidebar rows with the PR icon and CI dot (green ready, red conflicts and failing, neutral draft with amber dot, green with no checks, neutral merged). Titles stay the conversation titles

Dark: the same rows

Light: hovering a row's mark opens the card to its right

Dark: the card beside the row

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-06T21:25:50.390541Z 926b3ad New commits
🔒 Security Review ✅ Completed 2026-10-07T05:31:45.178415Z 926b3ad Manual request
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@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: 8c535d2a6d

ℹ️ 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 packages/api/src/pulls/handler.ts Outdated
Comment thread client/src/components/Chat/PullRequest/RowMark.tsx Outdated
Comment thread client/src/data-provider/PullRequest/queries.ts Outdated
Comment thread client/src/components/Chat/PullRequest/RowMark.tsx

@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: 00b7ef69d1

ℹ️ 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 client/src/data-provider/PullRequest/batch.ts Outdated

@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: a6810c3e75

ℹ️ 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 client/src/data-provider/PullRequest/batch.ts Outdated

@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: fc22b7fe46

ℹ️ 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 packages/api/src/pulls/handler.ts Outdated
Comment thread packages/api/src/pulls/handler.ts
Comment thread client/src/components/Conversations/Convo.tsx
@berry-13
berry-13 added this pull request to stack #16796 October 6, 2026 13:25
Base automatically changed from berry-13/pull-request-chip to dev October 6, 2026 13:26
Add a batch lookup route and a sidebar row mark: the state icon with the CI dot, opening the same card beside the row on hover. The row keeps the conversation's own title.
…w Mark

Cap the whole batch with a configurable deadline, make the row mark a keyboard-reachable button that opens the card on focus, refresh rows when the window regains focus through the shared batch, and show a retryable failure state instead of treating a failed first lookup as no pull request.
Queue every batch request behind the one before it, so an oversized list or an overlapping flush cannot multiply the server's configured lookup concurrency, and bound how long one request may hold the queue so a request that never answers cannot stop the rest.
Default the client's request timeout to just past the longest batchTimeoutSeconds a deployment may configure, so a queued request never starts while the previous request's server-side lookups are still running.
@berry-13
berry-13 force-pushed the berry-13/pull-request-sidebar branch from fc22b7f to 19f92dd Compare October 6, 2026 13:26

@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: 19f92dd835

ℹ️ 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 packages/api/src/pulls/handler.ts Outdated
Comment thread client/src/components/Conversations/Convo.tsx Outdated
Comment thread client/src/data-provider/PullRequest/queries.ts Outdated
…ilures Per Entry

Share one lookup limiter across every batch request so lookups that outlive a request's deadline keep their slot, answer a missing token only for the conversations that needed it, and point the row at its pull request description only while that text is in the page.
Copilot AI balanced review requested due to automatic review settings October 6, 2026 13:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@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: 407488a923

ℹ️ 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 client/src/components/Chat/PullRequest/RowMark.tsx
Comment thread packages/api/src/pulls/handler.ts
…e Sidebar on the Batch Version

Start the batch deadline when the request arrives and bound the config and lane reads, count lookup slots per credential, advertise a batch route version and ask only a server that has it, take no row space for an absent mark, show a failed refresh over a cached empty answer, keep a malformed response from stalling the request queue, and repair the lane recording tests that still used a mock removed on dev.

@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: 1009b89890

ℹ️ 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 packages/api/src/pulls/handler.ts Outdated
Comment thread client/src/data-provider/PullRequest/queries.ts
Comment thread client/src/data-provider/PullRequest/queries.ts Outdated
Comment thread api/server/routes/config.js Outdated
Comment thread packages/api/src/pulls/handler.ts Outdated
… Route and Queue

Resolve the pull request startup capabilities in packages/api so the route stays wiring only, bound the config and lane reads by the configured deadline, merge identical lanes before taking limiter slots, fall back to the single route when a replica has no batch route, and dispose the batch queue when the signed-in user changes.

@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: 10596609dd

ℹ️ 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 client/src/data-provider/PullRequest/batch.ts
…rlaps It

Give the batch fetcher the request's abort signal and pass it to every single-route call, abort a request that times out or is disposed, and stop the fallback workers from starting more calls once it has.

@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: 8764a2f695

ℹ️ 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 client/src/data-provider/PullRequest/queries.ts
Comment thread packages/api/src/pulls/handler.ts
Comment thread client/src/data-provider/PullRequest/batch.ts Outdated
Pass the request's abort signal through the batch fetcher, the data-provider call and Axios, so a batch request that times out or is disposed is cancelled instead of continuing beside the next one, and settle a request promptly when it is aborted.

@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: d0c7b58d81

ℹ️ 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 client/src/data-provider/PullRequest/queries.ts
Comment thread client/src/data-provider/PullRequest/queries.ts Outdated
@berry-13

berry-13 commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: 926b3addd4

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@berry-13
berry-13 merged commit caeb786 into dev Oct 7, 2026
45 checks passed
@berry-13
berry-13 deleted the berry-13/pull-request-sidebar branch October 7, 2026 10:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants