Skip to content

fix(web): open pull requests in the browser and resolve fork origins correctly (fork sync) - #5

Merged
Fryuni merged 25 commits into
mainfrom
t3code/merge-upstream-and-fork-origin-fixes
Sep 13, 2026
Merged

Fryuni merged 25 commits into
mainfrom
t3code/merge-upstream-and-fork-origin-fixes

Conversation

@Fryuni

@Fryuni Fryuni commented Sep 13, 2026

Copy link
Copy Markdown
Owner

What Changed

This branch merges the latest upstream main into the fork and carries a small fork-local fix on top of it (from t3code/fix-view-pr-fork-origin):

  • Pull requests now open in the system browser instead of the in-app side panel.
  • Repository identity resolution now treats a fork's own origin (e.g. you/forked-repo) as a first-class upstream when linking and opening pull requests, so PR links stop pointing at the parent repo you forked from.

The bulk of the diff is the upstream sync itself: Forgejo/Gitea source-control support, pooled subscription usage widgets on mobile, GitHub PR routing across matching accounts, composer paste folding, opt-in thread notifications, diagnostics for startup crashes, and the other changes already merged upstream.

Why

The fork needs to track upstream to stay current, but the way pull requests were surfaced didn't work for fork-based workflows: the side panel hit the parent repository's PR, not the fork's, and the identity resolver matched remotes in a way that lost the fork origin. Opening PRs in the browser uses GitHub's own fork-aware routing and removes the wrong-repo link entirely, which is smaller and more correct than teaching the panel about fork remotes.

The upstream merge is otherwise a plain git merge upstream/main with no conflict-driven behavior changes beyond what upstream already shipped.

UI Changes

Before: clicking a linked pull request opened T3's side panel, showing the parent repo's PR for fork branches.

After: the pull request opens in the system browser at the fork's origin.

(Screenshots to be attached before review; no motion involved.)

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Worked on by GLM (glm-5.3-flash) via opencode.

maria-rcks and others added 25 commits September 12, 2026 21:25
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
… it (pingdotgg#11487)

Co-authored-by: Claude Code <noreply@anthropic.com>
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
…ngdotgg#9139)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
…1524)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
- Drop the thread-scoped side panel open path and always open the PR URL via openPrLink
- Remove the onOpenPullRequest prop from ChatHeader and GitActionsControl
Reconcile the independent Forgejo implementations around upstream's fj/tea and full review support. Preserve instance-path case, URL normalization, fork filtering, and cached remote refinement; include requested web authorities in cache identity.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 13, 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-09-13T15:38:34.085809Z 377e1b5 PR opened
ℹ️ 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.

@Fryuni
Fryuni merged commit 665746a into main Sep 13, 2026
@Fryuni
Fryuni deleted the t3code/merge-upstream-and-fork-origin-fixes branch September 13, 2026 15:27

@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: 377e1b56a8

ℹ️ 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".

});
return;
}
openPrLink(event, prUrl);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Force the View PR action through the external opener

When an active thread exists and the PR belongs to a known project, an unmodified click passed to useOpenPrLink is consumed by useOpenChangeRequestLink, which opens the right-side PR panel and never reaches useOpenLink. Consequently this replacement still follows the in-app path—and retains the fork/wrong-repository behavior this change is intended to avoid—instead of opening the system browser. This action needs to bypass the internal change-request router or explicitly force external opening.

Useful? React with 👍 / 👎.

Comment on lines +207 to +210
const state = input.state === "merged" ? "closed" : input.state;
const query = {
...input,
path: `${repoPath(input)}/pulls?state=${state}&sort=recentupdate`,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Separate merged and unmerged Forgejo results

Forgejo represents both merged and merely closed pull requests with the API state closed, so translating a requested merged state to closed is only the first step. Every decoded row is currently returned without checking the normalized state from forgejoChangeRequest; therefore the Merged view includes unmerged closed PRs, and the Closed view includes merged PRs. Filter decoded rows against input.state while continuing pagination until enough matching rows have been collected.

Useful? React with 👍 / 👎.

Comment on lines +225 to +228
for (const row of rows.slice(start)) {
if (consumed >= input.limit) break;
consumed++;
if (row) items.push(forgejoChangeRequest(row));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor Forgejo involvement filters

When the PR page requests involvement: "authored" or "reviewing", this implementation never examines input.involvement or input.viewer and appends every Forgejo row. The shared service only applies label, draft, review, and author-field filters afterward, so the Authored and Reviewing views remain indistinguishable from All for Forgejo repositories. Apply the requested involvement predicate before adding each row, while paging past nonmatching results.

Useful? React with 👍 / 👎.

Comment on lines +191 to +194
return (
parsed.host === host &&
parsed.repository === normalizeSourceControlRepository(repository, identity.provider)
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Match SSH-based Forgejo identities by web authority

For a Forgejo repository cloned over SSH whose refined web endpoint uses a non-default port, host is derived from the refined canonical identity as forge.example:3000, while parseChangeRequestUrl places that value in authority and leaves parsed.host as forge.example. Since an SSH locator cannot take the HTTP branch above, this comparison always fails and legacyLinkedPullRequestOf removes the linked PR from the compatibility projection. Compare the parsed authority, or the identity's refined webUrl, so these links remain visible to legacy consumers.

Useful? React with 👍 / 👎.

Comment on lines +619 to +622
const repository = repositoryPath.includes("/")
? repositoryPath
: `${login.user}/${repositoryPath}`;
if (!/^[^/\s]+\/[^/\s]+$/.test(repository))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve mounted Forgejo base paths for fj

When fj is configured for an instance mounted below a path such as https://host/forge, its key storage supplies a root-only login URL, while an HTTP clone URL supplies forge/owner/repo. That leaves basePath empty here, so repositoryPath retains all three segments and the following owner/repository validation rejects every operation—even if a usable tea login exists. Resolve the mount from the remote before validating the API repository, or skip the incapable fj login and fall back to tea.

Useful? React with 👍 / 👎.

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.

9 participants