Skip to content

fix(server): explain fake-IP DNS failures in HTML previews - #30318

Merged
maria-rcks merged 4 commits into
pingdotgg:mainfrom
shivamhwp:issue-watch/30236
Nov 6, 2026
Merged

maria-rcks merged 4 commits into
pingdotgg:mainfrom
shivamhwp:issue-watch/30236

Conversation

@shivamhwp

@shivamhwp shivamhwp commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Refs #30236.

When Clash/Mihomo fake-IP DNS resolves a public CDN hostname to 198.18.0.0/15, HTML previews return only Chromium's generic SOCKS connection error. Add up to three capture-local warnings naming the affected hostname and address, explaining the possible DNS cause, and suggesting inline resources, fake-ip-filter, or redir-host. Each hostname gets its own bounded warning so even a maximum-length hostname retains the explanation and remedies. The user guide explains that DNS settings apply on the machine running the environment.

This implements the report's diagnostic fallback. Synthetic addresses remain blocked, including mixed public/fake DNS answers. Private-network protection and checked-address connection pinning remain intact.

Verification at final head

Candidate 2582ba9a8197e5571b5323202a7378b041fdd41e, incorporating main through 4a23e9e1bf126e858037060996f5278e2ecddaa9. The merge preserves main's Unicode-safe console clipping. The PR changes four files.

  • vp run check:changed passed format, lint, both Knip checks, GraphQL validation, affected-package typechecks and focused tests.
  • HtmlRender.test.ts and publicProxy.test.ts passed all 16 tests with real Chrome and no skips, including Unicode clipping and private-network/file isolation.
  • Two independent Codex review rounds covered the implementation and corrections. A separate review covered the merge resolution. Both CodeRabbit findings are resolved; Macroscope approved this head.
  • CI output at this head.

Exact-head command and result output

The attachments render saved output as text; complete transcripts also appear below. All three identify head 2582ba9a8197e5571b5323202a7378b041fdd41e, the environment, command and exit code.

  • 30 packaged inline/TUN assertions, original shiv stdout. Retained from completed run r_vy7l2bp6v81srw00; the verifier checks the actual clean source commit and packaged identity against the full SHA before its behavior assertions.
  • 16-test real-Chrome run, captured on corex. Reran on 2026-11-05 with Chrome headless shell 156.0.8078.47, Node 26.12.1, and a clean worktree at this exact head. All 16 tests passed, no skips, exit 0.
  • Changed-file checks and full original output. Revalidated on 2026-11-05 using vp run check:changed 4a23e9e1bf126e858037060996f5278e2ecddaa9. The content cache confirmed the same four files match the prior passing run. The transcript includes that result and the complete original uncached stdout. Exit 0.
30 focused assertions command and output
Retained command and stdout from shiv run r_vy7l2bp6v81srw00, 2026-11-05.
This is the completed device run, not a rerun after its temporary app was removed.
Source commit: 2582ba9a8197e5571b5323202a7378b041fdd41e
Environment: physical shiv Mac mini; macOS 27.0.1 build 26A434 arm64
Build: unsigned packaged T3 Code (Beta).app 0.1.6; app.isPackaged=true
app.asar SHA-256: 727c6bf629e39a586eea84e45ff79855693c6c1882a56befba6d5953947c73e2
Command: python3 /tmp/t3code-30236-inline/assert-results.py
Exit code: 0
Verifier SHA-256: ab6ed44eb5fbc9cc0538a18741eb859b7ecd0a459051571ba024aa3ed9dc57d9
Verifier source ties the run to this head and checks the real checkout/package:
r=pathlib.Path('/tmp/t3code-30236-inline');head='2582ba9a8197e5571b5323202a7378b041fdd41e';checks=[]
check('exact source commit and clean tracked checkout',subprocess.check_output(['git','-C',str(r/'repo'),'rev-parse','HEAD'],text=True).strip()==head and not subprocess.check_output(['git','-C',str(r/'repo'),'status','--porcelain','--untracked-files=no'],text=True).strip())
 ident=j['identity'];check(label+' genuine package identity',ident['commit']==head and ident['isPackaged'] is True and ident['package']['t3codeCommitHash']==head[:12] and ident['versions']['electron']=='44.10.0' and ident['versions']['node']=='24.22.1')

