Skip to content

refactor(source-control): Forgejo identity and Azure DevOps addressing move into their packages - #17624

Merged
juliusmarminge merged 2 commits into
t3/source-control-pullrequest-github-capabilitiesfrom
t3/source-control-pullrequest-host-capabilities
Oct 9, 2026
Merged

juliusmarminge merged 2 commits into
t3/source-control-pullrequest-github-capabilitiesfrom
t3/source-control-pullrequest-host-capabilities

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

The third cleanup layer, stacked on #17619. Two pieces of host-specific logic move out of generic server code and into their host packages.

Forgejo repository identity, from server.ts. server.ts built RepositoryIdentityResolver with about 25 lines of Forgejo logic. It parsed a Forgejo remote, asked the registry which login serves it, and derived the browser URL by stripping the installation mount.

  • That logic is now refineRepositoryIdentity, a resolver the Forgejo provider implements. The code moved unchanged.
  • server.ts asks each built-in driver's provider that implements it, in list order, and keeps the first change. It no longer imports from the Forgejo package.
  • The provider receives a resolveContext callback instead of the registry, so it stays decoupled from the server.
  • The logic had no direct test while it lived in server.ts. The package now tests an installation mount, an SSH alias, another host's identity, and a remote that no Forgejo login serves.

Azure DevOps addressing, from PullRequestService. Eight kind === "azure-devops" checks covered the list cursor key, the routing remote, which checkout serves a hosted reference, and the repository a completed action reports. All eight encode one fact: Azure DevOps names a repository by its full canonical key (host/org/project/repo).

  • That fact is now the repositoryKey({ canonicalKey }) resolver, which the Azure DevOps provider implements. A host without it is identified by owner/name.
  • The service resolves the key once per checkout into SupportedProject.repositoryKey and routes on that.

Behavior is unchanged.

Left out on purpose:

  • PullRequestService still has six Forgejo checks and pullRequestSyncKey has one Azure DevOps check. All of them go through pullRequestHostOf in contracts, which branches on "forgejo", and five web files call that function so the page and server agree on host names. They belong in the client layer, together with the branded kind and the client definitions.
  • The dev.azure.com host-narrowing shortcut in requireProject was already on main. I filed it as a follow-up instead of growing this layer.

Verified with tsc, knip, a frozen-lockfile install, and the open stack's tests (52 files, 1211 tests). The Effect-shortcut grep finds no hits in the added lines.

🤖 Generated with Claude Code — Claude Opus 5.5 in T3 Code

@juliusmarminge
juliusmarminge added this pull request to stack #17620 October 9, 2026 22:33
@juliusmarminge juliusmarminge changed the title t3/source control pullrequest host capabilities refactor(source-control): Forgejo identity and Azure DevOps addressing move into their packages Oct 9, 2026
@github-actions github-actions Bot added the vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. label Oct 9, 2026
@juliusmarminge juliusmarminge added the macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews label Oct 9, 2026
@github-actions github-actions Bot added the size:L 100-499 changed lines (additions + deletions). label Oct 9, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 5012fa4

Macroscope's review found this PR approvable — This is a contained source-control refactor that moves existing Forgejo and Azure DevOps behavior behind provider-owned capabilities without introducing a new workflow or changing product defaults. The runtime paths for existing providers retain their prior behavior, with focused tests added for the relocated Forgejo logic.

You can add or adjust custom eligibility rules. Learn more.

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ℹ️ No successful main baseline artifact is available yet. This run establishes the initial measurement.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire — 4.9 KiB — 6.8 KiB ✅
Codex Thread snapshot wire — 3.8 KiB — 4.9 KiB ✅
Codex Live turn WebSocket wire — 1.2 KiB — 2.0 KiB ✅
Codex Live turn WebSocket decoded — 20.8 KiB — 29.3 KiB ✅
Codex Live turn messages — 1 — 8 ✅
Claude Total thread wire — 5.0 KiB — 6.8 KiB ✅
Claude Thread snapshot wire — 3.8 KiB — 4.9 KiB ✅
Claude Live turn WebSocket wire — 1.2 KiB — 2.0 KiB ✅
Claude Live turn WebSocket decoded — 21.2 KiB — 29.3 KiB ✅
Claude Live turn messages — 1 — 8 ✅

Baseline: unavailable · PR result: 5012fa4 · Source CI: success

Scenario and decoded snapshot size

10 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.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Team
  • Run ID: 017bbf17-1ede-4e45-ac7b-30a31c27118c

📥 Commits

Reviewing files that changed from the base of the PR and between 771f9d4 and 5012fa4.


