Skip to content

Surface the built-in lane choice; default outbound User-Agent - #1357

Merged
kentcdodds merged 2 commits into
mainfrom
cursor/builtin-lane-choice-c0a2
Aug 10, 2026
Merged

kentcdodds merged 2 commits into
mainfrom
cursor/builtin-lane-choice-c0a2

Conversation

@kentcdodds

@kentcdodds kentcdodds commented Aug 10, 2026 •

Copy link
Copy Markdown
Owner

What

Live-testing the newly credentialed GitHub and Google built-ins (as the operator's own account) surfaced two rough edges:

1. The BYO-override was invisible

A complete bring-your-own record wins the connect lookup by design β€” but silently: clicking a built-in card reconnects the user's own app with zero indication. (Observed in production: the google built-in showed 0 connections after its operator "connected" to it; his complete BYO google record had won.) Now:

  • /account/integrations.json?name= carries builtInAvailable β€” true when an enabled built-in exists that the returned record isn't using.
  • /connect/oauth accepts platform=1, which forces the built-in prefill (and therefore the auto-start into the provider's consent screen). Forwarded through the SSR embed, the SPA route loader, and the in-component fallback identically.
  • The connect page shows a notice on user-lane configs when a built-in exists: "This uses your own OAuth app for {provider}. Prefer the hosted one? Use the built-in {provider} integration instead β€” connecting it replaces this connection's tokens and scopes." No silent lane conversion in either direction; the choice (and the scope trade-off) is the user's.
  • The notice link forces a full document load β€” a same-route SPA swap reuses the mounted route instance without re-running its init, so the auto-start would never fire (caught during verification).

2. Bare sandbox fetches to GitHub 403'd

GitHub rejects requests without a User-Agent and workerd sends none, so ad-hoc agent code calling api.github.com through createAuthenticatedFetch hit an opaque administrative 403 (packages that set their own UA were unaffected). The fetch gateway now sets kody-agent/1.0 when the caller doesn't provide one; caller values always win. Applied on both the placeholder-resolution path and the resolution-off fast path.

Testing

  • Data tests: preferPlatform overrides a complete BYO win; hasAlternativeBuiltInApp true only for user-lane records shadowing an enabled built-in.
  • Handler tests: platform=1 forwarding, builtInAvailable in the SSR embed shape.
  • Gateway tests: default UA applied on both paths, caller UA preserved.
  • Full validation green (one e2e re-run needed: the first run's failures were the e2e web server crashing from contention with the long-running dev server β€” all 7 pass in isolation).
  • Browser-verified end to end: notice renders on a complete-BYO account, the built-in link does a full load with platform=1 and auto-redirects into GitHub's real sign-in/authorize flow.
  • Production smoke tests via MCP: platform-lane GitHub token returns login: kentcdodds (with UA), google userinfo 200, integration_token_refresh fails cleanly on refresh-token-less connections, and refreshAccessToken throws the platform-lane teaching error.

Connect page notice offering the built-in alternative

builtin_lane_choice_flow_demo.mp4

Open in WebΒ Open in CursorΒ 

Summary by CodeRabbit

  • New Features

    • Added an option to switch from a custom OAuth app to an available hosted integration during setup and connection.
    • OAuth and integration details now indicate when a built-in alternative is available.
    • Added support for selecting the hosted integration when requested.
  • Bug Fixes

    • Outbound requests now use kody-agent/1.0 by default while preserving custom User-Agent values.

Live-testing the enabled GitHub and Google built-ins surfaced two
rough edges:

1. A complete bring-your-own record wins the connect lookup by design,
   but invisibly: connecting from a built-in card silently reconnects
   the user's own app (the google built-in showed zero connections
   after its operator 'connected' to it). The connect page now says so
   and offers the alternative β€” the integrations detail payload
   carries builtInAvailable, /connect/oauth accepts platform=1 to
   force the built-in prefill (which then auto-starts), and the notice
   warns that connecting the built-in replaces the connection's tokens
   and scopes. No silent lane conversion in either direction. The
   notice link forces a full document load because a same-route SPA
   swap reuses the mounted instance without re-running its init.

2. Bare sandbox fetches to api.github.com failed with an opaque 403:
   GitHub requires a User-Agent and workerd sends none. The fetch
   gateway now sets kody-agent/1.0 when the caller does not provide
   one.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@coderabbitai

coderabbitai Bot commented Aug 10, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. πŸŽ‰

ℹ️ Recent review info
βš™οΈ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a18248b4-acc7-458b-a989-d74057899b64

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 1673c5b and 806cc03.

πŸ“’ Files selected for processing (10)
  • packages/worker/client/routes/connect-oauth.tsx
  • packages/worker/src/app/account-integrations-data.node.test.ts
  • packages/worker/src/app/account-integrations-data.ts
  • packages/worker/src/app/handlers/account-integrations.node.test.ts
  • packages/worker/src/app/handlers/account-integrations.ts
  • packages/worker/src/app/handlers/connect-oauth.node.test.ts
  • packages/worker/src/app/handlers/connect-oauth.ts
  • packages/worker/src/mcp/fetch-gateway.node.test.ts
  • packages/worker/src/mcp/fetch-gateway.ts
  • packages/worker/universal/loader-data.ts

πŸ“ Walkthrough

Walkthrough

The OAuth flow now supports built-in integration preference, availability reporting, and switching from user-owned apps. Shared loader data and tests cover the new state. Gateway requests now use kody-agent/1.0 when no User-Agent is provided.

Changes

Built-in OAuth selection

Layer / File(s) Summary
OAuth integration resolution
packages/worker/src/app/account-integrations-data.ts, packages/worker/universal/loader-data.ts, packages/worker/src/app/account-integrations-data.node.test.ts
Integration loading can prefer enabled platform apps. The loader can report whether a built-in alternative exists. Loader data exposes builtInAvailable.
OAuth API and loader wiring
packages/worker/src/app/handlers/account-integrations.ts, packages/worker/src/app/handlers/connect-oauth.ts, packages/worker/src/app/handlers/*.node.test.ts
Named integration requests accept platform=1. API and OAuth loader responses include built-in availability. Tests cover platform preference and response data.
Built-in alternative in connection UI
packages/worker/client/routes/connect-oauth.tsx
The route preserves built-in availability and renders a navigation link during setup and connection. The link passes platform=1 and warns about replacing tokens and scopes.

Gateway User-Agent default

Layer / File(s) Summary
Default gateway request header
packages/worker/src/mcp/fetch-gateway.ts, packages/worker/src/mcp/fetch-gateway.node.test.ts
Outbound gateway requests use kody-agent/1.0 when no User-Agent is supplied. Caller-provided values remain unchanged. Tests cover both paths.

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

Sequence Diagram(s)

sequenceDiagram
  participant OAuthClient
  participant ConnectOauth
  participant AccountIntegrations
  participant IntegrationData
  OAuthClient->>ConnectOauth: Request OAuth route with platform=1
  ConnectOauth->>IntegrationData: Load integration with preferPlatform=true
  OAuthClient->>AccountIntegrations: Request named integration
  AccountIntegrations->>IntegrationData: Resolve integration and built-in availability
  IntegrationData-->>AccountIntegrations: Integration and builtInAvailable
  AccountIntegrations-->>OAuthClient: JSON integration response
Loading

Possibly related PRs

πŸš₯ Pre-merge checks | βœ… 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
βœ… Passed checks (4 passed)
Check name Status Explanation
Title check βœ… Passed The title clearly summarizes both primary changes: the built-in OAuth lane choice and the default outbound User-Agent.
Description check βœ… Passed The description explains the intent, summarizes the changes, and documents extensive testing, although it uses a custom heading instead of the template headings.
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.
✨ Finishing Touches πŸ’‘ 2
πŸ“ Generate docstrings πŸ’‘
  • Create stacked PR
  • Commit on current branch
πŸ› οΈ Fix failing CI checks πŸ’‘
  • Create stacked PR
  • Commit on current branch
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/builtin-lane-choice-c0a2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share

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

@github-actions

github-actions Bot commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

πŸ”Ž Preview deployed: https://kody-pr-1357.kody-a99.workers.dev

Worker: kody-pr-1357
D1: kody-pr-1357-db
KV: kody-pr-1357-oauth-kv

Mocks:

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@kentcdodds
kentcdodds merged commit d7f5117 into main Aug 10, 2026
10 checks passed
@kentcdodds
kentcdodds deleted the cursor/builtin-lane-choice-c0a2 branch August 10, 2026 04:03
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.

2 participants