Original stdout, unchanged:
PASS exact source commit and clean tracked checkout
PASS control genuine package identity
PASS control live app.asar hash
PASS control real native DNS before/after stays fake
PASS control actual MCP has no protocol/tool error
PASS control unmodified MCP text agrees with structured result
PASS control saved image equals actual returned image
PASS control image and dimensions agree
PASS inline genuine package identity
PASS inline live app.asar hash
PASS inline real native DNS before/after stays fake
PASS inline actual MCP has no protocol/tool error
PASS inline unmodified MCP text agrees with structured result
PASS inline saved image equals actual returned image
PASS inline image and dimensions agree
PASS same desktop package, backend and probe used
PASS external control uses original literal request
PASS external control fails and returns complete warning
PASS actual fetched dependency origin, bytes and hash
PASS inline payload round-trips every original dependency byte
PASS exact inline HTML fits genuine packaged tool cap
PASS inline page has no external script src and safely packs script boundaries
PASS actual library integrity, initialize call and no resource requests returned
PASS inline result has no stale fake-IP warning or SOCKS error
PASS same actual fake-IP config and active TUN before/after
PASS same real Mihomo PID and DNS listeners
PASS real TUN native fetch succeeded and packet proof exists
PASS fresh render browser processes and profiles
PASS inline TUN trace has zero packets and zero drops
PASS normal unmodified pinned render browser
ALL 30 FOCUSED ASSERTIONS PASSED.
16 real-Chrome tests command and output
Captured 2026-11-05T01:06:19.739654+00:00
Environment: corex Linux x86_64; v26.12.1
Source commit before: 2582ba9a8197e5571b5323202a7378b041fdd41e
Tracked and untracked working tree before: clean
Browser for focused Chrome run: Google Chrome for Testing 156.0.8078.47
Command: T3CODE_TEST_HEADLESS_SHELL=/home/shivam/.cache/graft/toolchains/chrome-headless-shell-156.0.8078.47/chrome-headless-shell-linux64/chrome-headless-shell TMPDIR=/tmp/t3code-30236 vp test run apps/server/src/htmlRender/HtmlRender.test.ts apps/server/src/htmlRender/publicProxy.test.ts
note: You are running `vp test` as a Vite+ built-in command. If you meant to run the test npm script, use `vpr test` instead.

 RUN  v5.0.5 /home/shivam/Developer/.state/issue-watch/worktrees/30236


 Test Files  2 passed (2)
      Tests  16 passed (16)
   Start at  01:06:28
   Duration  25.57s (tests 56%, transform 31%, setup 7%, import 5%)

Exit code: 0
Source commit after: 2582ba9a8197e5571b5323202a7378b041fdd41e
Changed-file checks command and output
Captured 2026-11-05T01:06:12.819864+00:00
Environment: corex Linux x86_64; v26.12.1
Source commit before: 2582ba9a8197e5571b5323202a7378b041fdd41e
Tracked and untracked working tree before: clean
Browser for focused Chrome run: Google Chrome for Testing 156.0.8078.47
Command: vp run check:changed 4a23e9e1bf126e858037060996f5278e2ecddaa9
$ node scripts/check-changed.ts 4a23e9e1bf126e858037060996f5278e2ecddaa9 ⊘ cache disabled
check:changed: 4 files since 4a23e9e1bf12 (4a23e9e1bf126e858037060996f5278e2ecddaa9)
Nothing changed since the last passing run.

check:changed summary
  pass  format  0.3s
  pass  lint  0.7s
  pass  knip 1/2  8.4s
  pass  knip 2/2  18.4s
  pass  graphql (apps/server)  0.8s
  pass  typecheck (3 packages)  18.9s
  pass  test (2 files)  17.4s
  CI also runs: full test suites, build
  unused patch check skipped: no dependency files changed

Exit code: 0
Source commit after: 2582ba9a8197e5571b5323202a7378b041fdd41e

Original uncached successful stdout retained with this cached validation:
$ node scripts/check-changed.ts ⊘ cache disabled
check:changed: 4 files since 4a23e9e1bf12 (origin/main)

> vp format  pass  0.3s
Checking formatting...

All matched files use the correct format.
Finished in 177ms on 4 files using 16 threads.

> vp lint  pass  0.7s

> vp knip 1/2  pass  8.4s

> vp knip 2/2  pass  18.4s

> vp graphql (apps/server)  pass  0.8s
~/apps/server$ graphqlgen --check ⊘ cache disabled

> vp typecheck (3 packages)  pass  18.9s
~/scripts$ tsc --noEmit ○ cache miss: 'packages/contracts/src/settings.ts' modified, executing

~/evals$ tsc --noEmit ○ cache miss: 'packages/provider-core/node_modules/@t3tools/shared/src/semver.ts' modified, executing

~/apps/server$ tsc --noEmit ○ cache miss: 'packages/provider-cursor/node_modules/@t3tools/provider-core/src/server/subagentProjection.ts' modified, executing

---
vp run: 0/3 cache hit (0%), 3/3 successful. @t3tools/scripts#typecheck not cached because it modified its inputs. (Run `vp run --last-details` for full details)

> vp test (2 files)  pass  17.4s

 RUN  v5.0.5 /home/shivam/Developer/.state/issue-watch/worktrees/30236


 Test Files  2 passed (2)
      Tests  5 passed (5)
   Start at  23:52:06
   Duration  13.46s (transform 64%, import 18%, setup 16%, tests 1%)

check:changed summary
  pass  format  0.3s
  pass  lint  0.7s
  pass  knip 1/2  8.4s
  pass  knip 2/2  18.4s
  pass  graphql (apps/server)  0.8s
  pass  typecheck (3 packages)  18.9s
  pass  test (2 files)  17.4s
  CI also runs: full test suites, build
  unused patch check skipped: no dependency files changed

Packaged desktop, real Mihomo TUN and both workarounds

Recorded on physical shiv on 2026-11-04, macOS 27.0.1 / 26A434 arm64, run r_0hunblvijey3q000. Both unsigned T3 Code (Beta).app builds used the repository's dist:desktop:artifact --platform mac --target dir --arch arm64 workflow. Runtime inspection confirmed app.isPackaged=true, genuine app.asar paths and embedded commits.

