Skip to content

fix(desktop): keep the native preview User-Agent so Turnstile passes - #7110

Merged
juliusmarminge merged 1 commit into
pingdotgg:mainfrom
akriaueno:fix/preview-turnstile-user-agent
Sep 12, 2026
Merged

fix(desktop): keep the native preview User-Agent so Turnstile passes#7110
juliusmarminge merged 1 commit into
pingdotgg:mainfrom
akriaueno:fix/preview-turnstile-user-agent

Conversation

@akriaueno

@akriaueno akriaueno commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

What Changed

apps/desktop/src/preview/BrowserSession.ts no longer rewrites the preview guest's User-Agent (the getUserAgent() → strip Electron/… / t3code/…setUserAgent() block is removed). A regression test asserts the guest's effective User-Agent stays equal to Electron's native one (the mock applies setUserAgent calls, so any reintroduced rewrite fails it — verified by mutation-testing it against the old code).

I checked for other UA-touching paths — app.userAgentFallback, a useragent attribute on the <webview>, webRequest header rewriting, other session setup — there are none, and the removal leaves no dead imports.

Why

Fixes #5002. On https://dash.cloudflare.com/login the Turnstile widget fails with console error 600010 and is recreated every ~3.3s, so login can never complete.

Why the rewrite existed: it shipped with the original preview panel, and the design doc annotates it as "strip electron/t3code from UA so dev preview doesn't trip bot detection". No other motivation (e.g. a specific OAuth breakage) is recorded in the history. Against Turnstile it empirically does the opposite: the rewrite is precisely what trips the bot check.

What I measured: I isolated the trigger with a minimal reproduction (akriaueno/electron-turnstile-repro), each case in a fresh session, instrumented to dump the guest's navigator.userAgent, navigator.userAgentData, and the actually-sent request headers. Across every case userAgentData is identical and no Sec-CH-UA* headers are sent at all, so the UA string is the only variable — and it alone flips the outcome. Turnstile is closed, so I don't claim the exact discriminator; the reproducible observation is that the untouched native UA passes and every rewritten variant fails.

Measured matrix and everything else that was ruled out

Electron 41.5.0 / Chromium 146, Ubuntu 24.04, fresh --user-data-dir per case. The User-Agent header and navigator.userAgent always agree; in all four cases navigator.userAgentData.brands is Not-A.Brand 24, Chromium 146 (no Google Chrome, no Electron entry) and no Sec-CH-UA* headers are sent.

UA string presented to the page/site Turnstile
native: … <app>/0.0.0 Chrome/146.0.7680.216 Electron/41.5.0 Safari/537.36 passes
setUserAgent() with the unchanged native string passes
app token stripped, Electron/… kept fails (600010 loop)
Electron/… stripped (what this app shipped) fails (600010 loop)

The no-op re-set passing rules out the setUserAgent() call itself; the app-token-stripped case failing shows no single token is the trigger.

Also ruled out as causes during the investigation: pre-granted permission handlers (the repro grants them like this app does — still passes), CDP debugger attachment (real Chrome passes with DevTools open; a diagnostic build that never attaches still looped), the preview preload / contextIsolation (a build without them still looped), WebGL/GPU state (real Chrome passes on the same machine with WebGL blocklisted), and BrowserWindow vs <webview>.

