Repository navigation
refactor(source-control): reference parsing and project matching are host resolvers - #17770
Conversation
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR centralizes change-request parsing, host resolution, and project matching behind a new shared source-control resolver contract used across all providers. Although intended as a behavior-preserving refactor, its cross-package impact on link handling and cached pull-request selection warrants human review. You can add or adjust custom eligibility rules. Learn more. |
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: unavailable · PR result: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
509298c to
f6baca3
Compare
…host resolvers The last host switches in web parsed pasted references with one regex per host and one CLI form per host, and matched change request links to projects with Forgejo and Azure DevOps special cases. Each is now a resolver every definition answers: checkoutCommandArgument, isChangeRequestReference, isChangeRequestInRepository, canReadChangeRequestOnHost, changeRequestUrlHost and checkoutChangeRequestHost. No behavior change: Bitbucket and GitCafe still accept no pasted URLs or checkout commands, which is what the old parser did. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
f6baca3 to
cd33ae9
Compare
## What's Changed * feat(server): stop Claude subagents without stopping their owner by @Yash-Singh1 in pingdotgg/t3code#17826 * fix(server): stopped native subagents no longer read as Running by @im-kvijay in pingdotgg/t3code#17223 * perf(server): t3_thread_list reads only the listed project's threads by @only21mil in pingdotgg/t3code#17843 * fix(server): show diffs for projects outside the server cwd by @maria-rcks in pingdotgg/t3code#17724 * fix(server): check the specific scope for scripts, preview input, and full-access MCP grants by @juliusmarminge in pingdotgg/t3code#17772 * fix(source-control): stop Forgejo status refresh from scanning every pull request by @loispostula in pingdotgg/t3code#12223 * refactor(contracts): source control provider kind is an open branded slug by @juliusmarminge in pingdotgg/t3code#17739 * feat(source-control): each host package ships a client definition by @juliusmarminge in pingdotgg/t3code#17746 * refactor(client-runtime): add project clone sources come from host definitions by @juliusmarminge in pingdotgg/t3code#17756 * refactor(web): host presentation and behavior come from client definitions by @juliusmarminge in pingdotgg/t3code#17757 * refactor(source-control): reference parsing and project matching are host resolvers by @juliusmarminge in pingdotgg/t3code#17770 * feat(pull-requests): quick actions follow each host's capabilities, not GitHub by @juliusmarminge in pingdotgg/t3code#17774 * feat(projects): new projects can be published to any ready host by @juliusmarminge in pingdotgg/t3code#17860 * fix(server): send Claude MCP servers over the control channel by @juliusmarminge in pingdotgg/t3code#17898 * fix(web): a finished reply replaced by a steer is no longer labeled partial by @juliusmarminge in pingdotgg/t3code#17761 * fix(client-runtime): queued runs that start after a steer show up in the thread by @juliusmarminge in pingdotgg/t3code#17764 * feat(mobile): choose the microphone order for voice input by @juliusmarminge in pingdotgg/t3code#17896 * feat(source-control): host settings live on each host's definition, with a GitCafe token by @juliusmarminge in pingdotgg/t3code#17901 ## New Contributors * @only21mil made their first contribution in pingdotgg/t3code#17843 * @loispostula made their first contribution in pingdotgg/t3code#12223 **Full Changelog**: pingdotgg/t3code@v0.0.46-nightly.20261010.2935...v0.0.46-nightly.20261010.2948 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.46-nightly.20261010.2948
## What's Changed * feat(server): stop Claude subagents without stopping their owner by @Yash-Singh1 in pingdotgg/t3code#17826 * fix(server): stopped native subagents no longer read as Running by @im-kvijay in pingdotgg/t3code#17223 * perf(server): t3_thread_list reads only the listed project's threads by @only21mil in pingdotgg/t3code#17843 * fix(server): show diffs for projects outside the server cwd by @maria-rcks in pingdotgg/t3code#17724 * fix(server): check the specific scope for scripts, preview input, and full-access MCP grants by @juliusmarminge in pingdotgg/t3code#17772 * fix(source-control): stop Forgejo status refresh from scanning every pull request by @loispostula in pingdotgg/t3code#12223 * refactor(contracts): source control provider kind is an open branded slug by @juliusmarminge in pingdotgg/t3code#17739 * feat(source-control): each host package ships a client definition by @juliusmarminge in pingdotgg/t3code#17746 * refactor(client-runtime): add project clone sources come from host definitions by @juliusmarminge in pingdotgg/t3code#17756 * refactor(web): host presentation and behavior come from client definitions by @juliusmarminge in pingdotgg/t3code#17757 * refactor(source-control): reference parsing and project matching are host resolvers by @juliusmarminge in pingdotgg/t3code#17770 * feat(pull-requests): quick actions follow each host's capabilities, not GitHub by @juliusmarminge in pingdotgg/t3code#17774 * feat(projects): new projects can be published to any ready host by @juliusmarminge in pingdotgg/t3code#17860 * fix(server): send Claude MCP servers over the control channel by @juliusmarminge in pingdotgg/t3code#17898 * fix(web): a finished reply replaced by a steer is no longer labeled partial by @juliusmarminge in pingdotgg/t3code#17761 * fix(client-runtime): queued runs that start after a steer show up in the thread by @juliusmarminge in pingdotgg/t3code#17764 * feat(mobile): choose the microphone order for voice input by @juliusmarminge in pingdotgg/t3code#17896 * feat(source-control): host settings live on each host's definition, with a GitCafe token by @juliusmarminge in pingdotgg/t3code#17901 ## New Contributors * @only21mil made their first contribution in pingdotgg/t3code#17843 * @loispostula made their first contribution in pingdotgg/t3code#12223 **Full Changelog**: pingdotgg/t3code@v0.0.46-nightly.20261010.2935...v0.0.46-nightly.20261010.2948 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.46-nightly.20261010.2948
After #17757 the last real host switches in client code were these:
pullRequestReference.tsturned a pasted reference into a PR. It used one URL regex per host (GitHub, GitLab, Forgejo, Azure) and one CLI form per host (gh pr checkout,glab mr checkout,tea pr checkout,az repos pr checkout). It feeds the Link PR and PR-thread dialogs and the branch selector.openPullRequestLink.tsmatched a change request link to a project, with a ForgejowebUrlspecial case,kind === "azure-devops"branches, and an earlydev.azure.comreturn.pullRequestDetail.logic.tsmade two GitHub/Forgejo checks: which host form a cached URL uses, and which hosts can fill in a missing reference host from the checkout.These rules differ per host, so they become resolvers that every definition answers, not shared helpers:
checkoutCommandArgument(input)--id/-iparsingisChangeRequestReference(url)isChangeRequestInRepository(identity, link)findProjectForChangeRequest's Forgejo-webUrl, Azure canonical-key and path/host branchescanReadChangeRequestOnHost(identity, link)findProjectOnChangeRequestHost's Forgejo mount check, Azure's "never host-wide" rule and the shared host matchchangeRequestUrlHost(url)provider === "forgejo" ? url.host : url.hostnamecheckoutChangeRequestHost(identity)identity?.provider !== "github"inresolvePullRequestReferenceHostThe parts every host shares live as plain helpers in core and are used by the definitions: the authority/port check, the path match and the
pullRequestHostOfhost match. The Azure early return in the web helper is gone, becausecanReadChangeRequestOnHostreturning false for Azure says the same thing per project.No behavior change. Bitbucket and GitCafe answer null and false for the two parsing resolvers, because the old parser accepted neither their URLs nor a
cafe pr checkoutcommand. Accepting them would be a feature, and that should be its own PR.Verification
parsePullRequestReferencewith the old one on 34 inputs. They covered every host's URL and CLI form, flags, casing, empty input, branch names and Bitbucket/GitCafe URLs, and all 34 produced identical output. The test is not committed.pullRequestReference.test.tsandopenPullRequestLink.test.tspass unchanged.npx tsc --noEmit -p .is clean in all sevensource-control-*packages, client-runtime, web, mobile and server.vp test runpasses on client-runtime,apps/web/src/lib,components/pullRequest,hooksand the reference consumers: 95 files, 1,311 tests.vp linton the touched files reports 0 errors,knipis clean, and the Effect-shortcut grep over the added lines finds nothing.🤖 Generated with Claude Code