Build Full source commit app.asar SHA-256
Main baseline dd69b316656119b4613b13f3c076f45d4dbda2ce 86a1303d11ec5f97e8c7a7bb2e04d8a5715625042efb97c962bfc61fa53a5023
Final PR head 2582ba9a8197e5571b5323202a7378b041fdd41e 7dbed9060a0afe937ec5cd5197610ee0476201cb86571b2949c5aa95977c885a

Both report version 0.1.6, embedded Node 24.22.1 and UI Chromium 152.0.7977.169. Main uses Electron 44.10.1 and candidate uses 44.10.0, as selected by their revisions. Both HTML renderers used Chrome headless shell 156.0.8078.80.

Mihomo Meta v1.19.33 ran with TUN enabled, gVisor and a real UP/RUNNING utun99. Only 198.18.0.0/16 was routed through it. A temporary macOS scoped resolver sent cdn.jsdelivr.net queries to Mihomo's TCP/UDP DNS listener at 127.0.0.1:15353. Runtime API, interface, route, native DNS and packet evidence confirm the setup. Native curl reached the same CDN URL through 198.18.0.4:443 with HTTP 200, and tcpdump observed that traffic on the TUN. Global networking and existing VPN configuration were preserved.

Every case sent the identical issue HTML, including https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js, to the packaged server's actual HTTP MCP html_preview. A free task-local ACP probe received the session-provided connection and displayed the genuine returned image and consoleMessages in the native thread. No DNS stub, replay, source-function call or classifier patch was used. This exercises HTTP MCP and agent-message display; it does not exercise a paid model, the stdio bridge or native tool-result presentation.

Case Condition, with TUN active Actual result
A, main fake-IP, no exclusion; OS DNS 198.18.0.4 Generic SOCKS error and external-script-failed; no warning.
B, final head Same runtime and fake-IP condition Same refusal plus the complete hostname/address/cause/remedies warning.
C, same final package fake-IP with only the CDN hostname in fake-ip-filter Public CDN DNS, control hostname still fake. Image says Script loaded; sole console message is external-script-loaded.
D, same final package Separate clean redir-host runtime, empty filter CDN and control DNS public. Image says Script loaded; sole console message is external-script-loaded.

Main and final head with fake-IP DNS and TUN enabled. Candidate starts at about 1:11. Each segment shows the native request, build/DNS identity and returned diagnostics.

before-after.mp4

Exact additional warning returned at final head:

DNS returned blocked 198.18.0.0/15 addresses, which may come from Clash or Mihomo fake-IP DNS. Inline the resource, add its host to fake-ip-filter, or switch DNS to redir-host. Affected host: cdn.jsdelivr.net (198.18.0.4)

Case C, CDN-only fake-ip-filter, with successful script loading and returned console messages:

C-filter.mp4

Case D, independent redir-host runtime with an empty filter, with successful loading and returned console messages:

D-redir.mp4

C and D used fresh render-browser processes. Packet captures observed new CDN TLS connections. Public requests followed the normal network path while Mihomo TUN stayed enabled.

The evidence assertions checked source/package identity, live bundle hashes, identical requests, agreement between unmodified MCP text and structured responses, returned image bytes, native DNS, actual TUN state, independent workaround configurations and fresh browser processes. The command exited 0:

PASS A-main commit dd69b316656119b4613b13f3c076f45d4dbda2ce
PASS B-head commit 2582ba9a8197e5571b5323202a7378b041fdd41e
PASS C-filter commit 2582ba9a8197e5571b5323202a7378b041fdd41e
PASS D-redir commit 2582ba9a8197e5571b5323202a7378b041fdd41e
ALL FOUR CASES PASSED.

The recordings are contiguous cuts of native window captures, with no overlays, speed changes or generated frames. Their decoded frames were inspected directly. All tracked task processes exited; the owned resolver, route and TUN were removed; original DNS/proxy/interface state and all 2,438 original profile file hashes were restored. Temporary builds and browser profiles were removed.

Inline dependency with fake-IP DNS and TUN unchanged

A focused follow-up on physical shiv on 2026-11-05, run r_vy7l2bp6v81srw00, rebuilt the same exact head 2582ba9a8197e5571b5323202a7378b041fdd41e as an unsigned packaged 0.1.6 app. Runtime identity confirmed app.isPackaged=true; this build's app.asar SHA-256 is 727c6bf629e39a586eea84e45ff79855693c6c1882a56befba6d5953947c73e2. OS, Electron, embedded Node and render-browser versions match the candidate above.

The original external CDN control still failed with the complete diagnostic. In the same Mihomo runtime, fake-IP mode and TUN stayed enabled, fake-ip-filter stayed empty, and native DNS remained 198.18.0.4 before and after the inline request. Native curl fetched the actual Mermaid 11.17.2 bundle through the synthetic IP and active TUN, with HTTP 200 and matching TUN packets.

The complete dependency is 3,572,661 bytes, SHA-256 581ed7d74bd9048d0e3a91363927d72ef22942d7722546b27f7cc29e35390eb8. It exceeds MCP's 512,000-character HTML cap as a plain inline script. This test therefore used lossless gzip plus Unicode packing, fitting the complete bundle into a 492,366-character self-contained HTML document. The page decompresses the original bytes, verifies their length and SHA-256 with Web Crypto, executes the actual script and calls mermaid.initialize({startOnLoad:false}). It has no external script source or substitute library.

