Skip to content

feat(dev): Make t3 code dev instances shareable over Tailscale - #4556

Merged
t3dotgg merged 24 commits into
mainfrom
agent/dev-server-sharing
Jul 27, 2026
Merged

t3dotgg merged 24 commits into
mainfrom
agent/dev-server-sharing

Conversation

@t3dotgg

@t3dotgg t3dotgg commented Jul 26, 2026 •

Copy link
Copy Markdown
Member

Note

Dev mode overhaul — PR 2 of 3. The stack moves from worktree-isolated dev state → single-origin and Tailscale sharing → pairing and seed utilities. This PR is stacked on #4555, and #4557 is stacked on this PR.

What

  • Make browser development single-origin by proxying backend HTTP, WebSocket, OAuth, and well-known routes through Vite.
  • Add dev:share / --share support that publishes the web port with Tailscale and cleans up the mapping on exit.
  • Make pairing grants and cookies work correctly from the shared HTTPS origin.
  • Centralize dev proxy configuration and cover the runner, sharing, auth, and Tailscale behavior with focused tests.

Why

Remote browsers could load the frontend but then try to connect to their own localhost for backend traffic. Sharing also needed the startup pairing URL, cookie policy, allowed origins, and Tailscale lifecycle to agree on the same public origin.

Impact

This is PR 2 of 3 and is stacked on #4555. Its diff is limited to single-origin browser hosting and Tailscale sharing.

Verification

  • 64 focused tests across the dev runner, sharing helper, auth policy, and Tailscale package
  • targeted lint
  • typechecks for shared, Tailscale, server, and web packages
  • isolated dev-stack startup smoke test

Note

Add --share flag to publish dev instances over Tailscale

  • Adds a --share flag (and dev:share npm script) to the dev runner that publishes the web dev server over HTTPS on the tailnet via tailscale serve, augmenting T3CODE_DEV_ALLOWED_ORIGINS with the tailnet origin so the backend accepts CORS requests from it.
  • Browser dev modes (dev, dev:web) now run in single-origin mode: VITE_HTTP_URL/VITE_WS_URL are cleared and Vite proxies backend path prefixes (/api, /oauth, /.well-known, /ws) so the app resolves the backend from window.location.origin rather than a hardcoded URL, enabling access from non-localhost origins.
  • Tailscale stderr is now classified into safe diagnostic labels (TailscaleStderrDiagnostic) to produce sanitized error messages without leaking secrets or node names; share/unshare failures surface structured DevShareError types with stage-specific messages.
  • Session cookie names are now port-scoped (e.g. t3_session_<port>) in desktop mode and in web dev mode when a devUrl is configured, so multiple instances on different ports do not collide.
  • Startup pairing tokens in dev environments now use a 24-hour TTL instead of the previous short default.
  • Risk: dev and dev:web now reject specific non-loopback --host values with DevRunnerHostNotProxiableError; inheriting a non-loopback HOST env var will also be rejected.

Macroscope summarized 83783d0.


Note

Medium Risk
Touches authentication (cookies, pairing TTL, CORS) and dev networking; mistakes could break local login or leak sensitive Tailscale stderr, though changes are dev-scoped with broad test coverage.

Overview
Browser dev becomes single-origin so the same UI works on localhost, tailnet, or LAN without baking in localhost backend URLs. The dev runner clears VITE_HTTP_URL / VITE_WS_URL, sets T3CODE_SINGLE_ORIGIN_DEV=1, and Vite proxies /api, /oauth, /.well-known, and /ws via a shared DEV_PROXIED_PATH_PREFIXES list; the server 404s those paths in dev instead of redirecting to Vite. Vite allows *.ts.net hosts and only pins HMR when HOST is set (desktop).

--share / dev:share publishes the web port with Tailscale (scripts/lib/dev-share.ts), sets VITE_DEV_SERVER_URL and appends the tailnet origin to T3CODE_DEV_ALLOWED_ORIGINS, and removes the mapping on exit (skipped for dry-run and warned for dev:desktop). Tailscale CLI failures now expose sanitized stderrDiagnostic labels instead of raw stderr.

Auth and cookies align with multi-instance dev: session cookies are t3_session_<port> when devUrl is set or in desktop mode; startup pairing tokens get a 24h TTL in dev via purpose: "startup"; dev CORS includes configured and shared origins.

Dev runner gains worktree-stable port offsets, loopback-focused port probing (avoids fighting tailscale serve), bind-host-aware server probes, rejection of non-proxiable --host for dev/dev:web, and DevRunnerHostNotProxiableError.

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

Summary by CodeRabbit

  • New Features

    • Added shared browser development via dev:share, publishing the web app over HTTPS on a tailnet.
    • Improved single-origin browser development with automatic proxying for backend and WebSocket routes.
    • Added support for configurable development hosts and allowed origins.
    • Startup pairing links now remain valid for up to 24 hours.
  • Bug Fixes

    • Prevented session collisions when running multiple development servers.
    • Improved port selection across worktrees and concurrent environments.
    • Replaced potentially sensitive Tailscale error output with safer diagnostic messages.
  • Documentation

    • Added guidance for shared development, browser proxying, port selection, and server startup output.

@coderabbitai

coderabbitai Bot commented Jul 26, 2026 •

Copy link
Copy Markdown
Contributor
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.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
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 matches the main change: adding Tailscale sharing for dev instances.
Description check ✅ Passed It covers what changed, why, impact, and verification, which satisfies the template's required information.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/dev-server-sharing

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 added size:L 100-499 changed lines (additions + deletions). vouch:trusted Author is trusted by repo permissions or the VOUCHED list. labels Jul 26, 2026
@t3dotgg
t3dotgg marked this pull request as ready for review July 26, 2026 05:21
Comment thread packages/tailscale/src/tailscale.ts Resolved
Comment thread scripts/dev-runner.ts Resolved
Comment thread scripts/dev-runner.ts Resolved
@macroscopeapp

macroscopeapp Bot commented Jul 26, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new Tailscale sharing feature with significant runtime behavior changes including port-scoped session cookies, extended dev token TTLs (5min→24h), new CORS configuration, and Tailscale CLI integration. An unresolved medium-severity comment identifies an issue with orphan process cleanup. Human review recommended for these auth-adjacent and feature-enablement changes.

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

t3dotgg and others added 2 commits July 25, 2026 22:40
A submodule's `.git` is also a file, so the file-vs-directory check alone
classified every submodule as a linked worktree and handed it a
worktree-local `.t3`. Read the `gitdir:` pointer and require it to land in
`.git/worktrees` (compared as path segments, not a substring).

Resolve cwd through a HostProcessWorkingDirectory reference rather than
calling process.cwd() directly, so the precedence chain is testable.

Add tests for the submodule and malformed-`.git`-file cases, plus
end-to-end coverage of all four home-precedence outcomes, which had no
test before. Document that worktree state lands in `.t3/userdata`.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
The `.git/worktrees` segment check rejected worktrees whose common dir is
not named `.git`. A worktree of a bare repo points at
`<repo>.git/worktrees/<name>`, and $GIT_COMMON_DIR can be anything. Git
always uses the `worktrees/<name>` tail, so match on that instead;
`<git-dir>/modules/<name>` still fails it.

A blank `--home-dir` also counted as a selection under `??`, skipping the
worktree default and landing on the shared home — the outcome this
precedence exists to prevent. Trim before choosing.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
@t3dotgg

t3dotgg commented Jul 26, 2026

Copy link
Copy Markdown
Member Author

Took ownership of this PR, reviewed it, and pushed one fix.

Fixed: --share silently half-worked for dev:desktop (edc8e4f0b)