📒 Files selected for processing (6)
  • apps/server/src/pullRequest/PullRequestService.test.ts
  • apps/server/src/pullRequest/PullRequestService.ts
  • apps/server/src/server.ts
  • packages/source-control-azure-devops/src/server/AzureDevOpsPullRequestProvider.ts
  • packages/source-control-core/src/server/PullRequestProvider.ts
  • packages/source-control-core/src/server/SourceControlProvider.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review.



📝 Walkthrough

Walkthrough

The pull request adds provider-supplied repository keys for pull request routing. It also adds provider-based repository identity refinement, which the server delegates to built-in source-control providers, including Forgejo.

Changes

Canonical repository addressing

Layer / File(s) Summary
Declare canonical repository keys
packages/source-control-core/src/server/PullRequestProvider.ts, packages/source-control-azure-devops/src/server/AzureDevOpsPullRequestProvider.ts
The pull request provider API adds an optional repositoryKey resolver. Azure DevOps returns the supplied canonical key.
Apply canonical repository keys
apps/server/src/pullRequest/PullRequestService.ts, apps/server/src/pullRequest/PullRequestService.test.ts
The service uses provider repository keys for project deduplication, remotes, hosted-reference routing, and action results. The test fixture adds a repository-key resolver.

Provider-based identity refinement

Layer / File(s) Summary
Define and implement identity refinement
packages/source-control-core/src/server/SourceControlProvider.ts, packages/source-control-forgejo/src/server/ForgejoSourceControlProvider.ts, packages/source-control-forgejo/src/server/ForgejoSourceControlProvider.test.ts
The source-control provider API adds a refinement callback. Forgejo implements it for eligible remotes. Tests cover mounted HTTP and SSH paths and unchanged identities.
Delegate refinement to built-in drivers
apps/server/src/server.ts
The server invokes available refinement callbacks and returns the first changed identity, or the original identity if no provider changes it.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Refactor

Sequence Diagram(s)

sequenceDiagram
  participant Server
  participant BuiltInSourceControlProviders
  participant ForgejoSourceControlProvider
  participant ResolveContext
  Server->>BuiltInSourceControlProviders: Iterate through providers
  BuiltInSourceControlProviders->>ForgejoSourceControlProvider: Call refineRepositoryIdentity
  ForgejoSourceControlProvider->>ResolveContext: Resolve Forgejo context for cwd
  ResolveContext-->>ForgejoSourceControlProvider: Return provider context or null
  ForgejoSourceControlProvider-->>Server: Return refined or unchanged identity
Loading

Suggested reviewers: maria-rcks


Merge Risk: ⚪ Minimal · up to 5012f

No actionable merge-blocking issue is established; the change is mergeable after normal checks.

Pre-merge checks | Passed 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Title check Passed The title clearly and concisely identifies the main refactor: moving Forgejo identity handling and Azure DevOps addressing into their provider packages.
Description check Passed The description explains the problem, the changes, the intentional scope limits, and focused verification results. It does not use the template headings or provide explicit maintainer approval details…


✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR

🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR


  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

juliusmarminge and others added 2 commits October 9, 2026 16:06
…its own package

server.ts built RepositoryIdentityResolver with ~25 lines of Forgejo logic:
parse a Forgejo remote, ask the registry which login serves it, and derive
the repository's browser URL by stripping the installation mount.

That logic moves into the Forgejo provider as `refineRepositoryIdentity`, a
new optional SourceControlProvider capability. server.ts now asks each
built-in driver's provider that has one, in list order, and keeps the first
change; it no longer imports from the Forgejo package. The provider gets a
`resolveContext` callback rather than the registry, so it stays decoupled
from the server.

The logic is moved verbatim. It had no direct test while it lived in
server.ts; the package now has one covering the installation mount, an SSH
alias, another host's identity, and a remote no Forgejo login serves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ssing, not its kind

PullRequestService checked `kind === "azure-devops"` in eight places: the
list cursor key, the routing remote, which checkout serves a hosted
reference, and the repository a completed action reports. All eight
encode one fact: Azure DevOps names a repository by the checkout's full
canonical key (`host/org/project/repo`), and derives its organization from
that checkout.

That fact is now a resolver on PullRequestProviderApi, `repositoryKey`,
which the Azure DevOps provider implements. A host without one is
identified by `owner/name`. The service resolves the key once per checkout
into SupportedProject.repositoryKey and routes on it, so generic code
asks "what is this repository's key?" rather than "is this Azure?".