The returned image says Inline Mermaid initialized successfully. Returned consoleMessages are exactly:

[
  {"level":"log","text":"inline-dependency-integrity: 3572661 bytes; SHA-256 581ed7d74bd9048d0e3a91363927d72ef22942d7722546b27f7cc29e35390eb8"},
  {"level":"log","text":"mermaid.initialize type: function"},
  {"level":"log","text":"inline-dependency-success: actual Mermaid initialized with startOnLoad=false"},
  {"level":"log","text":"inline-resource-requests: []"}
]

Native recording of the final inline request submission and response, including setup attempts. This uses the same real packaged HTTP MCP and ACP message presentation described above:

inline-request.mp4

Short native review of the actual control and inline responses, showing complete returned image/console output and native DNS. This reviews already returned messages:

inline-result-review.mp4

Decoded frame from that recording, showing the successful inline result and unchanged fake-IP DNS:

Actual returned inline image and console messages

All 30 focused assertions passed with exit 0. They checked source/package identity, dependency byte-for-byte round-trip and browser integrity verification, actual MCP text/structured/image agreement, unchanged fake-IP/TUN state, fresh render-browser processes and profiles, successful initialization and no stale warning. The inline page recorded no resource requests; its scoped TUN trace had zero packets and zero drops. A broader process-filtered trace had drops and is not used as exhaustive evidence. All 34 captured task PIDs, including ACP probes, exited; 2,625 original profile hashes matched after restoration; task DNS/proxy changes, resolver, route, TUN, build and browser scratch were removed. Natural system AWDL address rotation was left intact.

Not shown in these native runs: full-device or public IPv6 TUN routing, other clients/providers, the stdio bridge and native tool-result presentation. The inline case verifies full-bundle integrity and initialization, not Mermaid diagram rendering or lazy-loaded modules. A plain uncompressed full-bundle inline request exceeds the tool input cap. Earlier source-engine runtime captures also verified capture isolation and complete warnings for three 253-character hostnames. Maria's independent real-model Linux web verification supplements the native HTTP MCP evidence.

Implemented with Claude Opus 5.5 through Claude Code; investigated, verified and reviewed with GPT-6.1 Sol through Codex in T3 Code.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Nov 3, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Nov 3, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 2582ba9

Macroscope's review found this PR approvable — HTML previews now explain blocked fake-IP DNS results and suggest remediation. Existing network restrictions remain unchanged, and diagnostics are bounded and isolated to each capture.

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

@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Walkthrough

The proxy tracks hostnames that resolve only to fake-IP addresses. Screenshot results include clipped console messages and warnings for recorded hosts. Documentation describes the address restrictions and possible workarounds.

Changes: Fake-IP preview diagnostics

Layer / File(s) Summary
Track fake-IP hostnames
apps/server/src/htmlRender/publicProxy.ts, apps/server/src/htmlRender/publicProxy.test.ts
The proxy records up to three hostnames that resolve only to the 198.18.0.0/15 range. Its result includes the listening port and recorded hostnames. Tests check that mixed public and fake-IP results are not recorded.
Add fake-IP warnings to screenshot results
apps/server/src/htmlRender/headlessChrome.ts, docs/user/html-renders.md
Browser startup uses the proxy result object. Screenshot results include clipped page console messages and warnings for recorded fake-IP hosts. The documentation describes the restriction and listed workarounds.

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

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant publicProxy
  participant launchBrowser
  participant captureHtmlScreenshot
  publicProxy-->>launchBrowser: return port and fakeIpHosts
  launchBrowser->>launchBrowser: create fake-IP warning messages
  launchBrowser-->>captureHtmlScreenshot: return page console messages and warnings
  captureHtmlScreenshot->>captureHtmlScreenshot: combine console messages and warnings
Loading

Possibly related issues

  • Issue 30236: The changes add diagnostics and workarounds for fake-IP DNS conflicts. The proxy continues to refuse connections to those synthetic addresses.

Suggested reviewers: juliusmarminge, saphid

Merge Risk: Minimal · up to 2582b

The change preserves blocking of unsafe destinations while adding bounded fake-IP diagnostics; no unresolved merge-blocking risk was identified.

Pre-merge checks: Passed 3 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Description check Warning The description is detailed and covers the problem, implementation, scope, and verification. However, it does not use the required section headings and does not provide explicit maintainer approval ev… Reorganize the description under ## Problem, ## Change, ## Scope and approval, and ## Verification. In the scope section, link the triaged issue or approval discussion and include the maintainer approval comment, or explain why this focused…
Passed Passed checks: 3 passed

Check name Status Explanation
Title check Passed The title clearly identifies the server-side fix that explains fake-IP DNS failures in HTML previews.
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.
Full details: Description check

Explanation

The description is detailed and covers the problem, implementation, scope, and verification. However, it does not use the required section headings and does not provide explicit maintainer approval evidence or explain an approval exemption under “Scope and approval.”

Resolution

Reorganize the description under ## Problem, ## Change, ## Scope and approval, and ## Verification. In the scope section, link the triaged issue or approval discussion and include the maintainer approval comment, or explain why this focused bug fix qualifies without prior approval.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 41c67f7 and 2582ba9.

Files selected for processing: 1

  • apps/server/src/htmlRender/headlessChrome.ts

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

@coderabbitai coderabbitai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

  • Fix comments: Fix CodeRabbit comments on this PR

@macroscopeapp
macroscopeapp Bot dismissed their stale review November 3, 2026 19:34

Dismissing prior approval to re-evaluate 41c67f7

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Nov 3, 2026
@maria-rcks

maria-rcks commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

Verified in a real dev environment

Verified unchanged head 41c67f7cca47f313f829cd65c8d9b9faf7fd3f8b against github/main at 7c22e24e3fa1a3bb3a95f27aea000067f198fe7f in separate checkouts, with one dev server running at a time. Installed dependencies with vp i. Used Playwright from the repo dependencies and /usr/bin/google-chrome to create a project pointing at a real Git repository and send real Codex gpt-6.1-sol turns through the web composer. Codex called the dev server's real html_preview MCP tool. No mocks, fixtures, replay provider, DNS function overrides, or proxy patches.

Mihomo v1.19.33 supplied fake-IP DNS on loopback port 15353. A systemd-resolved routing domain scoped it to cdn.jsdelivr.net; the OS and Node lookup returned 198.18.0.4. Both runs used identical HTML loading the Mermaid CDN script. Main returned only ERR_SOCKS_CONNECTION_FAILED and external-script-failed. The PR returned those errors plus the complete warning naming the hostname/address, possible DNS cause, and inline / fake-ip-filter / redir-host remedies. The resource stayed blocked; both returned screenshot PNGs were byte-identical.

Neighboring behavior passed through the same web/composer/provider/MCP path:

  • A later inline script executed and returned only inline-script-loaded, with no stale warning.
  • After restoring public DNS, the identical CDN page displayed external script loaded and returned an empty consoleMessages array.

Blacksmith checks passed: publicProxy.test.ts (4 tests) and HtmlRender.test.ts with real Chrome headless shell (11 tests). The existing CI reports 32 successful checks. No code changes or pushes were needed.

Linux runtime: Node 24.22.1, UI Chrome 151.0.7922.108, T3-managed capture Chrome 156.0.8078.80 with its sandbox enabled. Both dev servers used DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/pr30318-no-session-bus to avoid this VM's desktop keyring startup wait; without that environment setting, main's inline and external previews both timed out. No keyring configuration was changed. Scoped DNS configuration was restored after verification.

Runtime transcript

Main: generic SOCKS errors without the fake-IP diagnostic

PR: complete fake-IP warning returned through the real Codex turn

Public-DNS control: the identical page loads its external script

Not verified

Native desktop, iOS and Android clients; macOS/Windows; remote/relay/tunnel connections; other providers; Mihomo TUN routing; applying the specific fake-ip-filter or redir-host settings; maximum-length hostname diagnostics. Verification covers the shared server behavior through the Linux web client and real Codex path.

@macroscopeapp
macroscopeapp Bot dismissed their stale review November 3, 2026 23:53

Dismissing prior approval to re-evaluate 2582ba9

@maria-rcks
maria-rcks merged commit b1f1731 into pingdotgg:main Nov 6, 2026
37 checks passed
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Nov 6, 2026
**v0.1.8-nightly.20261106.4262** · 129 changes from 44 contributors

- **Pull request composer suggestions.** Find users, issues, and pull requests as you type mentions and references in review composers.
- **Review comments in chat.** Add pull request comments to chat without framing them as fixes.
- **GitLab change requests.** Request changes on GitLab merge requests and see change requests submitted on GitLab.
- **GitLab pipeline jobs.** See individual pipeline jobs in the checks panel to identify failures without opening GitLab.
- **Desktop window tiling.** Shrink the desktop window to fit half-screen and quarter-screen tiles.
- **Stop project actions on settle.** Choose to stop project actions and their child processes automatically when a thread settles.
- **Preserved composer context.** Adding multiple findings or diff selections to the composer no longer drops earlier draft content.

### Plus 112 more bug fixes and performance improvements.

<details>
<summary>Full changelog</summary>

## What's Changed
* fix(gitlab): merge requests can delete their source branch by @TonybynMp4 in pingdotgg/t3code#30453
* fix(gitlab): comments link to their note on GitLab by @TonybynMp4 in pingdotgg/t3code#30411
* fix(mobile): iOS terminal accepts Chinese, Japanese and Korean input by @juliusmarminge in pingdotgg/t3code#30546
* fix(mobile): Android app no longer stays offline after reopening by @kahlstrm in pingdotgg/t3code#28625
* fix(mobile): show one Android notification per thread completion by @shivamhwp in pingdotgg/t3code#27699
* fix(mobile): stop Android composer flicker at the wrap boundary by @shivamhwp in pingdotgg/t3code#27682
* fix(mobile): Android dictation works with regional preferences set by @EhsanulHaqueSiam in pingdotgg/t3code#31030
* fix(mobile): iOS compose button no longer grows while a tab is pressed by @Jerematix in pingdotgg/t3code#28955
* fix(mobile): Android terminal Backspace deletes on the first press by @only21mil in pingdotgg/t3code#24983
* fix(mobile): Android secret requests no longer offer password manager logins by @voida6 in pingdotgg/t3code#29825
* fix(mobile): iOS composer text no longer turns invisible mid-draft by @wojas in pingdotgg/t3code#30135
* fix(mobile): iOS 26 scroll edge effect no longer hides composer text by @wojas in pingdotgg/t3code#30138
* fix(mobile): typing after in-app dictation reaches the draft again on iOS by @wojas in pingdotgg/t3code#30139
* perf(mobile): skip obsolete queued iOS diff row decodes by @saphid in pingdotgg/t3code#25287
* fix(gitlab): the checks and review list filters work by @TonybynMp4 in pingdotgg/t3code#30433
* fix(mobile): keep Android tablet cold launches in landscape by @Dwite in pingdotgg/t3code#28825
* fix(pr): GitCafe attachments render in pull request bodies by @juliusmarminge in pingdotgg/t3code#31741
* fix(gitlab): unresolved overview threads count as review findings by @TonybynMp4 in pingdotgg/t3code#30397
* fix(mobile): Android alerts and the live card show the same status bar icon by @juliusmarminge in pingdotgg/t3code#29738
* fix(mobile): keyboard state follows Android's nonanimated IME show by @juliusmarminge in pingdotgg/t3code#25847
* fix(mobile): Android composer no longer accepts autofill by @juliusmarminge in pingdotgg/t3code#27489
* perf(mobile): skip obsolete queued full token decodes by @saphid in pingdotgg/t3code#25320
* fix(gitlab): threads on changed code show as outdated by @TonybynMp4 in pingdotgg/t3code#30423
* fix(gitlab): the checks panel lists each pipeline job by @TonybynMp4 in pingdotgg/t3code#28728
* perf(mobile): avoid code row scans while dragging file paths by @saphid in pingdotgg/t3code#25484
* fix(chat): show one usage-limit recovery notice by @shivamhwp in pingdotgg/t3code#29292
* fix(web): adding to the composer no longer drops earlier findings and selections by @TonybynMp4 in pingdotgg/t3code#24990
* feat(pull-requests): PR composers complete @user mentions by @TonybynMp4 in pingdotgg/t3code#30747
* feat(web): add pull request comments to the chat by @TonybynMp4 in pingdotgg/t3code#30579
* feat(gitlab): link issue, merge request, commit and user references by @TonybynMp4 in pingdotgg/t3code#30524
* fix(mobile): sending on iOS no longer leaves an autocorrected draft behind by @saphid in pingdotgg/t3code#26452
* feat(gitlab): reviews can request changes by @TonybynMp4 in pingdotgg/t3code#30549
* feat(pull-requests): PR composers complete #123 and GitLab !123 references by @TonybynMp4 in pingdotgg/t3code#30857
* feat(gitlab): merge requests from forks can toggle maintainer edits by @TonybynMp4 in pingdotgg/t3code#30518
* fix(prs): reviewer menu searches past the first page and keeps GitLab's requested reviewers by @TonybynMp4 in pingdotgg/t3code#22489
* fix(ui): snooze menu times match the menu's typography by @ishaanko in pingdotgg/t3code#30596
* feat(web): a Labs setting hides tool calls so threads read like a chat by @flamboh in pingdotgg/t3code#30000
* feat(scheduled-tasks): tasks link to their thread by @t3dotgg in pingdotgg/t3code#31764
* fix(shared): recognize numeric bare-repository config by @macodev00 in pingdotgg/t3code#27500
* fix(server): a command id reused for two threads at once no longer succeeds for both by @saphid in pingdotgg/t3code#18385
* fix(server): coalesce tool output before it fills the live buffer by @snarkyalyx in pingdotgg/t3code#16317
* perf(server): Windows git reads no longer start a console host by @AkiVonAkira in pingdotgg/t3code#19288
* fix(server): a publish whose first push fails still shows the new remote by @saphid in pingdotgg/t3code#29688
* fix(server): reverting files removes what a new .gitignore from the turn was hiding by @saphid in pingdotgg/t3code#29795
* fix(server): Codex titles no longer fail on ChatGPT accounts without gpt-6-luna by @Muzammil-Bit in pingdotgg/t3code#30078
* fix(desktop): quit no longer orphans a backend that is slow to stop by @saphid in pingdotgg/t3code#22572
* perf(server): GitHub activity reads skip PR-wide fields on later review-thread pages (8.9 s → 6.8 s median) by @Yuruzuu in pingdotgg/t3code#30294
* perf(server): the headless browser closes after five idle minutes (517 MiB → 1.6 MiB median) by @Yuruzuu in pingdotgg/t3code#30306
* fix(provider-acp-registry): surface agent error message on sign-in failure by @iScabrous in pingdotgg/t3code#30295
* perf(server): a slow host no longer delays other watched PRs' wakes (935 ms → 65 ms median) by @Yuruzuu in pingdotgg/t3code#30291
* perf(server): PR cache invalidation no longer waits on other projects' reads (1,163 ms → 0.12 ms median) by @Yuruzuu in pingdotgg/t3code#30293
* fix(opencode): tools stopped mid-run show as interrupted, not failed by @saphid in pingdotgg/t3code#29762
* fix(client-runtime): pull request bodies with CRLF line endings keep their code blocks whole by @MarcoDotIO in pingdotgg/t3code#30352
* fix(shared): long assistant quote chips no longer end in a broken character by @spoukyii in pingdotgg/t3code#30367
* fix(cli): t3 connect unlink no longer warns about a server that is gone by @MarcoDotIO in pingdotgg/t3code#30324
* fix(server): ACP agents get T3CODE_THREAD_ID like Claude and Codex sessions by @frankhommers in pingdotgg/t3code#30361
* fix(server): accept a case-insensitive DPoP authorization scheme by @spoukyii in pingdotgg/t3code#30337
* fix(server): usage-limit auto-resume no longer arms subagents of archived or deleted parents by @spoukyii in pingdotgg/t3code#30363
* fix(provider-core): background work notices no longer end in a broken character by @spoukyii in pingdotgg/t3code#30369
* fix(client-runtime): subagent previews no longer end in a broken character by @spoukyii in pingdotgg/t3code#30391
* fix(server): explain fake-IP DNS failures in HTML previews by @shivamhwp in pingdotgg/t3code#30318
* perf(resource-monitor): Linux terminal process checks use a third of the CPU by @jaikhuranna in pingdotgg/t3code#30381
* fix(server): failed Claude text generation shows Claude's error instead of raw JSON by @MarcoDotIO in pingdotgg/t3code#30331
* fix(server): pull request tools point a bare thread uuid at its mcp: thread by @spoukyii in pingdotgg/t3code#30375
* fix(server): message search keeps results when a short non-Latin word differs in case by @MarcoDotIO in pingdotgg/t3code#30332
* fix(web): preview annotation chip labels no longer end in a broken character by @spoukyii in pingdotgg/t3code#30345
* fix(server): thread titles no longer fail when the text generation provider can't run by @medric-z in pingdotgg/t3code#29607
* fix(web): refresh resource timeline while diagnostics is open by @shawk08033 in pingdotgg/t3code#30528
* fix(usage): a CLIProxy hub saved as its management.html panel URL shows accounts again by @Jolymmiles in pingdotgg/t3code#25579
* fix(shared): command output keeps text after an unterminated OSC by @spoukyii in pingdotgg/t3code#30479
* fix(cli): t3 up's retry and restart hints keep --base-dir by @spoukyii in pingdotgg/t3code#30480
* fix(server): a branch tracking another local branch no longer shows that branch's PR by @MarcoDotIO in pingdotgg/t3code#30563
* fix(web): terminal links keep route and pnpm paths in one piece by @tiliakoos in pingdotgg/t3code#30603
* fix(shared): CSV and TSV attachments keep their table under generic file types by @tiliakoos in pingdotgg/t3code#30601
* fix(server): report Claude settings compaction threshold by @voltcrash in pingdotgg/t3code#29220
* fix(cli): t3 project remove finds a deleted project by a relative or trailing-slash path by @MarcoDotIO in pingdotgg/t3code#30562
* fix(server): an invalid regex in project search still finds its text when Match case is off by @MarcoDotIO in pingdotgg/t3code#30569
* fix(server): agents see why a project update was refused instead of a generic failure by @MarcoDotIO in pingdotgg/t3code#30564
* perf(client-runtime): stop tracing streamed thread batches by @ElliotDrel in pingdotgg/t3code#30679
* fix(server): rewound Codex threads import their history from before the rewind by @MarcoDotIO in pingdotgg/t3code#30652
* fix(server): keep writes moving with a larger WAL limit by @Yash-Singh1 in pingdotgg/t3code#31804
* fix(opencode): edits that delete text keep their empty replacement by @Jo2234 in pingdotgg/t3code#30643
* fix(forgejo): read author assignees once by @Jo2234 in pingdotgg/t3code#30686
* fix(cli): t3 pair's no-running-server hint keeps --base-dir by @saphid in pingdotgg/t3code#30689
* perf(server): stop tracing routine port polling helpers by @ElliotDrel in pingdotgg/t3code#30678
* fix(server): ACP MCP bridge no longer splits messages on U+2028/U+2029 by @geezoria in pingdotgg/t3code#30719
* fix(cli): expand home-relative thread project paths by @Jo2234 in pingdotgg/t3code#30721
* perf(ci): boot the built web client in Build and Typecheck, not Test Web (about 22 s off the longest job) by @Pyseph in pingdotgg/t3code#30752
* fix(shared): ignore unfinished quoted Git config continuations by @imharjot in pingdotgg/t3code#30743
* fix(review-guide): preserve excerpt line terminators by @Jo2234 in pingdotgg/t3code#30717
* feat(pi): show extension status in existing controls by @StiensWout in pingdotgg/t3code#23901
* fix(fx): preserve literal unicode escape text in clipped replies by @Jo2234 in pingdotgg/t3code#30701
* perf(dev): knip:check runs its two passes side by side (34 s → 26 s median on 4 CPUs) by @Pyseph in pingdotgg/t3code#30737
* fix(shared): command output no longer prints the final byte of escape sequences with intermediates by @geezoria in pingdotgg/t3code#30724
* fix(web): restore folder breadcrumb trails when reopening tabs by @Jo2234 in pingdotgg/t3code#30706
* fix(client-runtime): sanitized error stacks keep line and column for URLs with a query by @geezoria in pingdotgg/t3code#30726
* fix(shared): shortened agent paths like /tmp/... no longer become broken file chips by @saphid in pingdotgg/t3code#30762
* fix(server): MCP auth spans no longer include the tool call by @navidnadali in pingdotgg/t3code#30834
* fix(server): preview browser picks up Chrome 157 security fixes by @snnbotchway in pingdotgg/t3code#30820
* fix(server): agents read RTF paragraphs that end with a backslash by @geezoria in pingdotgg/t3code#30848
* fix(server): a late checkpoint keeps the stopped run's baselines by @navidnadali in pingdotgg/t3code#30830
* fix(shared): preserve IPv6 hosts when switching clone protocols by @Lucenx9 in pingdotgg/t3code#30798
* docs: explain Linux desktop installation by @voltcrash in pingdotgg/t3code#30819
* perf(server): each live event is projected once for all subscribers by @navidnadali in pingdotgg/t3code#30860
* fix(server): request_secret asks for one value per card by @rgrvlsk in pingdotgg/t3code#30805
* fix(ssh): host discovery skips hidden Include matches by @Lucenx9 in pingdotgg/t3code#30910
* docs: clarify diagnostic exports and their separate controls by @Mr-Neutr0n in pingdotgg/t3code#30942
* docs: fix worktree cleanup path in FAQ by @jacobcorbett in pingdotgg/t3code#31000
* fix(server): a policy that manages observability endpoints is refused instead of ignored by @MarcoDotIO in pingdotgg/t3code#30973
* fix(client-runtime): untitled subagent titles no longer end in a broken character by @spoukyii in pingdotgg/t3code#30390
* fix(shared): underline styles and colours no longer scramble command output colours by @MarcoDotIO in pingdotgg/t3code#21542
* perf(server): batch queued provider writes without waiting by @Yash-Singh1 in pingdotgg/t3code#31656
* fix(server): prepare restart continuations faster on shutdown by @Yash-Singh1 in pingdotgg/t3code#31807
* fix(web): keep change totals aligned beside the label by @Yash-Singh1 in pingdotgg/t3code#31814
* fix(web): rank usage provider summaries by the selected metric by @dharmeshgurnani in pingdotgg/t3code#15632
* fix(server): wait for automatic follow-ups before settling threads by @Yash-Singh1 in pingdotgg/t3code#31815
* fix(web): settings descriptions use the full row and stay two lines by @flamboh in pingdotgg/t3code#31826
* fix(voice): insert Unicode word boundaries for dictation by @juliusmarminge in pingdotgg/t3code#31799
* fix(mobile): use preferred languages for on-device iPhone dictation by @juliusmarminge in pingdotgg/t3code#31800
* fix(mobile): keep the opening words of local iPhone dictation by @juliusmarminge in pingdotgg/t3code#31801
* fix(server): keep PR generation focused on the change by @Yash-Singh1 in pingdotgg/t3code#31819
* chore(desktop): trace shutdown phases by @Yash-Singh1 in pingdotgg/t3code#31850
* perf(server): batch shutdown recovery commits by @Yash-Singh1 in pingdotgg/t3code#31854
* perf(server): batch projection recovery reads into one query by @Yash-Singh1 in pingdotgg/t3code#31842
* fix(desktop): let the window shrink to 400x360 so it fits half-screen tiles by @shivamhwp in pingdotgg/t3code#28223
* fix(web): improve Changes row text and spacing by @shivamhwp in pingdotgg/t3code#31858
* feat(server): stop opted-in project actions when threads settle by @Yash-Singh1 in pingdotgg/t3code#31857
* fix(build): skip Koffi source builds during cross-packaging by @Yash-Singh1 in pingdotgg/t3code#31864
* fix(server): Antigravity installs on Intel Macs by @aledog007 in pingdotgg/t3code#30189

## New Contributors
* @kahlstrm made their first contribution in pingdotgg/t3code#28625
* @Jerematix made their first contribution in pingdotgg/t3code#28955
* @snarkyalyx made their first contribution in pingdotgg/t3code#16317
* @Muzammil-Bit made their first contribution in pingdotgg/t3code#30078
* @iScabrous made their first contribution in pingdotgg/t3code#30295
* @frankhommers made their first contribution in pingdotgg/t3code#30361
* @medric-z made their first contribution in pingdotgg/t3code#29607
* @shawk08033 made their first contribution in pingdotgg/t3code#30528
* @Jolymmiles made their first contribution in pingdotgg/t3code#25579
* @geezoria made their first contribution in pingdotgg/t3code#30719
* @navidnadali made their first contribution in pingdotgg/t3code#30834
* @Mr-Neutr0n made their first contribution in pingdotgg/t3code#30942
* @jacobcorbett made their first contribution in pingdotgg/t3code#31000
* @dharmeshgurnani made their first contribution in pingdotgg/t3code#15632
* @aledog007 made their first contribution in pingdotgg/t3code#30189

**Full Changelog**: pingdotgg/t3code@v0.1.8-nightly.20261106.4247...v0.1.8-nightly.20261106.4262

</details>


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

Labels

size:M 30-99 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.

2 participants