The share block only guarded dev:server, so dev:desktop --share fell through and shared. That's broken in a way the user can't see:

  • Desktop keeps VITE_HTTP_URL/VITE_WS_URL baked to 127.0.0.1 (it's deliberately not single-origin), so a tailnet visitor loads the UI and then watches it dial their own loopback for the backend.
  • Worse, the share block overwrites VITE_DEV_SERVER_URL when --dev-url is unset — and that's the origin Electron loads the renderer from (DesktopApp.ts:176, Option.getOrThrow(environment.devServerUrl)).

Now warns and carries on serving locally, matching the dev:server treatment. Added a test asserting it still spawns the stack.

Verified, not just read

  • Loopback-only port probing is safe. The switch from probing ["127.0.0.1","0.0.0.0","::1","::"] to ["127.0.0.1","::1"] looked like it could hand out an occupied port. Empirically it can't — a wildcard 0.0.0.0 listener still makes a subsequent 127.0.0.1 bind fail EADDRINUSE, so loopback alone is a sufficient test.
  • Single-origin proxying works end to end. Booted the stack and probed: /.well-known/t3/environment through Vite → 200 with a real descriptor; / → 200; /api/foo straight at the backend → 404 (not a redirect loop); /somepage at the backend → 302 to Vite. The DEV_PROXIED_PATH_PREFIXES contract holds on both sides.
  • Port stability holds. I saw ports climb 8579→8580→8581 mid-review and suspected a bug in the worktree-hash offset — it was my own overlapping dev servers. With a clean process table the offset is stable at server=2849,web=2849 across runs.
  • Dropping /attachments from the proxy list is dead-code removal, not a regression. There is no /attachments HTTP route on the server and no client that fetches one; attachmentsDir is filesystem-only, and attachments are served under /api/assets (ASSET_ROUTE_PREFIX), which /api already covers.

Deliberate behavior changes worth flagging for reviewers

Both are correct, but they're the kind of thing that generates a bug report:

  1. Every dev session's cookie is renamed — t3_session → t3_session_<port> in web mode too. Anyone with a live browser session gets logged out once and re-pairs. The reasoning (cookies are host-scoped but not port-scoped, so concurrent servers clobber each other) is sound and the alternative is the far worse "Invalid session token signature" loop.
  2. Startup pairing tokens now live 24h instead of 5m, gated on devUrl !== undefined && purpose === "startup" — so it's dev-only; user-issued links and real servers keep 5 minutes. Correct gating.

typecheck clean (0 errors), lint clean on changed files, 40/40 tests passing in dev-runner.test.ts + dev-share.test.ts.

I'm babysitting this PR and will pick up review comments as they land.

t3dotgg and others added 2 commits July 25, 2026 23:54
Desktop dev is not single-origin: the renderer gets VITE_HTTP_URL and
VITE_WS_URL baked to loopback, so a tailnet visitor would load the UI and
then watch it dial its own 127.0.0.1 for the backend. Sharing also
overwrote VITE_DEV_SERVER_URL, which is the origin Electron loads the
renderer from.

Warn and carry on serving locally instead of handing out a URL that is
broken in a way the user cannot see.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
@t3dotgg
t3dotgg force-pushed the agent/dev-server-sharing branch from edc8e4f to dbad3bc Compare July 26, 2026 06:55
@t3dotgg

t3dotgg commented Jul 26, 2026

Copy link
Copy Markdown
Member Author

Rebased onto the updated base — #4555 picked up two new commits (e52d10409, 6404fc1a8) that touch scripts/dev-runner.ts in the same region as this PR, so GitHub flipped to CONFLICTING.

Resolution kept the base's improvements and adapted this PR to them:

  • Took HostProcessWorkingDirectory over process.cwd(), including for the new worktree port-offset hash this PR adds — it was the one remaining raw process.cwd() call, and using the service keeps it testable and consistent with the base.
  • Kept the base's blank---home-dir trim fix in the resolvedT3Home precedence chain.

45/45 tests passing (the base's 5 new tests merged in cleanly), typecheck 0 errors, and the runner still resolves the same stable offset (server=2849,web=2849) for both dev and dev:desktop.

Comment thread apps/web/vite.config.ts Resolved
Comment thread scripts/dev-runner.ts Resolved
Two findings from review.

stderrPreview carried the first 200 chars of raw CLI stderr into
DevShareError.detail and on into dev-runner's logs. tailscale prints auth
keys (tskey-...) and node names to stderr, and the package's own tests
already seed a token there and assert it does not leak — stderrPreview
walked straight past that invariant. Replace it with stderrDiagnostic, a
closed set of labels (no-existing-handler, not-logged-in,
permission-denied, unknown); callers match on the label and render our own
wording. Unrecognized stderr degrades to "unknown" rather than falling
back to text.

Port probing was narrowed to loopback, but --host/T3CODE_HOST moves the
backend onto another interface, and that interface decides whether the
bind succeeds. A port free on loopback and taken there was selected and
then failed to bind. Probe the configured host alongside loopback.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Jul 26, 2026
Comment thread scripts/dev-runner.ts Resolved
t3dotgg and others added 2 commits July 26, 2026 00:05
The runner deleted VITE_HTTP_URL/VITE_WS_URL for dev and dev:web, but
vite.config.ts calls loadRepoEnv, which merges .env/.env.local underneath
the process env. A developer with either URL in their .env got it back,
and Vite baked it into the bundle — pinning the client to localhost and
breaking every non-localhost origin. Invisible, too: the page still loads,
then dials the visitor's own machine.

Absence is not a usable signal, so state the intent: the runner sets
T3CODE_SINGLE_ORIGIN_DEV=1, and Vite ignores both URLs when it is set.
VITE_HTTP_URL is now pinned in `define` as well, since Vite's automatic
VITE_ exposure would otherwise leak it past the check.

Verified by A/B with a .env setting both URLs: the served module carries
"http://localhost:13773" without this change and "" with it, proxying
still 200.

Also point the dev:desktop --share refusal at `dev` rather than `dev:web`,
which starts no backend of its own.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
--host/T3CODE_HOST configures the backend. Vite takes its bind address
from HOST, which the runner sets for desktop alone, so the web port stays
on loopback. Probing it against the backend's interface could reject a
port that was free where Vite would actually bind, shifting offsets or
failing startup for no reason.

The checker now takes the port's role. Passed explicitly rather than
inferred from the port number, which stops discriminating once a large
T3CODE_PORT_OFFSET pushes the web port past the server base.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
@t3dotgg

t3dotgg commented Jul 26, 2026

Copy link
Copy Markdown
Member Author

Review round converged — CI green on 37e1c7978, mergeable, all six threads answered.

Fixed

dbad3bc9f --share silently half-worked for dev:desktop — shared a URL whose renderer dials the visitor's own loopback, and clobbered the VITE_DEV_SERVER_URL Electron loads from
ce4664d92 raw tailscale stderr (auth keys, node names) reached logs via stderrPreview; bind host was never probed after the loopback narrowing
2869a9e84 a repo .env revived VITE_HTTP_URL/VITE_WS_URL and silently defeated single-origin mode
37e1c7978 the web port was judged against the backend's bind interface (a flaw in my own earlier fix)

Declined, with reasoning

Refusing --share for dev:web. It's the documented "Vite only" mode, meant to pair with a separately-running dev:server, and that combination is legitimate to share; refusing it blocks a working setup to guard against a misconfiguration that announces itself the moment a request 502s. I did fix the half that was right — the dev:desktop refusal message pointed at dev:web, which was bad advice, and now points at dev. dev:desktop stays refused because it's broken even when everything runs correctly.

Things I checked empirically rather than by reading

  • Loopback-only probing is safe — a wildcard 0.0.0.0 listener still makes a later 127.0.0.1 bind fail EADDRINUSE, so loopback already catches wildcard squatters. This is why the narrowing was right and why I fixed the host gap by probing the specific configured host rather than restoring the wildcards.
  • The .env leak, by A/B — served module carried "http://localhost:13773" without the fix and "" with it, proxy still 200.
  • Single-origin proxying, end to end — descriptor through Vite 200, /api/foo at the backend 404 (no redirect loop), /somepage 302 to Vite.
  • Port stability — stable offset across restarts; earlier drift I saw was my own overlapping dev servers, not the worktree hash.

Still worth a human eye

Two intentional behavior changes that will generate reports if they surprise people: session cookies are renamed to t3_session_<port> in web mode, so every live dev session logs out once; and startup pairing tokens go to 24h (correctly gated to devUrl !== undefined && purpose === "startup", so real servers keep 5 minutes).

65 tests, typecheck 0 errors, lint clean on changed files. Still babysitting.

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

Actionable comments posted: 3

🧹 Nitpick comments (5)
scripts/dev-runner.ts (3)

639-639: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Recomputes the web port instead of reusing env.PORT.

createDevRunnerEnv already derived the same value into env.PORT; duplicating the BASE_WEB_PORT + webOffset arithmetic here is a second source of truth that will drift if web-port resolution ever changes.

♻️ Suggested change
-    const sharedWebPort = BASE_WEB_PORT + webOffset;
+    const sharedWebPort = Number(env.PORT);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/dev-runner.ts` at line 639, Update the code near sharedWebPort to
reuse the resolved env.PORT value produced by createDevRunnerEnv instead of
recomputing BASE_WEB_PORT + webOffset. Remove the duplicate arithmetic while
preserving the existing shared web-port behavior.

295-324: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

T3CODE_PORT is now set identically in both branches.

Lines 296 and 319 assign the same value; hoisting it above the isDesktopMode split would make the branch about the Vite URL/marker policy only.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/dev-runner.ts` around lines 295 - 324, Move the shared T3CODE_PORT
assignment above the isDesktopMode conditional, then remove the duplicate
assignments from both branches. Keep the existing Vite URL and
T3CODE_SINGLE_ORIGIN_DEV handling unchanged so the split only controls URL and
marker policy.

206-216: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Numeric T3CODE_DEV_INSTANCE bypasses the bounds applied elsewhere.

Unlike T3CODE_PORT_OFFSET (negative-checked) and the hashed path (% MAX_HASH_OFFSET), a numeric seed is used verbatim, so T3CODE_DEV_INSTANCE=90000 resolves to an out-of-range port pair and surfaces as DevRunnerPortExhaustedError rather than a message naming the bad input. Consider validating it against the same offset range.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/dev-runner.ts` around lines 206 - 216, Update the numeric-seed branch
in the dev-runner offset resolution to validate Number(seed) against the same
allowed offset bounds used by the other paths, rejecting values outside that
range with an error that identifies the invalid T3CODE_DEV_INSTANCE input;
preserve the existing hashed behavior and valid numeric offsets.
scripts/lib/dev-share.test.ts (1)

86-161: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider covering the no-tailnet-name / tailscale-unavailable branches.

Both produce user-facing hints and neither is exercised — a status payload without Self.DNSName and a non-zero status exit would close the gap cheaply given the existing spawnerLayer.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/lib/dev-share.test.ts` around lines 86 - 161, Add tests in the
shareDevServer suite for the no-tailnet-name and tailscale-unavailable branches:
configure spawnerLayer with a successful status response whose payload omits
Self.DNSName, and with a non-zero status exit respectively. Flip each effect and
assert the resulting DevShareError reason and user-facing hint message.
packages/tailscale/src/tailscale.ts (1)

252-254: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Duplicate stderrDiagnosticOf(stderr) evaluation in both error constructions. Both sites call the classifier once for the presence check and again for the value; binding the result once makes the intent clearer and avoids re-running the regex list.

  • packages/tailscale/src/tailscale.ts#L252-L254: hoist const stderrDiagnostic = stderrDiagnosticOf(stderr); before the TailscaleCommandExitError construction and spread ...(stderrDiagnostic ? { stderrDiagnostic } : {}).
  • packages/tailscale/src/tailscale.ts#L318-L320: apply the same hoist inside runTailscaleCommand.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/tailscale/src/tailscale.ts` around lines 252 - 254, Hoist the result
of stderrDiagnosticOf(stderr) into a local stderrDiagnostic before each
TailscaleCommandExitError construction, then reuse it for the conditional
stderrDiagnostic property. Apply this at packages/tailscale/src/tailscale.ts
lines 252-254 and 318-320 within runTailscaleCommand, preserving the existing
behavior when no diagnostic is available.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/server/src/auth/EnvironmentAuth.test.ts`:
- Around line 18-26: The makeServerConfigLayer helper currently allows overrides
to replace TEST_SERVER_PORT, which can desynchronize the server port and
makeCookieRequest’s fixed cookie name. Apply ...overrides before assigning port:
TEST_SERVER_PORT so the test port is always pinned while preserving all other
overrides.

In `@docs/reference/scripts.md`:
- Line 4: Update the documented base and sharing commands in the web-stack
startup instructions to use the required Bun workflow: replace the base command
with “bun run dev” and the sharing variant with “bun run dev:share”. Preserve
the existing descriptions of sharing behavior.

In `@packages/tailscale/src/tailscale.test.ts`:
- Around line 29-40: Update assertCarriesNoSecret to recursively inspect strings
inside nested objects, arrays, and causes, while preserving the message check.
Track visited objects with cycle protection so cyclic error structures terminate
safely, and retain field-specific context in assertion failures where practical.

---

Nitpick comments:
In `@packages/tailscale/src/tailscale.ts`:
- Around line 252-254: Hoist the result of stderrDiagnosticOf(stderr) into a
local stderrDiagnostic before each TailscaleCommandExitError construction, then
reuse it for the conditional stderrDiagnostic property. Apply this at
packages/tailscale/src/tailscale.ts lines 252-254 and 318-320 within
runTailscaleCommand, preserving the existing behavior when no diagnostic is
available.

In `@scripts/dev-runner.ts`:
- Line 639: Update the code near sharedWebPort to reuse the resolved env.PORT
value produced by createDevRunnerEnv instead of recomputing BASE_WEB_PORT +
webOffset. Remove the duplicate arithmetic while preserving the existing shared
web-port behavior.
- Around line 295-324: Move the shared T3CODE_PORT assignment above the
isDesktopMode conditional, then remove the duplicate assignments from both
branches. Keep the existing Vite URL and T3CODE_SINGLE_ORIGIN_DEV handling
unchanged so the split only controls URL and marker policy.
- Around line 206-216: Update the numeric-seed branch in the dev-runner offset
resolution to validate Number(seed) against the same allowed offset bounds used
by the other paths, rejecting values outside that range with an error that
identifies the invalid T3CODE_DEV_INSTANCE input; preserve the existing hashed
behavior and valid numeric offsets.

In `@scripts/lib/dev-share.test.ts`:
- Around line 86-161: Add tests in the shareDevServer suite for the
no-tailnet-name and tailscale-unavailable branches: configure spawnerLayer with
a successful status response whose payload omits Self.DNSName, and with a
non-zero status exit respectively. Flip each effect and assert the resulting
DevShareError reason and user-facing hint message.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6650ded2-f1b8-41f0-88dd-2bcf360de729

📥 Commits

Reviewing files that changed from the base of the PR and between 6404fc1 and 37e1c79.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (22)
  • .agents/skills/test-t3-app/SKILL.md
  • AGENTS.md
  • apps/server/src/auth/EnvironmentAuth.test.ts
  • apps/server/src/auth/EnvironmentAuth.ts
  • apps/server/src/auth/EnvironmentAuthPolicy.test.ts
  • apps/server/src/auth/EnvironmentAuthPolicy.ts
  • apps/server/src/auth/PairingGrantStore.ts
  • apps/server/src/auth/SessionStore.ts
  • apps/server/src/auth/utils.ts
  • apps/server/src/http.ts
  • apps/web/vite.config.ts
  • docs/reference/scripts.md
  • package.json
  • packages/shared/package.json
  • packages/shared/src/devProxy.ts
  • packages/tailscale/src/tailscale.test.ts
  • packages/tailscale/src/tailscale.ts
  • scripts/dev-runner.test.ts
  • scripts/dev-runner.ts
  • scripts/lib/dev-share.test.ts
  • scripts/lib/dev-share.ts
  • scripts/package.json

Comment thread docs/reference/scripts.md Resolved
Make assertCarriesNoSecret recurse. It checked only top-level strings, so
a leak inside a nested cause or an array would have passed while the
comment claimed coverage for fields added later. Verified the gap is real:
the shallow version passes on both a nested cause and an array carrying
the token, and the recursive one fails on each. Walks message/cause
explicitly (getters on Error subclasses are not own enumerable props) and
tracks visited objects so cyclic causes terminate.

Pin port after overrides in makeServerConfigLayer. makeCookieRequest
builds the cookie name from TEST_SERVER_PORT, so an override that changed
the port would leave the server reading one cookie name while requests
sent another.

Use bun run in docs/reference/scripts.md for the dev and dev:share lines,
matching AGENTS.md. Confirmed `bun run dev --share` forwards the flag.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
t3dotgg added a commit that referenced this pull request Jul 26, 2026
Rebasing onto the updated #4556 turned up two doc drifts: the base moved
the script list from `vp run` to `bun run`, and the state-directory
paragraph still described the fixed `userdata` preference that the mtime
tiebreak replaced.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
The Effect service conventions check was failing on this, correctly. The
single DevShareError violated four rules at once: a `reason` discriminator
chose both the user-facing message and the caller's remedy, the `message`
getter was a lookup table over it, `detail` copied `cause.message` and was
then used to build that message, and the underlying TailscaleCommandError
was discarded entirely so the error chain ended at the wrapper.

Now three classes, one per genuinely distinct failure:
TailscaleUnavailableError and TailnetNameMissingError each have one fixed
message and one remedy; DevServeFailedError keeps a `stage` discriminator,
which is legitimate — both stages share the same semantics (a serve
invocation failed for this port) and differ only in which one.

Each wrapping construction now preserves the immediate error as `cause`,
and every message derives solely from structural fields. unshareDevServer
returns the structured cause rather than a flattened string so its caller
can do the same. TailnetNameMissingError has no cause because none exists
— the status read succeeded and simply had no name.

Verified the chain end to end: the wrapped TailscaleCommandExitError is
reachable with exitCode and stderrDiagnostic intact, and the auth token in
stderr still never reaches the message.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
@t3dotgg

t3dotgg commented Jul 26, 2026

Copy link
Copy Markdown
Member Author

Fixed the failing Effect Service Conventions check in 2db512ad4.

The check was right, and its finding had been sitting in an orphaned inline comment from an earlier commit — the force-pushes marked it outdated, so it never showed up in my unreplied-thread sweep. My fault for only ever checking live threads.

DevShareError violated four rules of .macroscope/check-run-agents/effect-service-conventions.md at once:

  • a reason discriminator chose both the user-facing message and the caller's remedy (hint) — the convention says split those into separate classes
  • the message getter was a lookup table over that discriminator, which the convention names explicitly
  • detail copied cause.message and was then used to construct the wrapper message — also named explicitly
  • the underlying TailscaleCommandError was discarded entirely, so the error chain ended at the wrapper

Now three classes. TailscaleUnavailableError and TailnetNameMissingError each have one fixed message and one remedy, so the discriminator disappears. DevServeFailedError keeps a stage field — that one is legitimate under the convention, since both stages share the same semantics (a tailscale serve invocation failed for this port) and differ only in which one, which the message states plainly. The stage distinction matters operationally: clear-existing means the prior mapping survived, serve means it was already torn down.

Every wrapping construction now keeps the immediate error as cause, and messages derive solely from structural fields. unshareDevServer returns the structured cause instead of a flattened string so its caller can preserve the chain too. TailnetNameMissingError has no cause because there is no underlying failure — the status read succeeded and simply had no name, which is the case the convention describes as legitimately optional.

Verified the chain survives rather than assuming it: the wrapped TailscaleCommandExitError is reachable with exitCode and stderrDiagnostic intact, and the auth token seeded into stderr still never reaches the message — so this doesn't undo the earlier secret-leak fix.

204 tests passing across scripts/ and packages/tailscale/, typecheck 0 errors, lint clean.

patroza added a commit to patroza/t3code that referenced this pull request Jul 28, 2026
Opening a dev server from a remote client showed ERR_CONNECTION_REFUSED.
The client rewrote `localhost:PORT` to the environment's hostname, kept the
port and scheme, and navigated. That address only works if the port is
independently published there, which it usually is not — dev servers bind
loopback. The failure surfaced as a browser error page, indistinguishable
from a broken app, so agents reported it as one.

Reachability is now resolved by the environment, which is the only side that
knows what is listening and what the tailnet routes. A new
`preview.resolvePort` RPC answers with a URL it has verified:

- a same-machine client keeps plain localhost;
- an existing `tailscale serve` route is reused, at whatever port and scheme
  it was published under;
- a port already answering on the environment's own address (WSL, LAN, a
  tunnel) uses that address and publishes nothing;
- otherwise a tailnet-only HTTPS route is published, probed until it answers,
  and withdrawn when the dev server exits or the server shuts down.

When none of those work it fails with a reason and a next action instead of a
URL that cannot load. Navigation, the port list, chat links, and agent
`preview_navigate`/`preview_open` all route through it; the old synchronous
rewrite is kept for labels only.

Two loopback-family bugs fell out of verifying this end to end. Vite's default
`--host localhost` binds `::1` only, so `tailscale serve` mappings pinned to
`127.0.0.1` proxy to nothing and answer 502 — `vp run dev --share` produced a
URL that never worked. Both the new resolver and dev-share now target
`localhost` and let tailscale pick the family.

Upstream, not fork-local: both halves came from merged upstream PRs (pingdotgg#4011
rewrote the URL, pingdotgg#4556 added sharing) and the seam between them was never
covered. Promote after merge.
andreasmolnardev pushed a commit to andreasmolnardev/codewise that referenced this pull request Jul 28, 2026
patroza added a commit to patroza/t3code that referenced this pull request Jul 29, 2026
Opening a dev server from a remote client showed ERR_CONNECTION_REFUSED.
The client rewrote `localhost:PORT` to the environment's hostname, kept the
port and scheme, and navigated. That address only works if the port is
independently published there, which it usually is not — dev servers bind
loopback. The failure surfaced as a browser error page, indistinguishable
from a broken app, so agents reported it as one.

Reachability is now resolved by the environment, which is the only side that
knows what is listening and what the tailnet routes. A new
`preview.resolvePort` RPC answers with a URL it has verified:

- a same-machine client keeps plain localhost;
- an existing `tailscale serve` route is reused, at whatever port and scheme
  it was published under;
- a port already answering on the environment's own address (WSL, LAN, a
  tunnel) uses that address and publishes nothing;
- otherwise a tailnet-only HTTPS route is published, probed until it answers,
  and withdrawn when the dev server exits or the server shuts down.

When none of those work it fails with a reason and a next action instead of a
URL that cannot load. Navigation, the port list, chat links, and agent
`preview_navigate`/`preview_open` all route through it; the old synchronous
rewrite is kept for labels only.

Two loopback-family bugs fell out of verifying this end to end. Vite's default
`--host localhost` binds `::1` only, so `tailscale serve` mappings pinned to
`127.0.0.1` proxy to nothing and answer 502 — `vp run dev --share` produced a
URL that never worked. Both the new resolver and dev-share now target
`localhost` and let tailscale pick the family.

Upstream, not fork-local: both halves came from merged upstream PRs (pingdotgg#4011
rewrote the URL, pingdotgg#4556 added sharing) and the seam between them was never
covered. Promote after merge.
patroza added a commit to patroza/t3code that referenced this pull request Jul 29, 2026
Opening a dev server from a remote client showed ERR_CONNECTION_REFUSED.
The client rewrote `localhost:PORT` to the environment's hostname, kept the
port and scheme, and navigated. That address only works if the port is
independently published there, which it usually is not — dev servers bind
loopback. The failure surfaced as a browser error page, indistinguishable
from a broken app, so agents reported it as one.

Reachability is now resolved by the environment, which is the only side that
knows what is listening and what the tailnet routes. A new
`preview.resolvePort` RPC answers with a URL it has verified:

- a same-machine client keeps plain localhost;
- an existing `tailscale serve` route is reused, at whatever port and scheme
  it was published under;
- a port already answering on the environment's own address (WSL, LAN, a
  tunnel) uses that address and publishes nothing;
- otherwise a tailnet-only HTTPS route is published, probed until it answers,
  and withdrawn when the dev server exits or the server shuts down.

When none of those work it fails with a reason and a next action instead of a
URL that cannot load. Navigation, the port list, chat links, and agent
`preview_navigate`/`preview_open` all route through it; the old synchronous
rewrite is kept for labels only.

Two loopback-family bugs fell out of verifying this end to end. Vite's default
`--host localhost` binds `::1` only, so `tailscale serve` mappings pinned to
`127.0.0.1` proxy to nothing and answer 502 — `vp run dev --share` produced a
URL that never worked. Both the new resolver and dev-share now target
`localhost` and let tailscale pick the family.

Upstream, not fork-local: both halves came from merged upstream PRs (pingdotgg#4011
rewrote the URL, pingdotgg#4556 added sharing) and the seam between them was never
covered. Promote after merge.
patroza added a commit to patroza/t3code that referenced this pull request Jul 29, 2026
Opening a dev server from a remote client showed ERR_CONNECTION_REFUSED.
The client rewrote `localhost:PORT` to the environment's hostname, kept the
port and scheme, and navigated. That address only works if the port is
independently published there, which it usually is not — dev servers bind
loopback. The failure surfaced as a browser error page, indistinguishable
from a broken app, so agents reported it as one.

Reachability is now resolved by the environment, which is the only side that
knows what is listening and what the tailnet routes. A new
`preview.resolvePort` RPC answers with a URL it has verified:

- a same-machine client keeps plain localhost;
- an existing `tailscale serve` route is reused, at whatever port and scheme
  it was published under;
- a port already answering on the environment's own address (WSL, LAN, a
  tunnel) uses that address and publishes nothing;
- otherwise a tailnet-only HTTPS route is published, probed until it answers,
  and withdrawn when the dev server exits or the server shuts down.

When none of those work it fails with a reason and a next action instead of a
URL that cannot load. Navigation, the port list, chat links, and agent
`preview_navigate`/`preview_open` all route through it; the old synchronous
rewrite is kept for labels only.

Two loopback-family bugs fell out of verifying this end to end. Vite's default
`--host localhost` binds `::1` only, so `tailscale serve` mappings pinned to
`127.0.0.1` proxy to nothing and answer 502 — `vp run dev --share` produced a
URL that never worked. Both the new resolver and dev-share now target
`localhost` and let tailscale pick the family.

Upstream, not fork-local: both halves came from merged upstream PRs (pingdotgg#4011
rewrote the URL, pingdotgg#4556 added sharing) and the seam between them was never
covered. Promote after merge.
GenKerensky added a commit to GenKerensky/t3code that referenced this pull request Jul 29, 2026
`tailscale serve --https=<port> off` exits 1 with "handler does not exist"
when nothing is bound on that port. Confirmed against the real CLI:

    $ tailscale serve --https=8443 off
    error: failed to remove web serve: handler does not exist
    exit=1

The eager teardown treated that as a failure, so settings never recorded
`enabled: false`: the toggle stayed on and the user was warned the backend
might still be reachable, when in fact nothing was serving. It bit hardest in
precisely the case the eager teardown was added for — settings saying enabled
while no child ever bound Serve — leaving the user unable to turn it off at all.

Upstream anticipated this: pingdotgg#4556's label set carries `no-existing-handler` with
a comment naming `serve off` on an unmapped port as the case callers should
recognize. Match on it and continue.

The rollback is now armed only when a binding was actually removed. Re-creating
one that never existed would expose the backend rather than restore it.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015ajcLHZtGhRQRD6BwscU9R
GenKerensky added a commit to GenKerensky/t3code that referenced this pull request Jul 29, 2026
Two things surfaced by rebasing onto current main.

The desktop error mapping reads its reason from the classified
`stderrDiagnostic` label via `describeTailscaleServeExitCause`, rather than the
`detail` field pingdotgg#4556 removed. That adaptation lived only in the merge commit
this branch previously carried, so replaying the commits linearly dropped it.

Main's new `DesktopLifecycle.test.ts` builds a complete `ElectronApp` mock, and
this branch adds `releaseSingleInstanceLock` to that service — so the new test
stopped typechecking once the two met. Added the missing member to the mock.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015ajcLHZtGhRQRD6BwscU9R
awtprod added a commit to awtprod/t3-code that referenced this pull request Aug 1, 2026
* Fix incorrect pluralization of “entry” (pingdotgg#3933)

* feat(server): title background-task work-log rows with the task name (pingdotgg#3751)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix: delegate OpenCode session titles to provider (pingdotgg#3720)

* Archive selected threads from the context menu (pingdotgg#3895)

* fix(cli): support force removing projects (pingdotgg#3922)

* fix: allow sidebar to be shrunk when wider than viewport (pingdotgg#2456)

Co-authored-by: Shoaib Ansari <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>

* fix(codex): show web search query and url in tool call details (pingdotgg#2093)

Co-authored-by: Julius Marminge <[email protected]>

* Add Codex launch arguments setting (pingdotgg#2892)

Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: root <[email protected]>

* [orchestration] Clear stale active turn when session becomes inactive (pingdotgg#3159)

Co-authored-by: Julius Marminge <[email protected]>

* Regenerate Codex reset credit protocol bindings (pingdotgg#4173)

Co-authored-by: codex <[email protected]>

* fix(preview): preserve direct localhost navigation (pingdotgg#3939)

Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: codex <[email protected]>

* Synchronize mobile threads with authoritative shell snapshots (pingdotgg#4163)

Co-authored-by: codex <[email protected]>

* Gate iOS glass layout on native support (pingdotgg#4032)

Co-authored-by: codex <[email protected]>

* fix(opencode): resume the OpenCode session on follow-ups instead of starting an empty one (pingdotgg#3617)

Co-authored-by: codex <[email protected]>

* fix(server): use CLI for OpenCode health check instead of spawning server (pingdotgg#4153)

* fix(web): scope timeline minimap hover target to the side gutter (pingdotgg#3869)

Co-authored-by: Claude Fable 5 <[email protected]>

* [codex] show complete approval details (pingdotgg#4111)

* fix(web): paint text selection over composer chips (pingdotgg#4139)

Signed-off-by: Yordis Prieto <[email protected]>

* [codex] preserve custom model slugs (pingdotgg#4168)

* fix(web): preview workspace images in the file panel (pingdotgg#3996)

Co-authored-by: Rhiz3K <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>

* feat(web): drag files from the explorer into the chat composer (pingdotgg#4140)

Co-authored-by: Julius Marminge <[email protected]>
Signed-off-by: Yordis Prieto <[email protected]>

* fix(desktop): preserve main window bounds (pingdotgg#3851)

Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: codex <[email protected]>

* perf(orchestration): speed up new-chat propagation and offline catch-up (pingdotgg#4177)

Co-authored-by: codex <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>

* Finale: upgrade changed files card to fix various UI issues (pingdotgg#4113)

Co-authored-by: Julius Marminge <[email protected]>

* Pass CLI OAuth config to hosted web deploy (pingdotgg#4186)

Co-authored-by: codex <[email protected]>

* fix(web): always show environment chip for remote projects (pingdotgg#4217)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): keep composer editable while disconnected (pingdotgg#4241)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix: better defaults — Claude 1M context, Codex gpt-5.6, worktrees from origin main (pingdotgg#4240)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(claude): handle all SDK stream messages; stop spurious work-log warning rows (pingdotgg#4244)

Co-authored-by: Claude Fable 5 <[email protected]>

* Sidebar v2 beta: flat thread list with a server-backed settled lifecycle (pingdotgg#4026)

Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: maria-rcks <[email protected]>

* fix(settings): validate the add-provider wizard step before advancing (pingdotgg#2813) (pingdotgg#3100)

Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: codex <[email protected]>

* fix(claude): isolate capability probe from user MCP servers (pingdotgg#4015)

Co-authored-by: codex <[email protected]>

* Preserve connecting status while a turn starts (pingdotgg#4101)

Co-authored-by: codex <[email protected]>

* fix(server): stop restoring stale OpenCode models (pingdotgg#4095)

Co-authored-by: codex <[email protected]>

* [codex] keep scoped package references as text (pingdotgg#4167)

Co-authored-by: codex <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>

* fix(web): default provider selection for users without Codex (pingdotgg#4117)

Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: codex <[email protected]>

* Unify temporary worktree branch naming (pingdotgg#4278)

* fix(web): use message-square icon for settled icon-less project threads in sidebar v2 (pingdotgg#4279)

* Stabilize sidebar settling animations (pingdotgg#4280)

* Restore Copy Link in chat link context menu (pingdotgg#4161)

Co-authored-by: Julius Marminge <[email protected]>

* fix(desktop): handle EPIPE errors on stdout/stderr to prevent crash dialog (pingdotgg#4213)

* Preserve draft thread highlighting during promotion (pingdotgg#4283)

Co-authored-by: codex <[email protected]>

* Move mobile working timer into the thread timeline (pingdotgg#4285)

* Stabilize PR status lookups and provider session lifecycle (pingdotgg#4281)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix: open command palette instead of custom dialog for new thread picker in SidebarV2 (pingdotgg#4269)

* fix(server): don't drop sticky PR fallback when remote URL can't be resolved (pingdotgg#4289)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(web): copy branch name via right-click in the branch selector (pingdotgg#4275)

Co-authored-by: Claude Fable 5 <[email protected]>

* Add remote server updates and standalone service management (pingdotgg#4286)

Co-authored-by: codex <[email protected]>

* Refine light-mode sidebar surfaces (pingdotgg#4268)

Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: codex <[email protected]>

* fix(mobile): don't mark Android VPN/Tailscale as offline when connected (pingdotgg#3949)

* improve and prevent silent thread branch drift and PR fetching (pingdotgg#2284)

Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: codex <[email protected]>

* feat(web): refresh application surfaces

* style(web): polish dark mode dialogs

* fix(web): unify and tune glass surfaces

Co-authored-by: codex <[email protected]>

* fix(web): apply glass opacity to thread tooltip

* fix(web): override thread tooltip background

* fix(web): apply glass opacity to model picker

* style(web): polish glass opacity slider

* fix(web): apply glass opacity to command palette

* fix(web): add glass composer alerts

* fix(web): honor composer glass opacity

* test(web): stabilize timeline module setup

* style(web): fade settings content beneath navbar

* test(desktop): include glass opacity in settings fixture

* fix(web): address redesign review findings

* fix(web): sync provider banner dismissal

* fix(web): new-thread defaults ignored for remote environments (pingdotgg#4276)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat: add "Auto" runtime mode — AI-reviewed approvals for Codex and Claude (pingdotgg#4272)

Co-authored-by: Claude Fable 5 <[email protected]>

* Add shared t3.json project configuration support (pingdotgg#4317)

* Restore light-mode surfaces and refine dialog styling

- Restore light-mode glass, dialog, dropdown, and composer colors
- Refine provider wizard, changed-file cards, sidebar controls, and buttons
- Update wizard step tests for the new list structure

* Unify dialog glass and fix composer overlays (pingdotgg#4365)

Co-authored-by: codex <[email protected]>

* fix(web): warn before silent Windows updates (pingdotgg#4350)

* [codex] Move project grouping to General settings (pingdotgg#4313)

Co-authored-by: codex <[email protected]>

* [codex] Group project scopes in mobile thread lists (pingdotgg#4314)

Co-authored-by: codex <[email protected]>

* [codex] Move mobile project grouping to General settings (pingdotgg#4315)

Co-authored-by: codex <[email protected]>

* [codex] Deduplicate connection failure messaging (pingdotgg#4367)

Co-authored-by: codex <[email protected]>

* Restore grouped project filtering in Sidebar V2 (pingdotgg#4282)

Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: codex <[email protected]>

* [codex] restore Sidebar V2 project actions (pingdotgg#4373)

Co-authored-by: codex <[email protected]>

* [codex] Group projects in new-thread pickers (pingdotgg#4312)

Co-authored-by: codex <[email protected]>

* fix(web): restore dark composer toolbar styling

* Fix thread tooltip folder icon color (pingdotgg#4383)

* fix(server): parse CLI version in update preflight (pingdotgg#4389)

* fix(web): sidebar v2 polish — jump hints, working duration, in-flight fade, settled sort (pingdotgg#4274)

Co-authored-by: Claude Fable 5 <[email protected]>

* Fix logical project grouping labels on mobile (pingdotgg#4391)

Co-authored-by: codex <[email protected]>

* Add preview color scheme controls and simplify project grouping (pingdotgg#4385)

Co-authored-by: codex <[email protected]>
Co-authored-by: Claude Fable 5 <[email protected]>

* fix(cli): publish nightly branded favicons (pingdotgg#4372)

* Fix thread loading flash (pingdotgg#4396)

* fix(client-runtime): keep a warm thread un-settled despite a merged/closed PR (pingdotgg#4309)

Co-authored-by: Claude Fable 5 <[email protected]>

* Fix composer context strip alignment and glass shell (pingdotgg#4404)

* Polish iOS git progress overlay with glass effects (pingdotgg#4387)

* Improve composer glass fallbacks (pingdotgg#4406)

Co-authored-by: codex <[email protected]>

* feat(web): collapse large git diffs by default to make chat more readable (pingdotgg#4409)

* Stop new threads inheriting checkout/branch from viewed thread (pingdotgg#4411)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix: tone down branch-mismatch banner (pingdotgg#4416)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix: Claude Code skills discoverable for the composer $ picker (pingdotgg#4414)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): keep settled threads reachable when opened directly (pingdotgg#4413)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(sidebar-v2): thread snoozing (pingdotgg#4311)

Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: maria <[email protected]>

* Upgrade Clerk packages and Expo integration (pingdotgg#4440)

* Increase light-mode contrast for user message bubbles (pingdotgg#4441)

* Restore model picker layout and retain iterative test state (pingdotgg#4450)

Co-authored-by: codex <[email protected]>

* Color settled PR labels on hover (pingdotgg#4451)

Co-authored-by: codex <[email protected]>

* [codex] Fix glass hover compositing artifacts (pingdotgg#4446)

Co-authored-by: codex <[email protected]>

* Add Claude Opus 5 model (pingdotgg#4472)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
Co-authored-by: Theo Browne <[email protected]>

* feat(web): add collapse-all toggle to diff panel (pingdotgg#4475)

* feat(web): show fast mode as a bolt instead of a "Normal" label (pingdotgg#4488)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* feat(dev): keep worktree dev state isolated on T3 Code dev servers (pingdotgg#4555)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* feat(dev): Make t3 code dev instances shareable over Tailscale (pingdotgg#4556)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* fix(dev): skip browser-blocked ports (pingdotgg#4608)

* fix: cut websocket throughput in half by pruning activity payloads (pingdotgg#4622)

* perf(mobile): defer work-log detail serialization (pingdotgg#4607)

* test: account for lazy thread feed details (pingdotgg#4628)

* feat(relay): limit managed tunnels per user (pingdotgg#4530)

Co-authored-by: Claude Fable 5 <[email protected]>

* Add managed tunnel limits migration (pingdotgg#4635)

* Add background preview capture and picture-in-picture support (pingdotgg#4397)

Co-authored-by: codex <[email protected]>

* feat(web): prompt stash — cmd+S saves the composer to a per-provider queue (pingdotgg#4453)

Co-authored-by: Claude Fable 5 <[email protected]>

* Upgrade Effect and Alchemy betas (pingdotgg#4643)

Prepare Relay production infrastructure for the PlanetScale PS_20 HA topology, upgrade Effect and Alchemy to compatible betas, reconcile migration state, and preserve patched MCP session termination behavior.\n\nCo-authored-by: codex <[email protected]>

* feat: allow new thread creation through project breadcrumbs (pingdotgg#4638)

* fix(web): scope PR state to the thread branch (pingdotgg#4460)

Co-authored-by: codex <[email protected]>

* Drop redundant Relay user indexes (pingdotgg#4648)

Co-authored-by: codex <[email protected]>

* feat(connect): release the Cloudflare tunnel when the environment shuts down (pingdotgg#4531)

Co-authored-by: Claude Fable 5 <[email protected]>

* Fix Relay Worker RuntimeContext wiring (pingdotgg#4653)

Co-authored-by: codex <[email protected]>

* Fix live sidebar resize limits and defer Alchemy runtime context (pingdotgg#4655)

* fix(web): constrain branch toolbar context (pingdotgg#4657)

* Keep MCP credentials alive across provider turns (pingdotgg#4659)

* fix: close actions dropdown when editing (pingdotgg#4660)

* fix(preview): stabilize PiP viewport identity (pingdotgg#4661)

Co-authored-by: codex <[email protected]>

* Add glass styling for thread tooltips and simplify preview tab handling (pingdotgg#4665)

* Use tarball archiving for hosted web deploys (pingdotgg#4669)

* fix(server): bound editor discovery during config loading (pingdotgg#4291)

* Prevent draft thread detail polling before shell registration (pingdotgg#4670)

Co-authored-by: codex <[email protected]>

* feat: add configurable source control writing settings (pingdotgg#4204)

Co-authored-by: Claude <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: codex <[email protected]>

* feat(diff-panel): show total line additions and deletions (pingdotgg#4674)

* Clear provider update actions while updating (pingdotgg#4676)

* Fix sidebar highlighting for draft threads (pingdotgg#4679)

* Use glass surfaces for web toasts (pingdotgg#4681)

* Show origin ref in branch trigger label (pingdotgg#4680)

Co-authored-by: codex <[email protected]>

* fix(mobile): match react version to react-native 0.85.3 vendored renderer (19.2.3) (pingdotgg#4675)

* chore(release): prepare v0.0.29

* Add OTA update checks to mobile settings (pingdotgg#4686)

* fix(mobile): threads load snapped to bottom on iOS (pingdotgg#4689)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat: default sidebar v2 on for nightly and dev builds (pingdotgg#4491)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* fix(web): 33 web UI fixes (pingdotgg#4700)

* Make mobile Thread List v2 the default (pingdotgg#4717)

* Fix mobile showcase workflow without Clerk (pingdotgg#4718)

* Fix relay credential lookup for unlinked environments (pingdotgg#4692)

Co-authored-by: codex <[email protected]>

* Settle merged PR threads immediately (pingdotgg#4704)

* feat(web): add maria's sidebar header artwork toggle (pingdotgg#4652)

* feat(web): add appearance settings category (pingdotgg#4715)

* fix(desktop): allow updater-controlled relaunch (pingdotgg#4721)

* fix(web): prevent diff panel scroll jumping (pingdotgg#4724)

* Link inline code file paths in chat markdown (pingdotgg#4726)

Co-authored-by: Claude Fable 5 <[email protected]>

* Fix Android showcase capture and rebuild v2 queued rows (pingdotgg#4730)

Co-authored-by: Claude <[email protected]>

* perf(server): negotiate permessage-deflate on the websocket (pingdotgg#4705)

Co-authored-by: Claude Fable 5 <[email protected]>

* docs: overhaul agent guidance (pingdotgg#4782)

* Prevent sidebar row labels from truncating (pingdotgg#4789)

* perf(server): gzip large thread snapshots (pingdotgg#4788)

* fix(web): stashed prompts now survive switching providers (pingdotgg#4787)

Co-authored-by: Claude Fable 5 <[email protected]>

* Fix Git ref refresh resource storms (pingdotgg#4727)

Co-authored-by: codex <[email protected]>

* perf(server): trim stale context-window rows and drop dead replay RPC (pingdotgg#4791)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): defer command palette filesystem navigation (pingdotgg#2109)

Co-authored-by: codex <[email protected]>

* fix(release): skip scripts during Vercel installs (pingdotgg#4796)

* refactor(client): share filesystem browse navigation (pingdotgg#4797)

Co-authored-by: codex <[email protected]>

* fix(mobile): defer filesystem navigation (pingdotgg#4799)

Co-authored-by: codex <[email protected]>

* refactor(server): use native HTTP compression streams (pingdotgg#4798)

Co-authored-by: codex <[email protected]>

* Remove Connect waitlist and add GA announcement tooling (pingdotgg#4691)

* Fix Connect sign-in settings label (pingdotgg#4806)

* chore(release): prepare v0.0.30

* fix(desktop): restore T3 Connect sign-in (pingdotgg#4809)

Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: Claude Fable 5 <[email protected]>

* Simplify files panel header (pingdotgg#4828)

* build(desktop): reduce installed app size by ~300MB (pingdotgg#4824)

* Update model version from claude-opus-4-8 to claude-opus-5 (pingdotgg#4832)

* Preserve the thread shell while detail loads (pingdotgg#4830)

* Reduce idle work and disk churn with native resource diagnostics (pingdotgg#2679)

Co-authored-by: codex <[email protected]>

* fix(server): detect repositories after initialization (pingdotgg#4848)

* perf(server): merge separate staged/unstaged numstat calls into single diff HEAD --numstat (pingdotgg#4843)

* fix(git): disable external diff for review diff previews (pingdotgg#4854)

* Fix editable file focus and live syntax highlighting (pingdotgg#3979)

* fix(web): remember the rendered-markdown choice across threads (pingdotgg#4853)

Co-authored-by: Simon Doba <[email protected]>
Co-authored-by: Claude Opus 5 <[email protected]>

* chore(release): prepare v0.0.31

* fix(mobile): reduce thread feed scroll jank (pingdotgg#4874)

* fix(web): restore sidebar v2 thread actions and terminal icon (pingdotgg#4712)

* fix(web): settle button now works on hover, not just right-click (pingdotgg#4905)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(clients): disable add project while disconnected (pingdotgg#4834)

* fix(composer): hide default Codex service tier (pingdotgg#4784)

* docs: link iOS and Android app store downloads (pingdotgg#4902)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): align remote server update action (pingdotgg#4731)

* fix(connect): suggest a serve command that matches how you ran connect (pingdotgg#4897)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(mobile): stop shared content errors in Personal Team builds (pingdotgg#4943)

* perf(mobile): sends respond instantly, thread opens stop freezing (pingdotgg#4882)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): show Codex fast mode as a bolt (pingdotgg#4947)

* docs: seed worktrees with a copy of real userdata instead of banning it (pingdotgg#4949)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(mobile): support dragged images in the composer (pingdotgg#4953)

* fix(mobile): stop long iOS threads from jumping while scrolling up (pingdotgg#4867)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): keep worktree default when switching a draft's machine (pingdotgg#4964)

Co-authored-by: Claude Fable 5 <[email protected]>

* perf(mobile): reconnect environments immediately on resume (pingdotgg#4878)

* feat(web): pasting a huge screenshot now compresses it instead of erroring (pingdotgg#4967)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(web): regenerate thread titles from sidebar (pingdotgg#4810)

* fix(web): show server update progress through reconnect (pingdotgg#4903)

* feat(search): find threads by conversation content (pingdotgg#4959)

* fix: marketing site Vercel builds no longer die after ~100 deploys (pingdotgg#4975)

Co-authored-by: Claude Fable 5 <[email protected]>

* docs: split user and maintainer docs, fix 100+ stale claims (pingdotgg#4807)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): server updates no longer look like warnings (pingdotgg#4992)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(connect): reboots no longer strand the relay link, 403s now say why (pingdotgg#4988)

Co-authored-by: Claude Fable 5 <[email protected]>

* Add project file picker (⌘P) and project content search (⇧⌘F) (pingdotgg#4855)

Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>

* Check for mobile app updates on launch (pingdotgg#4958)

Co-authored-by: codex <[email protected]>

* fix(mobile): support pre-Liquid-Glass iOS bottom toolbar (pingdotgg#4984)

* fix(server): restore PR detection without HOME (pingdotgg#4985)

* fix(web): fill fast mode icon (pingdotgg#5004)

* fix: cache project favicons across web and mobile (pingdotgg#4767)

* perf(ci): cut stale runs and redundant setup (pingdotgg#4802)

* chore(mobile): bump app version to 1.0.1

Co-Authored-By: Claude Fable 5 <[email protected]>

* style(web): make scroll-to-end pill translucent (pingdotgg#5036)

* fix(ci): drop sparse-checkout from EAS workflows

actions/checkout implements sparse-checkout with --filter=blob:none, so
the runner repo is a partial clone missing the .repos/ blobs. eas-cli
archives the project via `git clone --depth 1 file://<workspace>`,
which upload-pack cannot serve from a partial clone and exits 128
(pingdotgg#4802 broke both EAS build workflows this way).

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(desktop): bump Clerk Electron SDK to 0.0.24 and register t3code:// scheme on Linux (pingdotgg#5015)

Co-authored-by: Claude Fable 5 <[email protected]>

* perf(server): cache default branch name and origin existence across status refreshes (pingdotgg#5008)

* feat(shared): support shorthand (major-only) versions in the semver helpers (pingdotgg#5027)

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>

* fix(mobile): remove unnecessary photo library permission (pingdotgg#4929)

* fix(shared): lenient JSON parser deletes commas inside string values (pingdotgg#5025)

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>

* fix(mobile): default bare IP pairing to HTTP (pingdotgg#4990)

* fix(mobile): restore iOS Threads branding (pingdotgg#4862)

* chore: add mobile issue template area (pingdotgg#4895)

* fix(desktop): link release notes from the update downloaded toast (pingdotgg#4771)

Co-authored-by: Claude Opus 5 <[email protected]>

* fix(mobile): accept Android clipboard images in composer (pingdotgg#4836)

* fix(mobile): show the correct build channel in Android's Threads page header (pingdotgg#4861)

* fix(contracts): decode growing config unions forward-compatibly (pingdotgg#5055)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(mobile): server model, worktree, and origin preferences now apply to new tasks (pingdotgg#5064)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(ci): repair the mobile showcase screenshots workflow (pingdotgg#5057)

* fix(ci): capture iPad App Store screenshots in landscape (pingdotgg#5065)

* fix(oxlint-plugin): Resolve the oxlint bin without assuming a pnpm layout (pingdotgg#5066)

* feat(cli): `npx t3 pair` - generate QR code from a running server (pingdotgg#4955)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(server): self-update no longer rolls itself back on restart (pingdotgg#5095)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(ci): rotate iPad showcase captures without Simulator UI scripting (pingdotgg#5094)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(web): render terminals with libghostty-vt (pingdotgg#4860)

Co-authored-by: Claude Fable 5 <[email protected]>

* refactor: move the canonical libghostty-vt vendor to the repository root (pingdotgg#5102)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(mobile): add thread snoozing (pingdotgg#5053)

* feat(mobile): make settled threads collapsible (pingdotgg#5056)

* follow-up normalization after pingdotgg#4700. (pingdotgg#4498)

Co-authored-by: T3 Code Test <[email protected]>

* feat(web): search threads from the sidebar (pingdotgg#4769)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(release): prepare Command Center desktop v1

* fix(ci): allow public release publisher identity

* fix(web): avoid Windows preview path collision

* test(release): reject Windows module path collisions

* fix(release): bundle command center core

* fix: audit preserved upstream history safely

* feat(providers): add Kimi, subagents, and usage analytics

* fix(ci): repair reconnects and PNG safety scanning

* test(desktop): update Clerk environment fixture

* fix(ci): align provider and server integration contracts

* perf(web): skip impossible image encodings

---------

Signed-off-by: Yordis Prieto <[email protected]>
Co-authored-by: mel <[email protected]>
Co-authored-by: Theo Browne <[email protected]>
Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: Tristan Knight <[email protected]>
Co-authored-by: Christoph Herzog <[email protected]>
Co-authored-by: Andrew Barnes <[email protected]>
Co-authored-by: Shoaib <[email protected]>
Co-authored-by: Shoaib Ansari <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: Guilherme Vieira <[email protected]>
Co-authored-by: James <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: root <[email protected]>
Co-authored-by: Andrew Forster <[email protected]>
Co-authored-by: codex <[email protected]>
Co-authored-by: Chris Michael Guzman <[email protected]>
Co-authored-by: Vadym Kotai <[email protected]>
Co-authored-by: Utkarsh Patil <[email protected]>
Co-authored-by: xxashxx-svg <[email protected]>
Co-authored-by: Maxwell Young <[email protected]>
Co-authored-by: Yordis Prieto <[email protected]>
Co-authored-by: Rhiz3K <[email protected]>
Co-authored-by: Rhiz3K <[email protected]>
Co-authored-by: Anirudh Coontoor <[email protected]>
Co-authored-by: Rusiru Sadathana <[email protected]>
Co-authored-by: ss <[email protected]>
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Leonel Rivas <[email protected]>
Co-authored-by: Jaret Bottoms <[email protected]>
Co-authored-by: Ishan <[email protected]>
Co-authored-by: Yukun Shan <[email protected]>
Co-authored-by: Miklós Fazekas <[email protected]>
Co-authored-by: Henry Zhang <[email protected]>
Co-authored-by: Rushikesh Gaikwad <[email protected]>
Co-authored-by: legs <[email protected]>
Co-authored-by: shivam <[email protected]>
Co-authored-by: tomlit <[email protected]>
Co-authored-by: jan <[email protected]>
Co-authored-by: Alex Southwell <[email protected]>
Co-authored-by: Max Katz <[email protected]>
Co-authored-by: Krzysztof Moch <[email protected]>
Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com>
Co-authored-by: Alex <[email protected]>
Co-authored-by: wukko <[email protected]>
Co-authored-by: Wout Stiens <[email protected]>
Co-authored-by: ohbentos <[email protected]>
Co-authored-by: Jake Leventhal <[email protected]>
Co-authored-by: Simon Doba <[email protected]>
Co-authored-by: Simon Doba <[email protected]>
Co-authored-by: Gabriel De Andrade <[email protected]>
Co-authored-by: Jono Kemball <[email protected]>
Co-authored-by: Arham Amin <[email protected]>
Co-authored-by: Elaine Lyons <[email protected]>
Co-authored-by: Simone <[email protected]>
Co-authored-by: Max Anderson <[email protected]>
Co-authored-by: Aditya Vardhan Sharma <[email protected]>
Co-authored-by: Mike Olson <[email protected]>
Co-authored-by: T3 Code Test <[email protected]>
Co-authored-by: atryan <[email protected]>
awtprod added a commit to awtprod/t3-code that referenced this pull request Aug 2, 2026
* fix: delegate OpenCode session titles to provider (pingdotgg#3720)

* Archive selected threads from the context menu (pingdotgg#3895)

* fix(cli): support force removing projects (pingdotgg#3922)

* fix: allow sidebar to be shrunk when wider than viewport (pingdotgg#2456)

Co-authored-by: Shoaib Ansari <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>

* fix(codex): show web search query and url in tool call details (pingdotgg#2093)

Co-authored-by: Julius Marminge <[email protected]>

* Add Codex launch arguments setting (pingdotgg#2892)

Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: root <[email protected]>

* [orchestration] Clear stale active turn when session becomes inactive (pingdotgg#3159)

Co-authored-by: Julius Marminge <[email protected]>

* Regenerate Codex reset credit protocol bindings (pingdotgg#4173)

Co-authored-by: codex <[email protected]>

* fix(preview): preserve direct localhost navigation (pingdotgg#3939)

Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: codex <[email protected]>

* Synchronize mobile threads with authoritative shell snapshots (pingdotgg#4163)

Co-authored-by: codex <[email protected]>

* Gate iOS glass layout on native support (pingdotgg#4032)

Co-authored-by: codex <[email protected]>

* fix(opencode): resume the OpenCode session on follow-ups instead of starting an empty one (pingdotgg#3617)

Co-authored-by: codex <[email protected]>

* fix(server): use CLI for OpenCode health check instead of spawning server (pingdotgg#4153)

* fix(web): scope timeline minimap hover target to the side gutter (pingdotgg#3869)

Co-authored-by: Claude Fable 5 <[email protected]>

* [codex] show complete approval details (pingdotgg#4111)

* fix(web): paint text selection over composer chips (pingdotgg#4139)

Signed-off-by: Yordis Prieto <[email protected]>

* [codex] preserve custom model slugs (pingdotgg#4168)

* fix(web): preview workspace images in the file panel (pingdotgg#3996)

Co-authored-by: Rhiz3K <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>

* feat(web): drag files from the explorer into the chat composer (pingdotgg#4140)

Co-authored-by: Julius Marminge <[email protected]>
Signed-off-by: Yordis Prieto <[email protected]>

* fix(desktop): preserve main window bounds (pingdotgg#3851)

Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: codex <[email protected]>

* perf(orchestration): speed up new-chat propagation and offline catch-up (pingdotgg#4177)

Co-authored-by: codex <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>

* Finale: upgrade changed files card to fix various UI issues (pingdotgg#4113)

Co-authored-by: Julius Marminge <[email protected]>

* Pass CLI OAuth config to hosted web deploy (pingdotgg#4186)

Co-authored-by: codex <[email protected]>

* fix(web): always show environment chip for remote projects (pingdotgg#4217)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): keep composer editable while disconnected (pingdotgg#4241)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix: better defaults — Claude 1M context, Codex gpt-5.6, worktrees from origin main (pingdotgg#4240)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(claude): handle all SDK stream messages; stop spurious work-log warning rows (pingdotgg#4244)

Co-authored-by: Claude Fable 5 <[email protected]>

* Sidebar v2 beta: flat thread list with a server-backed settled lifecycle (pingdotgg#4026)

Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: maria-rcks <[email protected]>

* fix(settings): validate the add-provider wizard step before advancing (pingdotgg#2813) (pingdotgg#3100)

Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: codex <[email protected]>

* fix(claude): isolate capability probe from user MCP servers (pingdotgg#4015)

Co-authored-by: codex <[email protected]>

* Preserve connecting status while a turn starts (pingdotgg#4101)

Co-authored-by: codex <[email protected]>

* fix(server): stop restoring stale OpenCode models (pingdotgg#4095)

Co-authored-by: codex <[email protected]>

* [codex] keep scoped package references as text (pingdotgg#4167)

Co-authored-by: codex <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>

* fix(web): default provider selection for users without Codex (pingdotgg#4117)

Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: codex <[email protected]>

* Unify temporary worktree branch naming (pingdotgg#4278)

* fix(web): use message-square icon for settled icon-less project threads in sidebar v2 (pingdotgg#4279)

* Stabilize sidebar settling animations (pingdotgg#4280)

* Restore Copy Link in chat link context menu (pingdotgg#4161)

Co-authored-by: Julius Marminge <[email protected]>

* fix(desktop): handle EPIPE errors on stdout/stderr to prevent crash dialog (pingdotgg#4213)

* Preserve draft thread highlighting during promotion (pingdotgg#4283)

Co-authored-by: codex <[email protected]>

* Move mobile working timer into the thread timeline (pingdotgg#4285)

* Stabilize PR status lookups and provider session lifecycle (pingdotgg#4281)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix: open command palette instead of custom dialog for new thread picker in SidebarV2 (pingdotgg#4269)

* fix(server): don't drop sticky PR fallback when remote URL can't be resolved (pingdotgg#4289)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(web): copy branch name via right-click in the branch selector (pingdotgg#4275)

Co-authored-by: Claude Fable 5 <[email protected]>

* Add remote server updates and standalone service management (pingdotgg#4286)

Co-authored-by: codex <[email protected]>

* Refine light-mode sidebar surfaces (pingdotgg#4268)

Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: codex <[email protected]>

* fix(mobile): don't mark Android VPN/Tailscale as offline when connected (pingdotgg#3949)

* improve and prevent silent thread branch drift and PR fetching (pingdotgg#2284)

Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: codex <[email protected]>

* feat(web): refresh application surfaces

* style(web): polish dark mode dialogs

* fix(web): unify and tune glass surfaces

Co-authored-by: codex <[email protected]>

* fix(web): apply glass opacity to thread tooltip

* fix(web): override thread tooltip background

* fix(web): apply glass opacity to model picker

* style(web): polish glass opacity slider

* fix(web): apply glass opacity to command palette

* fix(web): add glass composer alerts

* fix(web): honor composer glass opacity

* test(web): stabilize timeline module setup

* style(web): fade settings content beneath navbar

* test(desktop): include glass opacity in settings fixture

* fix(web): address redesign review findings

* fix(web): sync provider banner dismissal

* fix(web): new-thread defaults ignored for remote environments (pingdotgg#4276)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat: add "Auto" runtime mode — AI-reviewed approvals for Codex and Claude (pingdotgg#4272)

Co-authored-by: Claude Fable 5 <[email protected]>

* Add shared t3.json project configuration support (pingdotgg#4317)

* Restore light-mode surfaces and refine dialog styling

- Restore light-mode glass, dialog, dropdown, and composer colors
- Refine provider wizard, changed-file cards, sidebar controls, and buttons
- Update wizard step tests for the new list structure

* Unify dialog glass and fix composer overlays (pingdotgg#4365)

Co-authored-by: codex <[email protected]>

* fix(web): warn before silent Windows updates (pingdotgg#4350)

* [codex] Move project grouping to General settings (pingdotgg#4313)

Co-authored-by: codex <[email protected]>

* [codex] Group project scopes in mobile thread lists (pingdotgg#4314)

Co-authored-by: codex <[email protected]>

* [codex] Move mobile project grouping to General settings (pingdotgg#4315)

Co-authored-by: codex <[email protected]>

* [codex] Deduplicate connection failure messaging (pingdotgg#4367)

Co-authored-by: codex <[email protected]>

* Restore grouped project filtering in Sidebar V2 (pingdotgg#4282)

Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: codex <[email protected]>

* [codex] restore Sidebar V2 project actions (pingdotgg#4373)

Co-authored-by: codex <[email protected]>

* [codex] Group projects in new-thread pickers (pingdotgg#4312)

Co-authored-by: codex <[email protected]>

* fix(web): restore dark composer toolbar styling

* Fix thread tooltip folder icon color (pingdotgg#4383)

* fix(server): parse CLI version in update preflight (pingdotgg#4389)

* fix(web): sidebar v2 polish — jump hints, working duration, in-flight fade, settled sort (pingdotgg#4274)

Co-authored-by: Claude Fable 5 <[email protected]>

* Fix logical project grouping labels on mobile (pingdotgg#4391)

Co-authored-by: codex <[email protected]>

* Add preview color scheme controls and simplify project grouping (pingdotgg#4385)

Co-authored-by: codex <[email protected]>
Co-authored-by: Claude Fable 5 <[email protected]>

* fix(cli): publish nightly branded favicons (pingdotgg#4372)

* Fix thread loading flash (pingdotgg#4396)

* fix(client-runtime): keep a warm thread un-settled despite a merged/closed PR (pingdotgg#4309)

Co-authored-by: Claude Fable 5 <[email protected]>

* Fix composer context strip alignment and glass shell (pingdotgg#4404)

* Polish iOS git progress overlay with glass effects (pingdotgg#4387)

* Improve composer glass fallbacks (pingdotgg#4406)

Co-authored-by: codex <[email protected]>

* feat(web): collapse large git diffs by default to make chat more readable (pingdotgg#4409)

* Stop new threads inheriting checkout/branch from viewed thread (pingdotgg#4411)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix: tone down branch-mismatch banner (pingdotgg#4416)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix: Claude Code skills discoverable for the composer $ picker (pingdotgg#4414)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): keep settled threads reachable when opened directly (pingdotgg#4413)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(sidebar-v2): thread snoozing (pingdotgg#4311)

Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: maria <[email protected]>

* Upgrade Clerk packages and Expo integration (pingdotgg#4440)

* Increase light-mode contrast for user message bubbles (pingdotgg#4441)

* Restore model picker layout and retain iterative test state (pingdotgg#4450)

Co-authored-by: codex <[email protected]>

* Color settled PR labels on hover (pingdotgg#4451)

Co-authored-by: codex <[email protected]>

* [codex] Fix glass hover compositing artifacts (pingdotgg#4446)

Co-authored-by: codex <[email protected]>

* Add Claude Opus 5 model (pingdotgg#4472)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
Co-authored-by: Theo Browne <[email protected]>

* feat(web): add collapse-all toggle to diff panel (pingdotgg#4475)

* feat(web): show fast mode as a bolt instead of a "Normal" label (pingdotgg#4488)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* feat(dev): keep worktree dev state isolated on T3 Code dev servers (pingdotgg#4555)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* feat(dev): Make t3 code dev instances shareable over Tailscale (pingdotgg#4556)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* fix(dev): skip browser-blocked ports (pingdotgg#4608)

* fix: cut websocket throughput in half by pruning activity payloads (pingdotgg#4622)

* perf(mobile): defer work-log detail serialization (pingdotgg#4607)

* test: account for lazy thread feed details (pingdotgg#4628)

* feat(relay): limit managed tunnels per user (pingdotgg#4530)

Co-authored-by: Claude Fable 5 <[email protected]>

* Add managed tunnel limits migration (pingdotgg#4635)

* Add background preview capture and picture-in-picture support (pingdotgg#4397)

Co-authored-by: codex <[email protected]>

* feat(web): prompt stash — cmd+S saves the composer to a per-provider queue (pingdotgg#4453)

Co-authored-by: Claude Fable 5 <[email protected]>

* Upgrade Effect and Alchemy betas (pingdotgg#4643)

Prepare Relay production infrastructure for the PlanetScale PS_20 HA topology, upgrade Effect and Alchemy to compatible betas, reconcile migration state, and preserve patched MCP session termination behavior.\n\nCo-authored-by: codex <[email protected]>

* feat: allow new thread creation through project breadcrumbs (pingdotgg#4638)

* fix(web): scope PR state to the thread branch (pingdotgg#4460)

Co-authored-by: codex <[email protected]>

* Drop redundant Relay user indexes (pingdotgg#4648)

Co-authored-by: codex <[email protected]>

* feat(connect): release the Cloudflare tunnel when the environment shuts down (pingdotgg#4531)

Co-authored-by: Claude Fable 5 <[email protected]>

* Fix Relay Worker RuntimeContext wiring (pingdotgg#4653)

Co-authored-by: codex <[email protected]>

* Fix live sidebar resize limits and defer Alchemy runtime context (pingdotgg#4655)

* fix(web): constrain branch toolbar context (pingdotgg#4657)

* Keep MCP credentials alive across provider turns (pingdotgg#4659)

* fix: close actions dropdown when editing (pingdotgg#4660)

* fix(preview): stabilize PiP viewport identity (pingdotgg#4661)

Co-authored-by: codex <[email protected]>

* Add glass styling for thread tooltips and simplify preview tab handling (pingdotgg#4665)

* Use tarball archiving for hosted web deploys (pingdotgg#4669)

* fix(server): bound editor discovery during config loading (pingdotgg#4291)

* Prevent draft thread detail polling before shell registration (pingdotgg#4670)

Co-authored-by: codex <[email protected]>

* feat: add configurable source control writing settings (pingdotgg#4204)

Co-authored-by: Claude <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: codex <[email protected]>

* feat(diff-panel): show total line additions and deletions (pingdotgg#4674)

* Clear provider update actions while updating (pingdotgg#4676)

* Fix sidebar highlighting for draft threads (pingdotgg#4679)

* Use glass surfaces for web toasts (pingdotgg#4681)

* Show origin ref in branch trigger label (pingdotgg#4680)

Co-authored-by: codex <[email protected]>

* fix(mobile): match react version to react-native 0.85.3 vendored renderer (19.2.3) (pingdotgg#4675)

* chore(release): prepare v0.0.29

* Add OTA update checks to mobile settings (pingdotgg#4686)

* fix(mobile): threads load snapped to bottom on iOS (pingdotgg#4689)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat: default sidebar v2 on for nightly and dev builds (pingdotgg#4491)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* fix(web): 33 web UI fixes (pingdotgg#4700)

* Make mobile Thread List v2 the default (pingdotgg#4717)

* Fix mobile showcase workflow without Clerk (pingdotgg#4718)

* Fix relay credential lookup for unlinked environments (pingdotgg#4692)

Co-authored-by: codex <[email protected]>

* Settle merged PR threads immediately (pingdotgg#4704)

* feat(web): add maria's sidebar header artwork toggle (pingdotgg#4652)

* feat(web): add appearance settings category (pingdotgg#4715)

* fix(desktop): allow updater-controlled relaunch (pingdotgg#4721)

* fix(web): prevent diff panel scroll jumping (pingdotgg#4724)

* Link inline code file paths in chat markdown (pingdotgg#4726)

Co-authored-by: Claude Fable 5 <[email protected]>

* Fix Android showcase capture and rebuild v2 queued rows (pingdotgg#4730)

Co-authored-by: Claude <[email protected]>

* perf(server): negotiate permessage-deflate on the websocket (pingdotgg#4705)

Co-authored-by: Claude Fable 5 <[email protected]>

* docs: overhaul agent guidance (pingdotgg#4782)

* Prevent sidebar row labels from truncating (pingdotgg#4789)

* perf(server): gzip large thread snapshots (pingdotgg#4788)

* fix(web): stashed prompts now survive switching providers (pingdotgg#4787)

Co-authored-by: Claude Fable 5 <[email protected]>

* Fix Git ref refresh resource storms (pingdotgg#4727)

Co-authored-by: codex <[email protected]>

* perf(server): trim stale context-window rows and drop dead replay RPC (pingdotgg#4791)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): defer command palette filesystem navigation (pingdotgg#2109)

Co-authored-by: codex <[email protected]>

* fix(release): skip scripts during Vercel installs (pingdotgg#4796)

* refactor(client): share filesystem browse navigation (pingdotgg#4797)

Co-authored-by: codex <[email protected]>

* fix(mobile): defer filesystem navigation (pingdotgg#4799)

Co-authored-by: codex <[email protected]>

* refactor(server): use native HTTP compression streams (pingdotgg#4798)

Co-authored-by: codex <[email protected]>

* Remove Connect waitlist and add GA announcement tooling (pingdotgg#4691)

* Fix Connect sign-in settings label (pingdotgg#4806)

* chore(release): prepare v0.0.30

* fix(desktop): restore T3 Connect sign-in (pingdotgg#4809)

Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: Claude Fable 5 <[email protected]>

* Simplify files panel header (pingdotgg#4828)

* build(desktop): reduce installed app size by ~300MB (pingdotgg#4824)

* Update model version from claude-opus-4-8 to claude-opus-5 (pingdotgg#4832)

* Preserve the thread shell while detail loads (pingdotgg#4830)

* Reduce idle work and disk churn with native resource diagnostics (pingdotgg#2679)

Co-authored-by: codex <[email protected]>

* fix(server): detect repositories after initialization (pingdotgg#4848)

* perf(server): merge separate staged/unstaged numstat calls into single diff HEAD --numstat (pingdotgg#4843)

* fix(git): disable external diff for review diff previews (pingdotgg#4854)

* Fix editable file focus and live syntax highlighting (pingdotgg#3979)

* fix(web): remember the rendered-markdown choice across threads (pingdotgg#4853)

Co-authored-by: Simon Doba <[email protected]>
Co-authored-by: Claude Opus 5 <[email protected]>

* chore(release): prepare v0.0.31

* fix(mobile): reduce thread feed scroll jank (pingdotgg#4874)

* fix(web): restore sidebar v2 thread actions and terminal icon (pingdotgg#4712)

* fix(web): settle button now works on hover, not just right-click (pingdotgg#4905)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(clients): disable add project while disconnected (pingdotgg#4834)

* fix(composer): hide default Codex service tier (pingdotgg#4784)

* docs: link iOS and Android app store downloads (pingdotgg#4902)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): align remote server update action (pingdotgg#4731)

* fix(connect): suggest a serve command that matches how you ran connect (pingdotgg#4897)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(mobile): stop shared content errors in Personal Team builds (pingdotgg#4943)

* perf(mobile): sends respond instantly, thread opens stop freezing (pingdotgg#4882)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): show Codex fast mode as a bolt (pingdotgg#4947)

* docs: seed worktrees with a copy of real userdata instead of banning it (pingdotgg#4949)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(mobile): support dragged images in the composer (pingdotgg#4953)

* fix(mobile): stop long iOS threads from jumping while scrolling up (pingdotgg#4867)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): keep worktree default when switching a draft's machine (pingdotgg#4964)

Co-authored-by: Claude Fable 5 <[email protected]>

* perf(mobile): reconnect environments immediately on resume (pingdotgg#4878)

* feat(web): pasting a huge screenshot now compresses it instead of erroring (pingdotgg#4967)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(web): regenerate thread titles from sidebar (pingdotgg#4810)

* fix(web): show server update progress through reconnect (pingdotgg#4903)

* feat(search): find threads by conversation content (pingdotgg#4959)

* fix: marketing site Vercel builds no longer die after ~100 deploys (pingdotgg#4975)

Co-authored-by: Claude Fable 5 <[email protected]>

* docs: split user and maintainer docs, fix 100+ stale claims (pingdotgg#4807)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): server updates no longer look like warnings (pingdotgg#4992)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(connect): reboots no longer strand the relay link, 403s now say why (pingdotgg#4988)

Co-authored-by: Claude Fable 5 <[email protected]>

* Add project file picker (⌘P) and project content search (⇧⌘F) (pingdotgg#4855)

Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>

* Check for mobile app updates on launch (pingdotgg#4958)

Co-authored-by: codex <[email protected]>

* fix(mobile): support pre-Liquid-Glass iOS bottom toolbar (pingdotgg#4984)

* fix(server): restore PR detection without HOME (pingdotgg#4985)

* fix(web): fill fast mode icon (pingdotgg#5004)

* fix: cache project favicons across web and mobile (pingdotgg#4767)

* perf(ci): cut stale runs and redundant setup (pingdotgg#4802)

* chore(mobile): bump app version to 1.0.1

Co-Authored-By: Claude Fable 5 <[email protected]>

* style(web): make scroll-to-end pill translucent (pingdotgg#5036)

* fix(ci): drop sparse-checkout from EAS workflows

actions/checkout implements sparse-checkout with --filter=blob:none, so
the runner repo is a partial clone missing the .repos/ blobs. eas-cli
archives the project via `git clone --depth 1 file://<workspace>`,
which upload-pack cannot serve from a partial clone and exits 128
(pingdotgg#4802 broke both EAS build workflows this way).

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(desktop): bump Clerk Electron SDK to 0.0.24 and register t3code:// scheme on Linux (pingdotgg#5015)

Co-authored-by: Claude Fable 5 <[email protected]>

* perf(server): cache default branch name and origin existence across status refreshes (pingdotgg#5008)

* feat(shared): support shorthand (major-only) versions in the semver helpers (pingdotgg#5027)

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>

* fix(mobile): remove unnecessary photo library permission (pingdotgg#4929)

* fix(shared): lenient JSON parser deletes commas inside string values (pingdotgg#5025)

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>

* fix(mobile): default bare IP pairing to HTTP (pingdotgg#4990)

* fix(mobile): restore iOS Threads branding (pingdotgg#4862)

* chore: add mobile issue template area (pingdotgg#4895)

* fix(desktop): link release notes from the update downloaded toast (pingdotgg#4771)

Co-authored-by: Claude Opus 5 <[email protected]>

* fix(mobile): accept Android clipboard images in composer (pingdotgg#4836)

* fix(mobile): show the correct build channel in Android's Threads page header (pingdotgg#4861)

* fix(contracts): decode growing config unions forward-compatibly (pingdotgg#5055)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(mobile): server model, worktree, and origin preferences now apply to new tasks (pingdotgg#5064)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(ci): repair the mobile showcase screenshots workflow (pingdotgg#5057)

* fix(ci): capture iPad App Store screenshots in landscape (pingdotgg#5065)

* fix(oxlint-plugin): Resolve the oxlint bin without assuming a pnpm layout (pingdotgg#5066)

* feat(cli): `npx t3 pair` - generate QR code from a running server (pingdotgg#4955)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(server): self-update no longer rolls itself back on restart (pingdotgg#5095)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(ci): rotate iPad showcase captures without Simulator UI scripting (pingdotgg#5094)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(web): render terminals with libghostty-vt (pingdotgg#4860)

Co-authored-by: Claude Fable 5 <[email protected]>

* refactor: move the canonical libghostty-vt vendor to the repository root (pingdotgg#5102)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(mobile): add thread snoozing (pingdotgg#5053)

* feat(mobile): make settled threads collapsible (pingdotgg#5056)

* follow-up normalization after pingdotgg#4700. (pingdotgg#4498)

Co-authored-by: T3 Code Test <[email protected]>

* feat(web): search threads from the sidebar (pingdotgg#4769)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(release): prepare Command Center desktop v1

* fix(ci): allow public release publisher identity

* fix(web): avoid Windows preview path collision

* test(release): reject Windows module path collisions

* fix(release): bundle command center core

* fix: audit preserved upstream history safely

* feat(providers): add Kimi, subagents, and usage analytics

* fix(ci): repair reconnects and PNG safety scanning

* test(desktop): update Clerk environment fixture

* fix(ci): align provider and server integration contracts

* perf(web): skip impossible image encodings

* fix command center chats on native desktop hosts

---------

Signed-off-by: Yordis Prieto <[email protected]>
Co-authored-by: Tristan Knight <[email protected]>
Co-authored-by: Christoph Herzog <[email protected]>
Co-authored-by: Andrew Barnes <[email protected]>
Co-authored-by: Shoaib <[email protected]>
Co-authored-by: Shoaib Ansari <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: Guilherme Vieira <[email protected]>
Co-authored-by: James <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: root <[email protected]>
Co-authored-by: Andrew Forster <[email protected]>
Co-authored-by: codex <[email protected]>
Co-authored-by: Chris Michael Guzman <[email protected]>
Co-authored-by: Vadym Kotai <[email protected]>
Co-authored-by: Utkarsh Patil <[email protected]>
Co-authored-by: xxashxx-svg <[email protected]>
Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: Maxwell Young <[email protected]>
Co-authored-by: Yordis Prieto <[email protected]>
Co-authored-by: Rhiz3K <[email protected]>
Co-authored-by: Rhiz3K <[email protected]>
Co-authored-by: Anirudh Coontoor <[email protected]>
Co-authored-by: Rusiru Sadathana <[email protected]>
Co-authored-by: ss <[email protected]>
Co-authored-by: Theo Browne <[email protected]>
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Leonel Rivas <[email protected]>
Co-authored-by: Jaret Bottoms <[email protected]>
Co-authored-by: Ishan <[email protected]>
Co-authored-by: Yukun Shan <[email protected]>
Co-authored-by: Miklós Fazekas <[email protected]>
Co-authored-by: Henry Zhang <[email protected]>
Co-authored-by: Rushikesh Gaikwad <[email protected]>
Co-authored-by: legs <[email protected]>
Co-authored-by: shivam <[email protected]>
Co-authored-by: tomlit <[email protected]>
Co-authored-by: jan <[email protected]>
Co-authored-by: Alex Southwell <[email protected]>
Co-authored-by: Max Katz <[email protected]>
Co-authored-by: Krzysztof Moch <[email protected]>
Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com>
Co-authored-by: Alex <[email protected]>
Co-authored-by: wukko <[email protected]>
Co-authored-by: Wout Stiens <[email protected]>
Co-authored-by: ohbentos <[email protected]>
Co-authored-by: Jake Leventhal <[email protected]>
Co-authored-by: Simon Doba <[email protected]>
Co-authored-by: Simon Doba <[email protected]>
Co-authored-by: Gabriel De Andrade <[email protected]>
Co-authored-by: Jono Kemball <[email protected]>
Co-authored-by: Arham Amin <[email protected]>
Co-authored-by: Elaine Lyons <[email protected]>
Co-authored-by: Simone <[email protected]>
Co-authored-by: Max Anderson <[email protected]>
Co-authored-by: Aditya Vardhan Sharma <[email protected]>
Co-authored-by: Mike Olson <[email protected]>
Co-authored-by: T3 Code Test <[email protected]>
Co-authored-by: atryan <[email protected]>
aorwall added a commit to aorwall/t3code that referenced this pull request Aug 2, 2026
Brings in 81 upstream commits (up to v0.0.31, "fix(web): align remote
server update action" pingdotgg#4731). One file conflicted: apps/web/vite.config.ts.

Upstream independently shipped single-origin browser dev (pingdotgg#4555/pingdotgg#4556/pingdotgg#4608
— Tailscale sharing, isolated worktree dev state, browser-blocked port
avoidance), which covers the same ground as this fork's proxy-origin work in
pingdotgg#3. The conflict is resolved by taking upstream's implementation wholesale and
re-applying only what is genuinely fork-specific on top:

- T3CODE_DEV_PROXY_TARGET / T3CODE_PROXY_TARGET_OVERRIDE / T3CODE_PROXY_TARGET
  / MOATLESS_BASE_URL still select the proxy target, and now take precedence
  over upstream's T3CODE_PORT-derived default, which the dev runner always
  sets. Naming a target also implies single-origin mode, so VITE_HTTP_URL and
  VITE_WS_URL stay blank and the browser resolves the backend from its own
  origin.
- VITE_MOATLESS_PROXY_AUTH is still defined for environments/primary/auth.ts.
- T3CODE_ALLOWED_HOSTS is kept as an alias of upstream's new
  T3CODE_DEV_ALLOWED_HOSTS (deployments inject the former), along with the
  `true` escape hatch. Upstream's implicit .ts.net entry is preserved.
- The NODE_ENV=production pin for `vite serve` is kept; hosted sandboxes still
  export it process-wide.

Dropped as superseded:

- T3CODE_HMR_HOST and its dev-runner plumbing. Upstream now deletes an
  inherited HOST for every non-desktop mode and gates the HMR pin on
  `explicitHost`, which is the same fix with upstream's own tests
  (scripts/dev-runner.test.ts "drops an inherited HOST in <mode> mode").
  scripts/dev-runner.ts and its test now match upstream exactly.
- The separate /attachments proxy entry. Prefixes now come from
  packages/shared/src/devProxy.ts, and attachments moved under
  /api/assets (ASSET_ROUTE_PREFIX), which /api already covers.

Verified: pnpm typecheck clean across all 15 projects; pnpm test green
(apps/web 1673, scripts 197, full monorepo suite otherwise passing — one
load-induced 15s timeout in the upstream-owned
src/lib/stashImageCompression.test.ts, which passes in isolation);
pnpm lint exit 0; pnpm fmt:check clean.

Co-Authored-By: Claude Opus 5 <[email protected]>
awtprod added a commit to awtprod/t3-code that referenced this pull request Aug 8, 2026
* feat(web): add collapse-all toggle to diff panel (pingdotgg#4475)

* feat(web): show fast mode as a bolt instead of a "Normal" label (pingdotgg#4488)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* feat(dev): keep worktree dev state isolated on T3 Code dev servers (pingdotgg#4555)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* feat(dev): Make t3 code dev instances shareable over Tailscale (pingdotgg#4556)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* fix(dev): skip browser-blocked ports (pingdotgg#4608)

* fix: cut websocket throughput in half by pruning activity payloads (pingdotgg#4622)

* perf(mobile): defer work-log detail serialization (pingdotgg#4607)

* test: account for lazy thread feed details (pingdotgg#4628)

* feat(relay): limit managed tunnels per user (pingdotgg#4530)

Co-authored-by: Claude Fable 5 <[email protected]>

* Add managed tunnel limits migration (pingdotgg#4635)

* Add background preview capture and picture-in-picture support (pingdotgg#4397)

Co-authored-by: codex <[email protected]>

* feat(web): prompt stash — cmd+S saves the composer to a per-provider queue (pingdotgg#4453)

Co-authored-by: Claude Fable 5 <[email protected]>

* Upgrade Effect and Alchemy betas (pingdotgg#4643)

Prepare Relay production infrastructure for the PlanetScale PS_20 HA topology, upgrade Effect and Alchemy to compatible betas, reconcile migration state, and preserve patched MCP session termination behavior.\n\nCo-authored-by: codex <[email protected]>

* feat: allow new thread creation through project breadcrumbs (pingdotgg#4638)

* fix(web): scope PR state to the thread branch (pingdotgg#4460)

Co-authored-by: codex <[email protected]>

* Drop redundant Relay user indexes (pingdotgg#4648)

Co-authored-by: codex <[email protected]>

* feat(connect): release the Cloudflare tunnel when the environment shuts down (pingdotgg#4531)

Co-authored-by: Claude Fable 5 <[email protected]>

* Fix Relay Worker RuntimeContext wiring (pingdotgg#4653)

Co-authored-by: codex <[email protected]>

* Fix live sidebar resize limits and defer Alchemy runtime context (pingdotgg#4655)

* fix(web): constrain branch toolbar context (pingdotgg#4657)

* Keep MCP credentials alive across provider turns (pingdotgg#4659)

* fix: close actions dropdown when editing (pingdotgg#4660)

* fix(preview): stabilize PiP viewport identity (pingdotgg#4661)

Co-authored-by: codex <[email protected]>

* Add glass styling for thread tooltips and simplify preview tab handling (pingdotgg#4665)

* Use tarball archiving for hosted web deploys (pingdotgg#4669)

* fix(server): bound editor discovery during config loading (pingdotgg#4291)

* Prevent draft thread detail polling before shell registration (pingdotgg#4670)

Co-authored-by: codex <[email protected]>

* feat: add configurable source control writing settings (pingdotgg#4204)

Co-authored-by: Claude <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: codex <[email protected]>

* feat(diff-panel): show total line additions and deletions (pingdotgg#4674)

* Clear provider update actions while updating (pingdotgg#4676)

* Fix sidebar highlighting for draft threads (pingdotgg#4679)

* Use glass surfaces for web toasts (pingdotgg#4681)

* Show origin ref in branch trigger label (pingdotgg#4680)

Co-authored-by: codex <[email protected]>

* fix(mobile): match react version to react-native 0.85.3 vendored renderer (19.2.3) (pingdotgg#4675)

* chore(release): prepare v0.0.29

* Add OTA update checks to mobile settings (pingdotgg#4686)

* fix(mobile): threads load snapped to bottom on iOS (pingdotgg#4689)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat: default sidebar v2 on for nightly and dev builds (pingdotgg#4491)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* fix(web): 33 web UI fixes (pingdotgg#4700)

* Make mobile Thread List v2 the default (pingdotgg#4717)

* Fix mobile showcase workflow without Clerk (pingdotgg#4718)

* Fix relay credential lookup for unlinked environments (pingdotgg#4692)

Co-authored-by: codex <[email protected]>

* Settle merged PR threads immediately (pingdotgg#4704)

* feat(web): add maria's sidebar header artwork toggle (pingdotgg#4652)

* feat(web): add appearance settings category (pingdotgg#4715)

* fix(desktop): allow updater-controlled relaunch (pingdotgg#4721)

* fix(web): prevent diff panel scroll jumping (pingdotgg#4724)

* Link inline code file paths in chat markdown (pingdotgg#4726)

Co-authored-by: Claude Fable 5 <[email protected]>

* Fix Android showcase capture and rebuild v2 queued rows (pingdotgg#4730)

Co-authored-by: Claude <[email protected]>

* perf(server): negotiate permessage-deflate on the websocket (pingdotgg#4705)

Co-authored-by: Claude Fable 5 <[email protected]>

* docs: overhaul agent guidance (pingdotgg#4782)

* Prevent sidebar row labels from truncating (pingdotgg#4789)

* perf(server): gzip large thread snapshots (pingdotgg#4788)

* fix(web): stashed prompts now survive switching providers (pingdotgg#4787)

Co-authored-by: Claude Fable 5 <[email protected]>

* Fix Git ref refresh resource storms (pingdotgg#4727)

Co-authored-by: codex <[email protected]>

* perf(server): trim stale context-window rows and drop dead replay RPC (pingdotgg#4791)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): defer command palette filesystem navigation (pingdotgg#2109)

Co-authored-by: codex <[email protected]>

* fix(release): skip scripts during Vercel installs (pingdotgg#4796)

* refactor(client): share filesystem browse navigation (pingdotgg#4797)

Co-authored-by: codex <[email protected]>

* fix(mobile): defer filesystem navigation (pingdotgg#4799)

Co-authored-by: codex <[email protected]>

* refactor(server): use native HTTP compression streams (pingdotgg#4798)

Co-authored-by: codex <[email protected]>

* Remove Connect waitlist and add GA announcement tooling (pingdotgg#4691)

* Fix Connect sign-in settings label (pingdotgg#4806)

* chore(release): prepare v0.0.30

* fix(desktop): restore T3 Connect sign-in (pingdotgg#4809)

Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: Claude Fable 5 <[email protected]>

* Simplify files panel header (pingdotgg#4828)

* build(desktop): reduce installed app size by ~300MB (pingdotgg#4824)

* Update model version from claude-opus-4-8 to claude-opus-5 (pingdotgg#4832)

* Preserve the thread shell while detail loads (pingdotgg#4830)

* Reduce idle work and disk churn with native resource diagnostics (pingdotgg#2679)

Co-authored-by: codex <[email protected]>

* fix(server): detect repositories after initialization (pingdotgg#4848)

* perf(server): merge separate staged/unstaged numstat calls into single diff HEAD --numstat (pingdotgg#4843)

* fix(git): disable external diff for review diff previews (pingdotgg#4854)

* Fix editable file focus and live syntax highlighting (pingdotgg#3979)

* fix(web): remember the rendered-markdown choice across threads (pingdotgg#4853)

Co-authored-by: Simon Doba <[email protected]>
Co-authored-by: Claude Opus 5 <[email protected]>

* chore(release): prepare v0.0.31

* fix(mobile): reduce thread feed scroll jank (pingdotgg#4874)

* fix(web): restore sidebar v2 thread actions and terminal icon (pingdotgg#4712)

* fix(web): settle button now works on hover, not just right-click (pingdotgg#4905)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(clients): disable add project while disconnected (pingdotgg#4834)

* fix(composer): hide default Codex service tier (pingdotgg#4784)

* docs: link iOS and Android app store downloads (pingdotgg#4902)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): align remote server update action (pingdotgg#4731)

* fix(connect): suggest a serve command that matches how you ran connect (pingdotgg#4897)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(mobile): stop shared content errors in Personal Team builds (pingdotgg#4943)

* perf(mobile): sends respond instantly, thread opens stop freezing (pingdotgg#4882)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): show Codex fast mode as a bolt (pingdotgg#4947)

* docs: seed worktrees with a copy of real userdata instead of banning it (pingdotgg#4949)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(mobile): support dragged images in the composer (pingdotgg#4953)

* fix(mobile): stop long iOS threads from jumping while scrolling up (pingdotgg#4867)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): keep worktree default when switching a draft's machine (pingdotgg#4964)

Co-authored-by: Claude Fable 5 <[email protected]>

* perf(mobile): reconnect environments immediately on resume (pingdotgg#4878)

* feat(web): pasting a huge screenshot now compresses it instead of erroring (pingdotgg#4967)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(web): regenerate thread titles from sidebar (pingdotgg#4810)

* fix(web): show server update progress through reconnect (pingdotgg#4903)

* feat(search): find threads by conversation content (pingdotgg#4959)

* fix: marketing site Vercel builds no longer die after ~100 deploys (pingdotgg#4975)

Co-authored-by: Claude Fable 5 <[email protected]>

* docs: split user and maintainer docs, fix 100+ stale claims (pingdotgg#4807)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): server updates no longer look like warnings (pingdotgg#4992)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(connect): reboots no longer strand the relay link, 403s now say why (pingdotgg#4988)

Co-authored-by: Claude Fable 5 <[email protected]>

* Add project file picker (⌘P) and project content search (⇧⌘F) (pingdotgg#4855)

Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>

* Check for mobile app updates on launch (pingdotgg#4958)

Co-authored-by: codex <[email protected]>

* fix(mobile): support pre-Liquid-Glass iOS bottom toolbar (pingdotgg#4984)

* fix(server): restore PR detection without HOME (pingdotgg#4985)

* fix(web): fill fast mode icon (pingdotgg#5004)

* fix: cache project favicons across web and mobile (pingdotgg#4767)

* perf(ci): cut stale runs and redundant setup (pingdotgg#4802)

* chore(mobile): bump app version to 1.0.1

Co-Authored-By: Claude Fable 5 <[email protected]>

* style(web): make scroll-to-end pill translucent (pingdotgg#5036)

* fix(ci): drop sparse-checkout from EAS workflows

actions/checkout implements sparse-checkout with --filter=blob:none, so
the runner repo is a partial clone missing the .repos/ blobs. eas-cli
archives the project via `git clone --depth 1 file://<workspace>`,
which upload-pack cannot serve from a partial clone and exits 128
(pingdotgg#4802 broke both EAS build workflows this way).

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(desktop): bump Clerk Electron SDK to 0.0.24 and register t3code:// scheme on Linux (pingdotgg#5015)

Co-authored-by: Claude Fable 5 <[email protected]>

* perf(server): cache default branch name and origin existence across status refreshes (pingdotgg#5008)

* feat(shared): support shorthand (major-only) versions in the semver helpers (pingdotgg#5027)

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>

* fix(mobile): remove unnecessary photo library permission (pingdotgg#4929)

* fix(shared): lenient JSON parser deletes commas inside string values (pingdotgg#5025)

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>

* fix(mobile): default bare IP pairing to HTTP (pingdotgg#4990)

* fix(mobile): restore iOS Threads branding (pingdotgg#4862)

* chore: add mobile issue template area (pingdotgg#4895)

* fix(desktop): link release notes from the update downloaded toast (pingdotgg#4771)

Co-authored-by: Claude Opus 5 <[email protected]>

* fix(mobile): accept Android clipboard images in composer (pingdotgg#4836)

* fix(mobile): show the correct build channel in Android's Threads page header (pingdotgg#4861)

* fix(contracts): decode growing config unions forward-compatibly (pingdotgg#5055)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(mobile): server model, worktree, and origin preferences now apply to new tasks (pingdotgg#5064)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(ci): repair the mobile showcase screenshots workflow (pingdotgg#5057)

* fix(ci): capture iPad App Store screenshots in landscape (pingdotgg#5065)

* fix(oxlint-plugin): Resolve the oxlint bin without assuming a pnpm layout (pingdotgg#5066)

* feat(cli): `npx t3 pair` - generate QR code from a running server (pingdotgg#4955)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(server): self-update no longer rolls itself back on restart (pingdotgg#5095)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(ci): rotate iPad showcase captures without Simulator UI scripting (pingdotgg#5094)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(web): render terminals with libghostty-vt (pingdotgg#4860)

Co-authored-by: Claude Fable 5 <[email protected]>

* refactor: move the canonical libghostty-vt vendor to the repository root (pingdotgg#5102)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(mobile): add thread snoozing (pingdotgg#5053)

* feat(mobile): make settled threads collapsible (pingdotgg#5056)

* follow-up normalization after pingdotgg#4700. (pingdotgg#4498)

Co-authored-by: T3 Code Test <[email protected]>

* feat(web): search threads from the sidebar (pingdotgg#4769)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(web): add settings sidebar search (pingdotgg#4682)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix: threads with open PRs no longer auto-settle (pingdotgg#5151)

* fix(server): bound thread catch-up replay and stop full-DB snapshot hydration (pingdotgg#5147)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(server): follow branch drift in dedicated worktrees so PRs link to their thread (pingdotgg#5159)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(server): make remote updates rollback-safe (pingdotgg#5181)

* fix(web): stop settle controls overlapping the status label (pingdotgg#4574)

* fix: normalize app icon glyph sizing (pingdotgg#5202)

Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com>

* fix(server): surface cloudflared FTL/PNC relay logs as warnings, not debug (pingdotgg#5076)

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>

* fix(server): stop npx service updates from silently leaving the old server running (pingdotgg#5217)

Co-authored-by: Claude <[email protected]>

* feat: fold legacy models into separate menus (pingdotgg#5190)

* fix(desktop): claim the t3code:// scheme default on Linux at startup (pingdotgg#5054)

* fix(web): polish interface spacing (pingdotgg#5252)

* fix(desktop): Niri/Hyprland - Linux secret storage backend (pingdotgg#2916)

Co-authored-by: Julius Marminge <[email protected]>

* fix(web): match loading screen to dark theme (pingdotgg#5303)

* fix(web): blink the terminal cursor again (pingdotgg#5314)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* fix(terminal): protect held Ctrl/Cmd+W close shortcut (pingdotgg#5322)

* fix(server): strip replayable terminal queries from history (pingdotgg#5319)

* fix(contracts): decode ServerProviders forward-compatibly (pingdotgg#5327)

Co-authored-by: Rodrigo Brechard <[email protected]>

* fix(web): simplify chat code blocks (pingdotgg#5301)

* fix(web): align multiline error alert controls (pingdotgg#5304)

* Upgrade Effect to beta.103 (pingdotgg#5331)

* fix(web): increase tooltip z-index to overlay popovers and menus (pingdotgg#5326)

* fix(server): use a Cursor todo's title when its content is blank (pingdotgg#5073)

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>

* fix(ssh): isolate managed tunnel processes (pingdotgg#4347)

* fix(server): scrub AppImage XDG_DATA_DIRS and GSETTINGS_SCHEMA_DIR from terminals (pingdotgg#5075)

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>

* fix(mobile): show correct provider icons for Grok, Cursor, and OpenCode (pingdotgg#4586)

* fix(web): stop the chat timeline reading through the provider status banner (pingdotgg#5353)

* fix(desktop,web): contain renderer memory growth and recover from renderer OOM crashes (pingdotgg#5148)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(server): generate durable thread titles (pingdotgg#5357)

* fix(web): better right panel (new diffs styling) (pingdotgg#5260)

* fix(server): keep regenerated titles on topic (pingdotgg#5365)

* refactor(server): make title prompts plaintext (pingdotgg#5368)

* feat(web): configurable fonts and sizes under Settings → Appearance (pingdotgg#5103)

Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>

* feat(sidebar-v2): thread pinning for sidebar v2 (pingdotgg#5312)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(web): make pairing QR codes actually scannable, with endpoint choice (pingdotgg#5360)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(desktop,web): improve in-app browser shortcuts and URL behavior (pingdotgg#4703)

* fix(web): prevent legacy model picker layout shift (pingdotgg#5349)

* fix(server): allow remote updates with database migrations (pingdotgg#5374)

* fix(mcp): unblock Kimi models in OpenCode with preview tools (pingdotgg#5128)

* fix(web): clear main branch lint warnings (pingdotgg#5384)

* fix(mobile): preserve grouped project workspaces (pingdotgg#4642)

Co-authored-by: T3 Code Test <[email protected]>

* fix(mobile): prevent Android thread search crash (pingdotgg#5386)

* fix(web): truncate long project switcher names (pingdotgg#5348)

* fix(mobile): avoid double dividers between thread sections (pingdotgg#5391)

Co-authored-by: T3 Code Test <[email protected]>

* fix(web): keep the composer command menu anchored to the composer (pingdotgg#5336)

* fix(web): restore terminal link hover styles (pingdotgg#5382)

* fix(ci): isolate releases from shared API rate limits (pingdotgg#5394)

* fix(web): keep model picker shortcuts in sync (pingdotgg#5400)

* fix(web): keep terminal font settings reliable (pingdotgg#5397)

* Enrich terminal font previews (pingdotgg#5428)

* fix(web): preserve terminal font size when splitting (pingdotgg#5444)

Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com>

* Prevent terminal loading flash (pingdotgg#5432)

* fix: reconnect faster after remote server updates (pingdotgg#5404)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat: native subagent & workflow observability (pingdotgg#5219)

Co-authored-by: Claude Fable 5 <[email protected]>

* perf(server): stop shipping full MCP tool results in thread payloads (pingdotgg#5482)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): closed plan sidebar stays closed when returning to a thread (pingdotgg#5484)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix: respect time format for sidebar snooze (pingdotgg#4438)

* fix(web): calm one-row server update status and banner

The version-skew banner is no longer an amber warning: it reads
"Server update available" with the raw versions (unreadable for
nightlies) moved to a tooltip. The in-flight rail (Download/Install/
Resume) becomes a single status row, "Downloading…" then
"Restarting…", since the wire installing stage is a sub-second
launcher handoff and "resuming" meant nothing to most people.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(server): keep the managed tunnel across remote update restarts

Measured on a live update: the server was back in ~9s but stayed
unreachable for ~96s, because releasing the tunnel on shutdown forces
the replacement tunnel's hostname route through 1-2 minutes of edge
propagation. An update handoff always brings a server right back
(new version or rollback), so the tunnel is never orphaned; skip the
release when the launcher state file records a pending update. The
next boot respawns the connector from the stored config against the
same tunnel and is reachable as soon as it connects.

Co-Authored-By: Claude Fable 5 <[email protected]>

* test(server): use the launcher state writer in release tests

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(server): release the tunnel when an explicit stop interrupts an update

A pending update in the launcher state is not proof a replacement
server is coming: `t3 service uninstall` or `systemctl stop` during
the pending window also tears the server down, permanently. The
launcher now writes a stop marker before signalling its child on an
explicit stop and clears it on the next start; the shutdown tunnel
release keeps the tunnel only for pending updates without the marker.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(server): clean up interrupted update trials

* fix(server): order explicit service shutdown

* fix(web): make update version tooltips accessible

* fix(server): separate trial cleanup from handoff retention

* fix(server): drop superseded tool updates from snapshots

A tool.updated row is the in-flight snapshot of a call; once the call
completes, the tool.completed row carries the final state and both
clients fold every matching update into it. Shipping the updates buys
nothing: 47k such rows exist in one real database, and a single thread
carries 3,291 of them.

Filter them out of thread snapshots, mirroring the existing
context-window dedup. Matching is per turn and only against a LATER
completion, so a revert that discards the completing turn cannot leave
a call unrepresented, and a later update under the same identity (the
next call, still in flight) survives. Live events are untouched.

Rows are matched on the same identity the clients collapse by: an
explicit data.toolCallId when the adapter emits one, otherwise the
itemType/title/detail triple. No tool lifecycle row in the real db
carries a toolCallId, so the fallback does the work.

Co-Authored-By: Claude Fable 5 <[email protected]>

* docs(server): pin interleaved-collapse divergence as intentional with test

Bugbot flagged that clients collapse only adjacent lifecycle rows, so
dropping a superseded update separated by an interleaved parallel call
diverges from full-history rendering. Measured on a real database: 1.5%
of dropped rows (553/36,581), all pure in-flight state whose final result
the retained completion still shows, and zero dropped rows carry a
client-merged payload field their completion lacks (verified across all
49,515 update rows). Documents the tradeoff and adds a test pinning it.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(web): clarify auto permission fallback (pingdotgg#5431)

Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com>

* fix(acp): keep unknown approvals actionable (pingdotgg#5430)

Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com>

* fix(mobile): stop thread messages reading through pending cards (pingdotgg#5450)

Co-authored-by: Claude Opus 5 <[email protected]>

* fix(web): align composer inline chips with prompt text (pingdotgg#5495)

* fix(web): clear woke state on explicit thread actions (pingdotgg#5486)

* fix(server): skip origin fetch when creating worktrees in repos without an origin remote (pingdotgg#5556)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): update tooltip no longer dismisses when scrolling release notes (pingdotgg#5547)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(server): stop showing commit/push/PR notices as errors in the work log (pingdotgg#5559)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): show remote environment for non-Git projects (pingdotgg#5555)

* fix(server): stopping a Claude thread no longer shows an ede_diagnostic error (pingdotgg#5557)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): show one toast when snoozing threads in bulk (pingdotgg#5560)

* fix(server): let stopped threads settle immediately (pingdotgg#5553)

* feat: paginate thread loading with user-anchored turn windows (pingdotgg#5493)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix: prevent reconnect loops during server stalls (pingdotgg#5561)

Co-authored-by: t3-turbo-simulation <[email protected]>
Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: Theo Browne <[email protected]>

* fix(server): settle stopped Claude subagents (pingdotgg#5568)

* fix: scrolling up during a running thread no longer snaps back to the bottom (pingdotgg#5566)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(server): one disconnecting client no longer blocks every reconnect (pingdotgg#5572)

Co-authored-by: Claude <[email protected]>

* test(server): catch client transfer regressions in CI (pingdotgg#5350)

* fix(web): stop the "requests are slow" warning from firing on every provider update (pingdotgg#5570)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* fix(web): keep agent panel rows stable (pingdotgg#5569)

* docs: ship production T3 Connect public config in .env.example (pingdotgg#5573)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): plans stop hijacking the UI, fold into chat instead (pingdotgg#5558)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(web): remove Build/Plan toggle from the composer (pingdotgg#5551)

Co-authored-by: Claude Fable 5 <[email protected]>

* feat(web): per-device provider settings (pingdotgg#4479)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* fix(mobile): invisible T3 Connect devices can now be seen and removed (pingdotgg#5563)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix: add missing space before 'GitHub releases page' link on download page (pingdotgg#4511)

* fix(web): stop the sidebar "Working" label from pulsing (pingdotgg#5580)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* feat(web): add modular theme library (pingdotgg#5226)

Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>

* fix(web): reading a thread clears Done; Woke is dismissible (pingdotgg#5579)

Co-authored-by: Claude Fable 5 <[email protected]>

* perf(dev): faster cold-start for dev web serving (pingdotgg#5584)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(dev): Improve instructions for --share (pingdotgg#5586)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(mobile): improve keyboard avoiding (pingdotgg#5451)

* fix(web): live background-work banner no longer hides behind the update notice (pingdotgg#5595)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(web): stabilize chat timeline positioning (pingdotgg#5449)

Co-authored-by: codex <[email protected]>

* feat(server): record runtime mode per turn and on mode changes (pingdotgg#5593)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* feat(web): thread actions from the chat header title (pingdotgg#5592)

Co-authored-by: Claude Fable 5 <[email protected]>

* fix(mobile): avoid iOS terminal reset on clear (pingdotgg#5440)

* fix(mobile): pad scroll views above Android nav bar (pingdotgg#5415)

* fix(mobile): keep Android chat text from showing through the composer (pingdotgg#5582)

* fix(mobile): repair Clerk auth navigation headers (pingdotgg#5140)

Co-authored-by: codex <[email protected]>

* Bump mobile app version to 1.0.2 (pingdotgg#5588)

* feat(web): click the pin icon to unpin a thread (pingdotgg#5578)

* fix(web): show the correctly matching shortcut in new thread button's tooltip (pingdotgg#5594)

* chore: advance public upstream baseline

* chore: advance upstream baseline to v0.0.32

* fix: align react native patch lock hash

---------

Co-authored-by: jan <[email protected]>
Co-authored-by: Theo Browne <[email protected]>
Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
Co-authored-by: Alex Southwell <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: codex <[email protected]>
Co-authored-by: Max Katz <[email protected]>
Co-authored-by: maria <[email protected]>
Co-authored-by: Krzysztof Moch <[email protected]>
Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com>
Co-authored-by: Alex <[email protected]>
Co-authored-by: wukko <[email protected]>
Co-authored-by: Wout Stiens <[email protected]>
Co-authored-by: Utkarsh Patil <[email protected]>
Co-authored-by: ohbentos <[email protected]>
Co-authored-by: Jake Leventhal <[email protected]>
Co-authored-by: Simon Doba <[email protected]>
Co-authored-by: Simon Doba <[email protected]>
Co-authored-by: Gabriel De Andrade <[email protected]>
Co-authored-by: Jono Kemball <[email protected]>
Co-authored-by: Arham Amin <[email protected]>
Co-authored-by: Elaine Lyons <[email protected]>
Co-authored-by: Simone <[email protected]>
Co-authored-by: Max Anderson <[email protected]>
Co-authored-by: Aditya Vardhan Sharma <[email protected]>
Co-authored-by: Mike Olson <[email protected]>
Co-authored-by: shivam <[email protected]>
Co-authored-by: T3 Code Test <[email protected]>
Co-authored-by: Illia Panasenko <[email protected]>
Co-authored-by: Rodrigo Brechard <[email protected]>
Co-authored-by: Rodrigo Brechard <[email protected]>
Co-authored-by: naMqe <[email protected]>
Co-authored-by: Yukun Shan <[email protected]>
Co-authored-by: Rushikesh Gaikwad <[email protected]>
Co-authored-by: Bilal Bakr <[email protected]>
Co-authored-by: Fllip <[email protected]>
Co-authored-by: Hwanseo Choi <[email protected]>
Co-authored-by: Hugo Blom <[email protected]>
Co-authored-by: Carlos Rico-Ospina <[email protected]>
Co-authored-by: Gabe Fletcher <[email protected]>
Co-authored-by: t3-turbo-simulation <[email protected]>
Co-authored-by: Mateleo <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: Jay Meistrich <[email protected]>
Co-authored-by: Justyn Leung <[email protected]>
Co-authored-by: Tyler Saari <[email protected]>
Co-authored-by: Pavlo Trinko <[email protected]>
Co-authored-by: atryan <[email protected]>
NeilTheFisher pushed a commit to NeilTheFisher/t3code that referenced this pull request Aug 18, 2026
darjss pushed a commit to darjss/t3code that referenced this pull request Aug 26, 2026
@t3dotgg t3dotgg mentioned this pull request Sep 6, 2026
2 of 4 tasks
HaukeSchnau added a commit to HaukeSchnau/t3code that referenced this pull request Oct 27, 2026
The fork-vs-upstream audit after the bfc7177 sync found upstream behavior the fork had dropped by accident, mostly where an older fork change won a merge. This restores it and fixes the patch docs that described the old state.

- Web dev HMR takes upstream's page-origin behavior (pingdotgg#4556) instead of pinning the socket to VITE_DEV_SERVER_URL, so LAN, tailnet and forwarded-port browsers get hot reload again. Agent-service and --dev-url origins are covered by origin derivation. The one fork exception: upstream's Electron HOST pin is skipped in single-origin browser dev, because devenv binds the listener with --web-host 127.0.0.1 behind the proxy.
- The provider event logger runs upstream's shouldPersistProviderEvent filter again (pingdotgg#12305), so canonical deltas, raw native frames and token deltas never reach the log; sampling now only applies to native events that pass it. An oversized metadata record keeps its identity fields clipped instead of dropping them. Restored upstream's concurrent-first-write and oversized-record tests, adapted to metadata-only records, plus a test for the filter.
- reconcileV2PreviewMigration can never fire on a fork database (fork ids 53/54 never held OrchestrationV2), so its test is one focused no-op check without the hardcoded migration list.
- Removed dead code upstream had deleted: reauthenticatePrimaryEnvironment, the desktop T3CODE_DESKTOP_PROTOCOL_* registration helper (the Clerk bridge registers the app scheme; t3code://open still dispatches), the unused Clerk passkey build exports, docs/internals/ci.md (fork CI notes moved to patches/fast-project-qa.md), and a pruned settings comment. The Clerk bridge and preload no longer enable passkeys, since no passkey binaries are staged.
- Mobile ends Live Activities once no paired environment remains, like upstream did on sign-out; remounts and environment list changes only release the transport.
- T3CODE_MOBILE_UPDATES_ENABLED=0 disables OTA updates again.
- Mobile README, mobile-distribution, fast-project-qa, jujutsu, fork-workflow, nix-flake-packaging, desktop docs and agent-service-dev-url no longer contradict the code.

Verified: focused server, mobile, desktop, contracts and scripts tests pass, and the new logger and Live Activity tests fail without the fix. vp run check:changed passes format, lint, typecheck and graphql. Its knip and combined test steps fail for reasons that predate this change (repo-wide unused exports and files; root vs server Vitest groupOrder clash).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:trusted 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