Trade-off: sites now see the stock Electron UA (Electron and app tokens included) instead of a Chrome-looking one — exactly what a default Electron <webview> sends, and the identity Turnstile accepts. The flip side is that services which block embedded browsers by UA sniffing (notably Google OAuth's disallowed_useragent policy) can now recognize the preview as Electron. If that ever needs solving, the honest route is overriding userAgentMetadata together with the UA via CDP (Network.setUserAgentOverride) so every layer stays consistent — a much larger, fingerprint-chasing change I deliberately left out.

Verified on Linux (Ubuntu 24.04): the login challenge completes and sign-in proceeds. vp test run apps/desktop/src/preview/BrowserSession.test.ts passes (7 tests); tsgo --noEmit in apps/desktop reports no new diagnostics.

Screencast

Screencast.from.2026-08-16.00-49-47.mp4

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes — N/A, no UI changes
  • I included a video for animation/interaction changes — screencast of the Turnstile behavior above

Note

Medium Risk
Preview identity visible to sites changes (full Electron UA vs Chrome-like), which can affect bot/OAuth UA policies, though scope is limited to preview partition sessions.

Overview
Stops rewriting the desktop preview guest session User-Agent in BrowserSession.getSession — the previous getUserAgent() → strip Electron/… and t3code/…setUserAgent() path is removed so the webview keeps Electron’s native string. That fixes Cloudflare Turnstile error 600010 / endless challenge loops on sites like the Cloudflare login (#5002).

Adds a regression test that models a session whose setUserAgent updates the effective UA and asserts it still matches the native value after getSession, so any future rewrite fails CI.

Reviewed by Cursor Bugbot for commit 1043f76. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Keep native Electron User-Agent in desktop preview session so Cloudflare Turnstile passes

Removes the UA rewriting logic in BrowserSession.getSession that stripped Electron and t3code tokens from the session's User-Agent. Cloudflare Turnstile fails when the UA is modified, so the guest session now retains Electron's native UA unchanged.

Macroscope summarized 1043f76.

Summary by CodeRabbit

  • Bug Fixes

    • Preserved Electron’s native browser User-Agent for desktop sessions.
    • Fixed login failures with Cloudflare Turnstile caused by User-Agent rewriting.
  • Tests

    • Added coverage confirming the User-Agent remains unchanged when a browser session is created.

@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: e878f1b5-68ed-47c9-b432-43ba5721f34e

📥 Commits

Reviewing files that changed from the base of the PR and between a43f9b4 and 353a5ee.

📒 Files selected for processing (2)
  • apps/desktop/src/preview/BrowserSession.test.ts
  • apps/desktop/src/preview/BrowserSession.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

The preview browser no longer rewrites Electron’s native User-Agent. A regression test verifies that session creation preserves the native value.

Changes

Native User-Agent handling

Layer / File(s) Summary
Preserve native User-Agent
apps/desktop/src/preview/BrowserSession.ts, apps/desktop/src/preview/BrowserSession.test.ts
getSession no longer strips Electron and t3code tokens from the User-Agent. The mock type is more precise, and a test verifies that the native User-Agent remains unchanged.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: juliusmarminge

Merge Risk: ⚪ Minimal · up to fc47a

Preview sessions preserve their native User-Agent, and the regression test guards against reintroducing a rewrite. No actionable merge risk remains.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the primary change: preserving the native preview User-Agent so Cloudflare Turnstile passes.
Description check ✅ Passed The description includes What Changed, Why, UI impact, checklist status, verification results, reproduction details, and trade-offs. It is complete and directly related to the pull request.
Linked Issues check ✅ Passed Issue #5002 requires a stable Cloudflare login and Turnstile flow. BrowserSession.getSession no longer rewrites the session User-Agent, so the guest keeps Electron's native value. The new regression…
Out of Scope Changes check ✅ Passed The changes are limited to preview session User-Agent handling and its regression test. The permission handlers remain unchanged. The changes directly support issue #5002 and do not demonstrate unrela…
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2…
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 15, 2026
@macroscopeapp

macroscopeapp Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved 1043f76

Straightforward bug fix that removes User-Agent rewriting code which was breaking Cloudflare Turnstile login flows. The change is limited to removing problematic behavior and includes a regression test to prevent reintroduction.

You can customize Macroscope's approvability policy. Learn more.

@shivamhwp

Copy link
Copy Markdown
Collaborator

Note: GPT-6 on behalf of shivam (@shivamhwp).

Please rebase this against current main and repeat the native Turnstile check on the current Electron 44.1.0 runtime. The PR's measured matrix used Electron 41.5.0; retaining the native User-Agent still passes the session regression, but that regression cannot establish current challenge behavior. Keep the existing permission handlers when resolving the session changes.

@akriaueno
akriaueno force-pushed the fix/preview-turnstile-user-agent branch from 1043f76 to 353a5ee Compare September 12, 2026 18:07
Why:
- The preview browser rewrote its guest User-Agent to strip the Electron
  and app tokens (added with the original preview panel to avoid tripping
  bot detection). On https://dash.cloudflare.com/login this backfires:
  Cloudflare Turnstile fails its integrity check with console error 600010
  and recreates the challenge every ~3.3s, so login never completes (pingdotgg#5002).
- A minimal Electron reproduction (akriaueno/electron-turnstile-repro)
  isolates the UA string as the single variable: the native UA passes,
  re-setting the unchanged native string passes, and every rewritten
  variant fails — including one that keeps the Electron token. Across all
  cases navigator.userAgentData is identical and no Sec-CH-UA headers are
  sent, so nothing else differed. Turnstile is closed, so the exact
  discriminator is unknowable; empirically, only the untouched native UA
  is accepted.

Changes:
- Stop rewriting the guest User-Agent in BrowserSession.getSession.
- Add a test asserting getSession does not call setUserAgent, with a
  comment explaining why the absence matters.

Impact:
- Sites now see the stock Electron UA (Electron and app tokens included)
  instead of a Chrome-looking one. Services that block embedded browsers
  by UA (e.g. Google OAuth's disallowed_useragent policy) may now
  recognize the preview as Electron; fixing that properly would require
  overriding userAgentMetadata in lockstep via CDP, out of scope here.
- No other code rewrites the preview UA (no userAgentFallback, webview
  useragent attribute, or webRequest header rewriting), and the removal
  leaves no dead imports.

Verification:
- Manually verified on rebuilt Linux (Ubuntu 24.04) and macOS builds: the
  Turnstile challenge on https://dash.cloudflare.com/login completes and
  login proceeds.
- vp test run apps/desktop/src/preview/BrowserSession.test.ts (7 passed)
- tsgo --noEmit in apps/desktop (no new diagnostics)

Fixes pingdotgg#5002
@akriaueno
akriaueno force-pushed the fix/preview-turnstile-user-agent branch from cde61c7 to fc47acb Compare September 12, 2026 18:47
@cursor

cursor Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@akriaueno

Copy link
Copy Markdown
Contributor Author

@shivamhwp
Rebased onto current main and verified that the Cloudflare Turnstile challenge completes successfully in the rebuilt app running Electron 44.1.0. The existing permission handlers are preserved. Video attached.

fc47acb.mp4

@juliusmarminge
juliusmarminge merged commit c542b78 into pingdotgg:main Sep 12, 2026
22 checks passed
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 13, 2026
## What's Changed
* fix(mobile): render photo library picks to a bounded JPEG off the JS thread by @Nelglor in pingdotgg/t3code#11440
* fix(desktop): keep the native preview User-Agent so Turnstile passes by @akriaueno in pingdotgg/t3code#7110
* fix(chat): keep user input outside collapsed work by @maria-rcks in pingdotgg/t3code#11363
* fix(web): preserve preview focus on window return by @Lucenx9 in pingdotgg/t3code#11444
* fix(web): complete thread status icons and keep input threads prominent by @maria-rcks in pingdotgg/t3code#11461
* feat(web): tint image chips with their average color by @maria-rcks in pingdotgg/t3code#11468
* fix(web): move viewer controls outside media and restore arrow navigation by @maria-rcks in pingdotgg/t3code#11470
* fix(web): tighten sidebar search and footer spacing by @maria-rcks in pingdotgg/t3code#11466
* feat(web): subagent spawns render as an expandable work row by @maria-rcks in pingdotgg/t3code#11433
* fix(web): keep subagent rows visible under folded turns by @maria-rcks in pingdotgg/t3code#11474
* fix(usage): make unavailable account limits more visible by @dominic-r in pingdotgg/t3code#10601
* fix(desktop): bound backend shutdown wait during quit by @ishaanko in pingdotgg/t3code#7599
* feat(web): choose the default diff file state by @maria-rcks in pingdotgg/t3code#11484
* feat(composer): fold large pastes into text attachments by @chrisdeeming in pingdotgg/t3code#11442
* feat(web): expose each chat message as a heading for screen readers by @Leos-Khai in pingdotgg/t3code#11199
* fix(usage): respect provider account homes by @maria-rcks in pingdotgg/t3code#11485

## New Contributors
* @Nelglor made their first contribution in pingdotgg/t3code#11440
* @akriaueno made their first contribution in pingdotgg/t3code#7110
* @Leos-Khai made their first contribution in pingdotgg/t3code#11199

**Full Changelog**: pingdotgg/t3code@v0.0.41-nightly.20260912.1612...v0.0.41-nightly.20260913.1625

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.41-nightly.20260913.1625
aorwall added a commit to aorwall/t3code that referenced this pull request Sep 13, 2026
Merges `upstream/main` at `0c5771d60` into the fork, from merge base
`e81606494` — 32 upstream commits.

The range is mostly client polish, plus two structural changes that
mattered
here: upstream extracted the sidebar header into a new component
(`SidebarThreadHeader.tsx`, pingdotgg#11315), which is where two fork gates had
to be
re-homed, and upstream added a `context` field to orchestration messages
at the
exact anchor the fork's `origin` field sits on, which is four of the
eight
conflicts.

## Merge stats

- Landed (`HEAD^1..HEAD`): 489 files, 36117+/5930−
- Upstream range (base..`HEAD^2`): 484 files, 35784+/5824−
- Fork delta (`HEAD^2..HEAD`): 767 files, 78724+/2528−

The two file lists reconcile exactly. The 5 extra landed files are all
fork-owned and none of them is upstream work:
`apps/web/src/fork/SidebarThreadFilter.tsx`
(one className, described below), `docs/fork/inventory.json`,
`docs/fork/gaps.md`, `docs/fork/upstream-merge-log.md`, and
`.agents/skills/fork-upstream-merge/scripts/unsupported-methods.mjs`.
Nothing in
the upstream range failed to land.

## Conflicts

All 8 were resolved by the verdict `preflight.mjs` printed. No `decide`
conflict
was left unresolved.

- `projector.ts`, `orchestration.ts`, `threadReducer.ts`,
`MessagesTimeline.tsx`
— `converged — message-origin-upstream-files`, and all the same
conflict:
upstream appended where the fork already appends. Both sides kept, twice
per
file for the first three. `duplicate-adds.mjs` confirms no line was
taken
  twice.
- `Sidebar.tsx` — `converged — thread-visibility-upstream-files`. Took
upstream
whole; its `SidebarThreadFilter` import was left unused by the
extraction and
  was removed.
- `SettingsSidebarNav.tsx` — unlisted. Kept the fork's
`settingsPathEnabled`
filter over the personal nav items and took upstream's new active-state
rule
(`/settings/general` stays active on `/settings/open-source-licenses`).
- `ChatComposer.tsx` — unlisted, so `decide, then add an entry`. Both
fork deltas
  survived and the entry is now written; see below.
- `routeTree.gen.ts` — generated; regenerated with
`regen-route-tree.mjs` after
  the install.

`pnpm-lock.yaml` auto-merged rather than conflicting, so it was reset to
`upstream/main` and the fork edges re-derived with `vp i`. The remaining
diff
against upstream is exactly the `@t3tools/moatless-api` workspace link,
`mermaid ^11.17.2`, and one alchemy peer hash.

Two findings worth naming here:

- **A fork gate's host file was replaced by a file upstream had not
written yet.**
  pingdotgg#11315 extracted the whole sidebar header into
`apps/web/src/components/sidebar/SidebarThreadHeader.tsx`. Both fork
deltas
were re-applied there additively — the `FEATURES.projectManagement` gate
on
New project, and `<SidebarThreadFilter />` as a third child of
upstream's new
segmented icon well. No props threaded, no state added, no upstream JSX
re-indented. The one edit outside that file is
`SidebarThreadFilter.tsx`'s
  trigger className, now `size-7` so it matches upstream's own
  `SidebarHeaderIconButton` in the well it now sits in.
- **The unsupported-method derivation could not read the backend, and
that was
the script's fault, not a finding.** `unsupported-methods` exited 2 with
"could
not read the backend dispatch". The Moatless backend moved its dispatch
a
second time: `crates/t3code/src/rpc/dispatch.rs` is now a module stub
over an
`rpc/dispatch/` directory whose `routing.rs` holds the arms and whose
siblings
hold the handler bodies. `BACKEND_APIS` now names the directory and the
script
concatenates every `.rs` file in it — pointing it at `routing.rs` alone
would
have read the arms and lost the handlers, and `refusesInside` only
follows
calls it can find in the same source, so every conditional refusal would
have
  come back as a false DROP.

## Inventory

- `moatless-admin-pages` was stale: it still listed the two Workspaces
admin
routes that the 2026-09-12 commit folded into the project settings page.
Re-pointed to the five surfaces that remain, and the untracked delta
that move
  left behind is now its own entry, `project-workspace-settings`.
- `chat-surface-gates` gained
`apps/web/src/components/chat/ChatComposer.tsx`
with a guard on `FEATURES.accessMode`, plus a `chat-composer-gates` path
policy
so the next merge gets a cached verdict instead of the same decision.
The two
deltas there are the runtime-mode picker lifted into a
`runtimeModePicker`
  const behind the flag, and `phase === "running"` left out of
  `collapsedComposerPrimaryActionDisabled`.
- `inventory-check.mjs` is clean.

## Unsupported methods

0 ADD, 0 DROP, 2 KEEP (`git.preparePullRequestThread`, `vcs.switchRef`),
5 known
exceptions still firing, no stale ones. `packages/contracts/src/rpc.ts`
is
unchanged: the range's one unsupported-surface change is upstream's
Cursor
`--classic` launcher fix, which lands on a method already refused.

## Feature classification

### Usable as-is

Client-side work the fork can expose with no Moatless backend or
deployment
change. 28 of the 32 commits.

- Open-source license notices page (pingdotgg#8962) — new
`/settings/open-source-licenses`
route; upstream also made `/settings/general` stay active while it is
open.
- Client perf: fewer repeated sorts and date formats (pingdotgg#11019).
- Inline file previews and attachment chips across surfaces (pingdotgg#11265) —
rides
  `attachments.createUploadUrl` and `assets.createUrl`, both dispatched.
- Subagent spawns as an expandable work row (pingdotgg#11433) and those rows kept
visible
under folded turns (pingdotgg#11474) — derived from the orchestration event
stream the
  backend already serves.
- Opt-in thread notifications and sounds (pingdotgg#11481) — client settings,
persisted
  through the `server.getSettings` read the backend serves.
- Large pastes folded into text attachments (pingdotgg#11442); user input kept
outside
collapsed work (pingdotgg#11363); each chat message exposed as a heading for
screen
  readers (pingdotgg#11199); the default diff file state (pingdotgg#11484).
- Sidebar project scope folded into the search row (pingdotgg#11315); thread
status icons
completed and input threads kept prominent (pingdotgg#11461); sidebar search and
footer
  spacing (pingdotgg#11466); draft row heights matched to thread rows (pingdotgg#11512).
- Image chips tinted with their average colour (pingdotgg#11468); viewer controls
moved
outside the media with arrow navigation restored (pingdotgg#11470); snapshot
preview size
preserved in sent messages (pingdotgg#11429); preview focus preserved on window
return
  (pingdotgg#11444).
- Unavailable account limits made more visible (pingdotgg#10601) — web-only; the
backend
  dispatches `server.getUsageSummary`.
- Saved environments switched off instead of removed (pingdotgg#11478) — entirely
client-side (connection catalog and registry). This build runs one
environment
and gates the Connections settings page, so nothing on screen changes;
the
  catalog behaviour carries.
- Desktop and mobile: long offscreen text in SnapShots (pingdotgg#11250), native
preview
User-Agent kept for Turnstile (pingdotgg#7110), bounded backend shutdown wait on
quit
(pingdotgg#7599), expo-audio pinned (pingdotgg#11426), photo library picks rendered to a
bounded
JPEG off the JS thread (pingdotgg#11440), launch crash with a PR stack (pingdotgg#11486),
the
  shared-content alert after sending (pingdotgg#11487).
- Repository hygiene: `.pnpm-store/v11` deleted.

### Unsupported in Moatless / needs implementation

- **Cursor links open in classic IDE mode (pingdotgg#11498).** Upstream gave
Cursor
`baseArgs: ["--classic"]` in `packages/contracts/src/editor.ts` so a
file open
  targets the IDE rather than its Agents Window, and tested it in
  `apps/server/src/process/externalLauncher.ts`. The method behind it,
`shell.openInEditor`, is not dispatched — the browser is not on the
machine the
workspace is on — so this lands in the contract and in `apps/server` and
changes nothing here. Recorded in `docs/fork/gaps.md` under _Opening in
an
external editor_, whose standing conclusion is that the surface is a
candidate
  for deletion rather than for serving.

### Backend behavior to consider reproducing in Moatless

All three are recorded in `docs/fork/gaps.md` under _Runtime fixes
upstream made
to its own server_. Nothing in this repository holds them open; they are
Moatless-side work.

- **Listing pull requests should read only the projects asked about
(pingdotgg#11299).**
`listWorkspaceProjects` fetched the whole shell snapshot and filtered
it; it now
  asks the projection for the one project, or for the listed ids
  (`apps/server/src/pullRequest/PullRequestService.ts`,
  `persistence/Layers/ProjectionSnapshotQuery.ts`). Moatless dispatches
`pullRequests.summary`, so the same cost lands on it as soon as a
summary is
  derived from a list.
- **Usage should read each provider account's own history directory
(pingdotgg#11485).**
Upstream resolves an account's home from its home setting or its
`CODEX_HOME` /
`CLAUDE_CONFIG_DIR` / `GROK_HOME` variable, counts disabled accounts,
and
de-duplicates accounts sharing a directory
(`apps/server/src/usage/UsageService.ts`).
Moatless serves `server.getUsageSummary` itself, so an account with a
custom
home reports zero there — or double — until it resolves homes the same
way.
- **Forgejo and Gitea remotes should be first-class source control
(pingdotgg#11436).**
Upstream recognises both hosts and drives them with the `fj` and `tea`
CLIs
  across remote identity, PR creation and PR sync (`git/GitManager.ts`,
  `project/RepositoryIdentityResolver.ts`,
`orchestration/PullRequestSyncReactor.ts`). Moatless owns git and pull
requests,
so a Forgejo or Gitea project is an unrecognised host there regardless
of what
  the client can render.

## Verification

`verify.mjs` is green on seven of eight checks: `duplicate-adds` (none
across 34
files both sides changed), `tripwires` (3 deleted surfaces intact,
exactly the 5
known re-deletions, 3 allowed workflows), `resolution-check` (16
fork-delta paths
still differ from upstream, 17 carry upstream's change, 17
theirs-verbatim
byte-identical, 18 unlisted), `unsupported-methods`, `fmt:check`,
`lint`,
`typecheck`.

`test` is red on one file, and it is the standing environmental failure
rather
than a merge regression:

- `@t3tools/desktop` → `scripts/browser-secret-native.test.mjs > bundled
libsecret
helper` fails with `Package 'libsecret-1' not found` from `pkg-config`.
1 file
  of 105; the rest of the package is 1341 tests passed. The test file is
byte-identical to upstream, arrived on the fork before this merge, and
the
sandbox image ships neither `libsecret-1` nor its pkg-config file. There
is no
  root in the sandbox, so it cannot be installed here. Recorded in
`docs/fork/gaps.md` under _The desktop suite needs libsecret, which the
sandbox
  does not have_.

Four packages did not finish under `vp run -r test` and were each run
alone
again, all green: `@t3tools/mobile` (165 files, 1528 tests), `t3` (317
files,
4528 tests), `@t3tools/web` (412 files, 5205 tests), `t3code-relay` (30
files,
284 tests).

The owned-concern sweep over newly added upstream files found no keyword
hits, so
no `concerns` entry was needed.

**CI caught one thing no local check runs.** `Build & push moatless-t3`
failed on
the first push: upstream's new `t3code:third-party-licenses` plugin
(pingdotgg#8962) runs
in `generateBundle` and refuses any bundled package whose license it
cannot
resolve, and three packages reach the web bundle only through the fork's
own
`mermaid` edge — `khroma` via mermaid, `fastdom` and `strictdom` via
cytoscape
under it — so upstream's config has never carried overrides for them.
Fixed with
three `packageOverrides` entries: `khroma` needed a `license: "MIT"`
declaration
only, since it ships its own `license` file, and `fastdom` and
`strictdom` needed
a `generatedNotice` each, since both declare MIT and ship no notice
file.
Verified with the build itself — all three now appear in
`apps/web/dist/third-party-licenses.json` with a license and a notice,
and the
workflow is green. The delta is held by the `mermaid-diagrams` inventory
entry
plus a `third-party-licenses-config` path policy, and the reason it
escaped
`verify.mjs` — which has no build step at all — is now
`docs/fork/gaps.md`, _Nothing builds the web app before a merge is
pushed_.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Cloudflare Turnstile challenge loops indefinitely in the built-in browser preview

3 participants