Behavior is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@juliusmarminge
juliusmarminge merged commit 51347ac into main Oct 9, 2026
31 checks passed
@juliusmarminge
juliusmarminge deleted the t3/source-control-pullrequest-host-capabilities branch October 9, 2026 23:22
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Oct 10, 2026
## What's Changed
* chore(deps): upgrade Effect to 4.0.2 by @juliusmarminge in pingdotgg/t3code#17571
* fix(devices): recover stalled video without losing simulator input by @juliusmarminge in pingdotgg/t3code#17566
* fix(web): keep checkout stable while pr actions load by @maria-rcks in pingdotgg/t3code#16625
* fix(mobile): show waiting thread status by @maria-rcks in pingdotgg/t3code#16693
* feat(web): add parent thread breadcrumb navigation by @maria-rcks in pingdotgg/t3code#16666
* fix(server): restart inactivity after snoozed threads wake by @maria-rcks in pingdotgg/t3code#16674
* feat(desktop): passkeys in the in-app browser on macOS by @juliusmarminge in pingdotgg/t3code#16952
* fix(client): load earlier turns works for MCP threads over T3 Connect by @juliusmarminge in pingdotgg/t3code#17599
* refactor(client): sign relay request URLs built from the HttpApi contract by @juliusmarminge in pingdotgg/t3code#17602
* refactor(source-control): add @t3tools/source-control-core by @juliusmarminge in pingdotgg/t3code#17573
* refactor(source-control): Forgejo lives in @t3tools/source-control-forgejo by @juliusmarminge in pingdotgg/t3code#17581
* refactor(source-control): Azure DevOps lives in @t3tools/source-control-azure-devops by @juliusmarminge in pingdotgg/t3code#17592
* refactor(source-control): GitLab lives in @t3tools/source-control-gitlab by @juliusmarminge in pingdotgg/t3code#17594
* refactor(source-control): Bitbucket lives in @t3tools/source-control-bitbucket by @juliusmarminge in pingdotgg/t3code#17597
* refactor(source-control): GitHub lives in @t3tools/source-control-github by @juliusmarminge in pingdotgg/t3code#17607
* refactor(usage): transcript readers come from their drivers by @juliusmarminge in pingdotgg/t3code#17576
* refactor(usage): OpenCode usage comes from provider-opencode by @juliusmarminge in pingdotgg/t3code#17577
* refactor(usage): Cursor account usage comes from provider-cursor by @juliusmarminge in pingdotgg/t3code#17578
* refactor(usage): Antigravity usage is a reader on its driver by @juliusmarminge in pingdotgg/t3code#17579
* refactor(usage): usage readers use Effect FileSystem and SqlClient by @juliusmarminge in pingdotgg/t3code#17615
* fix(web): composer context strip pads both edges evenly by @limineol in pingdotgg/t3code#17562
* test(usage): v4 cache upgrade test waits for the migrated cache write by @Mnigos in pingdotgg/t3code#17553
* feat(mobile): support Duo in the shared iOS app by @juliusmarminge in pingdotgg/t3code#12648
* refactor(source-control): GitManager reads provider resolvers, not host kinds by @juliusmarminge in pingdotgg/t3code#17617
* refactor(source-control): PullRequestService reads GitHub resolvers, not its kind by @juliusmarminge in pingdotgg/t3code#17619
* refactor(source-control): Forgejo identity and Azure DevOps addressing move into their packages by @juliusmarminge in pingdotgg/t3code#17624
* refactor: home directory comes from a HostProcessHomeDirectory reference by @juliusmarminge in pingdotgg/t3code#17628
* refactor(shared): host process references live in a HostProcess module by @juliusmarminge in pingdotgg/t3code#17641
* feat(web): filter PR comments by bots and resolved threads by @juliusmarminge in pingdotgg/t3code#17645
* fix(clients): remove redundant prefix from PR watch status by @extoci in pingdotgg/t3code#17635
* fix(web): pending requests wait until you stop typing by @maria-rcks in pingdotgg/t3code#17637
* fix(models): remove new badges from Claude Opus and Sonnet 5.5 by @extoci in pingdotgg/t3code#17646
* fix(ui): keep focus and selection borders visible across the app by @maria-rcks in pingdotgg/t3code#16675
* fix(mobile): prevent row presses during native back swipes by @juliusmarminge in pingdotgg/t3code#17648
* fix(server): Codex shadow homes replace stray sqlite maintenance locks by @juliusmarminge in pingdotgg/t3code#17663
* feat(desktop): T3 Code can be your default web browser on macOS by @juliusmarminge in pingdotgg/t3code#17587
* test(server): the ACP process-tree test no longer collides with the runner's own pid by @yordis in pingdotgg/t3code#17647
* fix(web): keep branch restore action inline in narrow composers by @Saikrishna1876 in pingdotgg/t3code#14811
* fix(web): composer banner actions stay inline whenever they fit by @maria-rcks in pingdotgg/t3code#17640


**Full Changelog**: pingdotgg/t3code@v0.0.46-nightly.20261009.2886...v0.0.46-nightly.20261010.2908

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.46-nightly.20261010.2908
github-actions Bot added a commit to davidvanderklay/t3code-flake that referenced this pull request Oct 10, 2026
## What's Changed
* chore(deps): upgrade Effect to 4.0.2 by @juliusmarminge in pingdotgg/t3code#17571
* fix(devices): recover stalled video without losing simulator input by @juliusmarminge in pingdotgg/t3code#17566
* fix(web): keep checkout stable while pr actions load by @maria-rcks in pingdotgg/t3code#16625
* fix(mobile): show waiting thread status by @maria-rcks in pingdotgg/t3code#16693
* feat(web): add parent thread breadcrumb navigation by @maria-rcks in pingdotgg/t3code#16666
* fix(server): restart inactivity after snoozed threads wake by @maria-rcks in pingdotgg/t3code#16674
* feat(desktop): passkeys in the in-app browser on macOS by @juliusmarminge in pingdotgg/t3code#16952
* fix(client): load earlier turns works for MCP threads over T3 Connect by @juliusmarminge in pingdotgg/t3code#17599
* refactor(client): sign relay request URLs built from the HttpApi contract by @juliusmarminge in pingdotgg/t3code#17602
* refactor(source-control): add @t3tools/source-control-core by @juliusmarminge in pingdotgg/t3code#17573
* refactor(source-control): Forgejo lives in @t3tools/source-control-forgejo by @juliusmarminge in pingdotgg/t3code#17581
* refactor(source-control): Azure DevOps lives in @t3tools/source-control-azure-devops by @juliusmarminge in pingdotgg/t3code#17592
* refactor(source-control): GitLab lives in @t3tools/source-control-gitlab by @juliusmarminge in pingdotgg/t3code#17594
* refactor(source-control): Bitbucket lives in @t3tools/source-control-bitbucket by @juliusmarminge in pingdotgg/t3code#17597
* refactor(source-control): GitHub lives in @t3tools/source-control-github by @juliusmarminge in pingdotgg/t3code#17607
* refactor(usage): transcript readers come from their drivers by @juliusmarminge in pingdotgg/t3code#17576
* refactor(usage): OpenCode usage comes from provider-opencode by @juliusmarminge in pingdotgg/t3code#17577
* refactor(usage): Cursor account usage comes from provider-cursor by @juliusmarminge in pingdotgg/t3code#17578
* refactor(usage): Antigravity usage is a reader on its driver by @juliusmarminge in pingdotgg/t3code#17579
* refactor(usage): usage readers use Effect FileSystem and SqlClient by @juliusmarminge in pingdotgg/t3code#17615
* fix(web): composer context strip pads both edges evenly by @limineol in pingdotgg/t3code#17562
* test(usage): v4 cache upgrade test waits for the migrated cache write by @Mnigos in pingdotgg/t3code#17553
* feat(mobile): support Duo in the shared iOS app by @juliusmarminge in pingdotgg/t3code#12648
* refactor(source-control): GitManager reads provider resolvers, not host kinds by @juliusmarminge in pingdotgg/t3code#17617
* refactor(source-control): PullRequestService reads GitHub resolvers, not its kind by @juliusmarminge in pingdotgg/t3code#17619
* refactor(source-control): Forgejo identity and Azure DevOps addressing move into their packages by @juliusmarminge in pingdotgg/t3code#17624
* refactor: home directory comes from a HostProcessHomeDirectory reference by @juliusmarminge in pingdotgg/t3code#17628
* refactor(shared): host process references live in a HostProcess module by @juliusmarminge in pingdotgg/t3code#17641
* feat(web): filter PR comments by bots and resolved threads by @juliusmarminge in pingdotgg/t3code#17645
* fix(clients): remove redundant prefix from PR watch status by @extoci in pingdotgg/t3code#17635
* fix(web): pending requests wait until you stop typing by @maria-rcks in pingdotgg/t3code#17637
* fix(models): remove new badges from Claude Opus and Sonnet 5.5 by @extoci in pingdotgg/t3code#17646
* fix(ui): keep focus and selection borders visible across the app by @maria-rcks in pingdotgg/t3code#16675
* fix(mobile): prevent row presses during native back swipes by @juliusmarminge in pingdotgg/t3code#17648
* fix(server): Codex shadow homes replace stray sqlite maintenance locks by @juliusmarminge in pingdotgg/t3code#17663
* feat(desktop): T3 Code can be your default web browser on macOS by @juliusmarminge in pingdotgg/t3code#17587
* test(server): the ACP process-tree test no longer collides with the runner's own pid by @yordis in pingdotgg/t3code#17647
* fix(web): keep branch restore action inline in narrow composers by @Saikrishna1876 in pingdotgg/t3code#14811
* fix(web): composer banner actions stay inline whenever they fit by @maria-rcks in pingdotgg/t3code#17640


**Full Changelog**: pingdotgg/t3code@v0.0.46-nightly.20261009.2886...v0.0.46-nightly.20261010.2908

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.46-nightly.20261010.2908
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant