Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
3ae672f
fix(desktop): ask once per site before a preview page reads the clipb…
juliusmarminge Oct 27, 2026
294981f
fix(mobile): Windows paths in messages keep their backslashes (#21454)
juliusmarminge Oct 27, 2026
7e884b2
feat: triage an issue from the command palette, no terminal needed (#…
t3dotgg Oct 27, 2026
a846084
fix(server): Forgejo required-check globs no longer hang the event lo…
juliusmarminge Oct 27, 2026
735cc3c
fix(server): fx's version policy reaches servers with a cached model …
juliusmarminge Oct 27, 2026
c570c2c
fix(mobile): keep iPad tab bar within narrow sidebars (#26198)
juliusmarminge Oct 28, 2026
c38b265
feat(web): filter the sidebar by several projects at once (#25284)
maria-rcks Oct 28, 2026
0894156
fix(mobile): provider accounts fit each provider on one row (#25861)
saphid Oct 28, 2026
531cee6
fix(server): Claude background-task wakes start when the queue is hel…
fireboltdude1357 Oct 28, 2026
68495b6
docs(testing): new tests extend existing cases and stay at one layer …
t3dotgg Oct 28, 2026
06d4b57
fix(web): composer strip drops the folder icon next to the machine ic…
maria-rcks Oct 28, 2026
7e71392
feat(web): background work line shows the newest activity, no dots (#…
maria-rcks Oct 28, 2026
7f2dcd8
fix(mobile): dictation buttons line up with the send button on every …
juliusmarminge Oct 28, 2026
df4132b
chore(mobile): e2e runs keep Metro's output, the app's console logs, …
juliusmarminge Oct 28, 2026
2e2d86c
chore(mobile): e2e Metro serves no lazy chunks
juliusmarminge Oct 28, 2026
4ab7084
feat(web,mobile): the @ picker lists threads on linked machines (#26201)
juliusmarminge Oct 28, 2026
0affd28
feat(web,mobile): Copy thread copies a chip that works on linked mach…
juliusmarminge Oct 28, 2026
5cf49d2
fix(mobile): unclosed code fences in HTML blocks no longer freeze PR …
juliusmarminge Oct 28, 2026
b5af460
fix(opencode): apply runtime mode changes to existing OpenCode sessio…
juliusmarminge Oct 28, 2026
8251578
fix(server): Antigravity file writes cannot escape the workspace thro…
juliusmarminge Oct 28, 2026
7a059b9
chore(mobile): e2e treats a failed daemon read as a pool error
juliusmarminge Oct 28, 2026
2525252
feat(web): F6 moves between workspace areas, and the sidebar is keybo…
t3dotgg Oct 28, 2026
575a03f
chore(review): Macroscope check agents move to GPT 6.1 Sol (#26187)
t3dotgg Oct 28, 2026
e2a8ef0
feat(dev): test turns in the UI for free with a replay provider (#26207)
t3dotgg Oct 28, 2026
93a9e07
feat(threads): choose your own snooze options in settings (#26208)
t3dotgg Oct 28, 2026
c3b40b9
fix(relay): stop delivery attempts from growing the database forever …
juliusmarminge Oct 28, 2026
9638e17
fix(relay): tunnel cleanup keeps up with new idle tunnels (#26135)
juliusmarminge Oct 28, 2026
4b00290
fix(server): delegate cgroups to agent scopes (#23913)
juliusmarminge Oct 28, 2026
3b2f958
fix(server): ACP Registry searches reuse a recently fetched index (#2…
juliusmarminge Oct 28, 2026
67661cf
chore: delete 18k lines of code that nothing reaches (#26238)
t3dotgg Oct 28, 2026
e0b3cfe
fix(web): image and file chips underline their name on hover again (#…
flamboh Oct 28, 2026
2de4762
fix(mobile): tab bar hides with the push, logo fits the iPad sidebar,…
juliusmarminge Oct 28, 2026
91992bd
fix(web): update dialog shows one row per machine (#26210)
t3dotgg Oct 28, 2026
7c6446b
chore(mobile): e2e review skips behaviour confirmed as intended
juliusmarminge Oct 28, 2026
36aea58
fix(mobile): trust user-installed Android CA certificates (#25730)
juliusmarminge Oct 28, 2026
8947f3e
fix(web): server rows keep their source visible, cmd-click opens your…
t3dotgg Oct 28, 2026
f120c51
fix(mobile): list bullets keep a gap before their text at every text …
juliusmarminge Oct 28, 2026
949929d
fix(mobile): Android split content keeps a gap at the screen edge (#2…
juliusmarminge Oct 28, 2026
c2fbf0a
feat(server,web,mobile): thread links name their environment and neve…
juliusmarminge Oct 28, 2026
fe55faf
fix(clients): # suggestions put linked pull requests first for text q…
juliusmarminge Oct 28, 2026
49a9e80
fix(terminal): keep shared terminal grids in sync (#24352)
juliusmarminge Oct 28, 2026
0c80751
feat: sign in to GitHub through the T3 Code for GitHub app [internal …
juliusmarminge Oct 28, 2026
ff71186
test(mobile): vp run mobile:behavior grades app behavior on pool devices
juliusmarminge Oct 28, 2026
9910c0e
perf: reduce remote reconnect and command delays (#25754)
Bil0000 Oct 28, 2026
822fc15
fix(relay): deploys plan again after the Worker lost its default expo…
juliusmarminge Oct 28, 2026
3ef1610
fix(web): compaction row says "Compacting for 12s" instead of "after …
t3dotgg Oct 28, 2026
9a8bc04
test(task-cache): remove flaky native runner integration test
juliusmarminge Oct 28, 2026
c4606e5
fix(server): Codex shadow homes share thread writer locks with the ma…
t3dotgg Oct 28, 2026
28da8c8
fix(mobile): sidebar connection status uses the header's free width (…
juliusmarminge Oct 28, 2026
9c6429d
fix(web): threads without a project start on the primary environment …
juliusmarminge Oct 28, 2026
cafdcda
fix(clients): give image attachment chips a blue accent (#26306)
Yash-Singh1 Oct 28, 2026
afc2334
fix(web): prevent image thumbnails from warping during repaints (#26308)
Yash-Singh1 Oct 28, 2026
49582b7
test(web): attachment font and large-text preview tests wait for the …
juliusmarminge Oct 28, 2026
8031991
fix(opencode): subagent sessions follow runtime mode changes (#26302)
juliusmarminge Oct 28, 2026
1f8530e
feat(web): pending approvals show on their timeline row (#26255)
maria-rcks Oct 28, 2026
9b052a2
fix(web): show the platform modifier in the send tooltip (#22436)
UtkarshUsername Oct 28, 2026
feb49e7
fix(web): let theme color pickers use popover glass (#22348)
UtkarshUsername Oct 28, 2026
9bc0419
fix(relay): concurrent link requests can no longer exceed the managed…
juliusmarminge Oct 28, 2026
003ccd3
fix(client-runtime): pairing links can no longer add routes to a save…
juliusmarminge Oct 28, 2026
feb2e32
fix(web): align sidebar button geometry with shared tokens (#22287)
UtkarshUsername Oct 28, 2026
c0f9e36
fix(mobile): pairing deep links can no longer target a saved environm…
juliusmarminge Oct 28, 2026
8e76f94
feat(relay): T3 Chat Pro and Premier accounts get more tunnels (#25931)
t3dotgg Oct 28, 2026
0deb383
test(mobile): pairing link test runs the app's real link parsing (#26…
juliusmarminge Oct 28, 2026
50d3a31
fix: guests see the screenshots the agent shows in its replies (#26323)
t3dotgg Oct 28, 2026
a9418a1
ci(release): releases no longer reinstall Vite+ in every job (#26305)
t3dotgg Oct 28, 2026
f6d3700
ci: server test shards survive a throttled task cache (#26332)
t3dotgg Oct 28, 2026
4e4d4ba
feat(web): boring sidebar groups threads into project folders (#21039)
t3dotgg Oct 28, 2026
9ebca5f
fix(relay): tunnel limit counts abandoned reprovisions and frees fail…
juliusmarminge Oct 28, 2026
cadbdaf
test(web): attachment preview tests wait long enough for cold workers…
t3dotgg Oct 28, 2026
2349c81
refactor(mobile): app link parsing reads top to bottom with pipe (#26…
juliusmarminge Oct 28, 2026
ce66aab
ci(release): Windows CLI builds retry the Node.js download (#26345)
t3dotgg Oct 28, 2026
7e0cd67
Merge tag 'v0.1.4-nightly.20261028.3814' into chamaquita/upstream-v0.…
chamaquita-d3[bot] Oct 28, 2026
66552f3
fix(mobile): export shouldRecheckAppUpdateOnForeground for the fork's…
chamaquita-d3[bot] Oct 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
13 changes: 13 additions & 0 deletions .agents/skills/test-t3-app/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ Test with meaningful project and thread data. Read
[references/sqlite-fixtures.md](references/sqlite-fixtures.md) only when
inspecting or seeding SQLite. Stop the test server before direct fixture writes.

## Drive agent turns for free

Do not spend a paid model to see a turn render. `vp run dev` registers the
`Replay (dev)` provider, which replays recorded turns with simulated streaming
through the real adapter and orchestration. Its models are scenarios:
`showcase` covers thinking, a plan, tool calls, an approval, and markdown.
Press `Ctrl+Alt+Shift+R` for a picker (GNOME takes that key for screen
recording), call `window.t3dev.replay("showcase")`
with `preview_evaluate`, or run
`node apps/server/src/bin.ts thread start --base-dir .t3 --provider devReplay --model showcase <project> "go"`.
When the test needs real provider behavior, use that provider's cheapest
model, such as Haiku for Claude or Luna for Codex.

## Use the Browser panel

Call `preview_status`, then `preview_open` if the Browser panel is
Expand Down
2 changes: 1 addition & 1 deletion .coderabbit.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default defineConfig((ctx) => ({
instructions: "Hold changed code to the rules in docs/internals/web-ui.md.",
},
{
path: "**/*.test.{ts,tsx}",
path: "**/*.test.*",
instructions:
"Hold changed tests to the rules in docs/internals/testing.md. Request tests only as those rules allow.",
},
Expand Down
61 changes: 50 additions & 11 deletions .github/actions/setup-ci-deps/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ inputs:
description: Read-only credential for the private maintainer task cache
required: false
default: ""
install:
description: Set to "false" to set up Vite+ only, with no pnpm store or install
required: false
default: "true"
install-args:
description: Arguments for `vp install`, such as filters. Empty installs the whole workspace.
required: false
default: ""
runs:
using: composite
steps:
Expand All @@ -19,10 +27,11 @@ runs:
echo "node=$(jq -r '.engines.node' package.json)" >> "$GITHUB_OUTPUT"
echo "pnpm=$(jq -r '.packageManager' package.json)" >> "$GITHUB_OUTPUT"

# Pinned because release-desktop.yml signs builds with this action in the job.
- name: Cache Vite+
id: vp_cache
if: steps.vp.outputs.version != ''
uses: actions/cache@v6
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: ~/.vite-plus
key: vite-plus-home-v2-${{ runner.os }}-${{ runner.arch }}-${{ steps.vp.outputs.version }}-node${{ steps.vp.outputs.node }}-${{ steps.vp.outputs.pnpm }}
Expand All @@ -40,36 +49,66 @@ runs:

- name: Setup Vite+
if: steps.vp_cache.outputs.cache-hit != 'true'
uses: voidzero-dev/setup-vp@v1
uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1
with:
node-version-file: package.json
cache: false
run-install: false

- name: Resolve pnpm store path
# A shared key lets whichever install saves first, often a small filtered
# one, become every job's store. Each set of install args gets its own.
- name: Resolve pnpm store
id: pnpm_store
if: inputs.install == 'true'
shell: bash
env:
INSTALL_ARGS: ${{ inputs.install-args }}
run: |
store_path="$(vp pm cache dir)"
echo "path=$store_path" >> "$GITHUB_OUTPUT"
echo "path=$(vp pm cache dir)" >> "$GITHUB_OUTPUT"
if [[ -z "$INSTALL_ARGS" ]]; then
echo "namespace=full" >> "$GITHUB_OUTPUT"
else
echo "namespace=filtered-$(printf '%s' "$INSTALL_ARGS" | cksum | cut -d' ' -f1)" >> "$GITHUB_OUTPUT"
fi

# setup-vp's shared cache key ignores install filters. Keep full installs in a
# separate namespace, including fallback restores.
# Filtered installs prefer the current full store, which holds every package,
# over an older store of their own.
# The pnpm store stays a cache tarball on the runner's own disk. A store on a
# Blacksmith sticky disk mounts in under a second, but pnpm then copies every
# package across filesystems instead of hard-linking it: install took 28-49s
# against 9s plus an 11s restore.
- name: Cache full pnpm store
uses: actions/cache@v6
- name: Restore pnpm store
id: pnpm_cache
if: inputs.install == 'true'
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: ${{ steps.pnpm_store.outputs.path }}
key: pnpm-full-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('pnpm-lock.yaml', 'pnpm-workspace.yaml', 'package.json') }}
key: pnpm-${{ steps.pnpm_store.outputs.namespace }}-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('pnpm-lock.yaml', 'pnpm-workspace.yaml', 'package.json') }}
restore-keys: |
pnpm-full-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('pnpm-lock.yaml', 'pnpm-workspace.yaml', 'package.json') }}
pnpm-${{ steps.pnpm_store.outputs.namespace }}-v1-${{ runner.os }}-${{ runner.arch }}-
pnpm-full-v1-${{ runner.os }}-${{ runner.arch }}-

- name: Install dependencies
if: inputs.install == 'true'
shell: bash
run: vp install
env:
INSTALL_ARGS: ${{ inputs.install-args }}
# Unquoted so each filter is its own argument.
run: vp install $INSTALL_ARGS

# A filtered install that started from the current full store adds nothing
# worth a second copy of it.
- name: Save pnpm store
if: >-
inputs.install == 'true' &&
steps.pnpm_cache.outputs.cache-hit != 'true' &&
(steps.pnpm_store.outputs.namespace == 'full' ||
steps.pnpm_cache.outputs.cache-matched-key != format('pnpm-full-v1-{0}-{1}-{2}', runner.os, runner.arch, hashFiles('pnpm-lock.yaml', 'pnpm-workspace.yaml', 'package.json')))
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: ${{ steps.pnpm_store.outputs.path }}
key: ${{ steps.pnpm_cache.outputs.cache-primary-key }}

- name: Enable shared task cache
if: >-
Expand Down
4 changes: 2 additions & 2 deletions .github/triage/PLAYBOOK.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ provided alongside this playbook. Everything machine-specific lives there, not h

## 1. Ask what went wrong

Your first message to the user: ask them to describe what went wrong, in their own
words. Ask them to paste screenshots directly into this session if they have any.
Unless the user already described it, your first message asks what went wrong, in
their own words. Ask them to paste screenshots directly into this session if they have any.
Ask follow-up questions when the description is vague. Good repro steps are the most
valuable thing you can extract from this conversation.

Expand Down
14 changes: 3 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -225,16 +225,6 @@ jobs:
!/apps/mobile/modules/t3-terminal/Vendor/**/*.a
sparse-checkout-cone-mode: false

# Blacksmith boots GitHub's Ubuntu runner image (gcc is usually present),
# but ACP process-tree live tests compile a small pthread fixture with `cc`
# and soft-skip when it is missing. Install build-essential so that path
# always runs in CI instead of silently no-oping.
- name: Install C toolchain for process-tree fixtures
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends build-essential
command -v cc
- uses: ./.github/actions/setup-apt-mirrors

# The desktop tests compile the browser secret helper. The install runs in
Expand Down Expand Up @@ -364,7 +354,9 @@ jobs:
id-token: write
name: Test Server ${{ matrix.shard }}
runs-on: blacksmith-4vcpu-ubuntu-2404
timeout-minutes: 10
# Shards take 2-5 minutes. When the shared task cache throttles reads, each
# failed fetch stalls vp for 15-90s, which pushed shards past 10 minutes.
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/deploy-relay.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ jobs:
CLERK_SECRET_KEY: ${{ secrets.CLERK_SECRET_KEY }}
APNS_PRIVATE_KEY: ${{ secrets.APNS_PRIVATE_KEY }}
FCM_SERVICE_ACCOUNT: ${{ secrets.FCM_SERVICE_ACCOUNT }}
T3CHAT_LINK_SECRET: ${{ secrets.T3CHAT_LINK_SECRET }}

- name: Publish relay deploy commit status
uses: actions/github-script@v8
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/relay-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,5 @@ jobs:
PLANETSCALE_API_TOKEN: ${{ secrets.PLANETSCALE_API_TOKEN }}
AXIOM_TOKEN: ${{ secrets.AXIOM_TOKEN }}
CLERK_SECRET_KEY: ${{ secrets.CLERK_SECRET_KEY }}
# Unset by default, so previews keep the T3 Chat link off.
T3CHAT_LINK_SECRET: ${{ secrets.T3CHAT_LINK_SECRET }}
31 changes: 22 additions & 9 deletions .github/workflows/release-desktop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,6 @@ jobs:
git sparse-checkout set --no-cone '/*' '!/.repos/'
git -c checkout.workers=0 checkout --detach FETCH_HEAD

- name: Setup Vite+
uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1
with:
node-version-file: package.json
cache: true
run-install: false

# pnpm checks the lockfile and policy before reusing this result. A missing
# artifact leaves the cache empty, so installation runs the checks again.
- name: Download dependency verification
Expand All @@ -163,10 +156,12 @@ jobs:
name: release-dependency-verification
path: ${{ runner.temp }}/pnpm-metadata

- name: Install desktop dependencies
- name: Setup dependencies
uses: ./.github/actions/setup-ci-deps
with:
install-args: --filter=@t3tools/desktop... --filter=t3... --filter=@t3tools/scripts...
env:
pnpm_config_cache_dir: ${{ runner.temp }}/pnpm-metadata
run: vp install --filter=@t3tools/desktop... --filter=t3... --filter=@t3tools/scripts...

- name: Cache resource monitor
id: resource_monitor_cache
Expand Down Expand Up @@ -259,6 +254,24 @@ jobs:
if [[ "${{ inputs.version }}" =~ -nightly\.[0-9]{8}\.[0-9]+$ ]]; then brand=nightly; fi
node scripts/apply-web-brand-assets.ts "$brand" apps/server/dist/client

# tsdown downloads the target Node with one fetch and no retry, and
# nodejs.org drops that download often enough to fail releases. Seed
# tsdown's cache with a retried, checksum-verified copy instead.
- name: Download target Node.js for the CLI executable
if: inputs.cli_archive && inputs.platform == 'win'
shell: bash
run: |
set -euo pipefail
version="$(node -p 'require("./package.json").engines.node')"
name="node-v$version-win-${{ inputs.arch }}"
dest="${XDG_CACHE_HOME:-$HOME/.cache}/tsdown/node/v$version/win-${{ inputs.arch }}"
dir="$RUNNER_TEMP/node-download"
mkdir -p "$dir" "$dest"
curl -fsSL --retry 5 --retry-all-errors -o "$dir/$name.zip" "https://nodejs.org/dist/v$version/$name.zip"
curl -fsSL --retry 5 --retry-all-errors -o "$dir/SHASUMS256.txt" "https://nodejs.org/dist/v$version/SHASUMS256.txt"
(cd "$dir" && grep " $name.zip\$" SHASUMS256.txt | sha256sum -c -)
unzip -p "$dir/$name.zip" "$name/node.exe" > "$dest/node.exe"

# Setup Vite+ selects the exact engines.node version from package.json.
# Native builds embed that executable; cross-target builds download the
# same version for their target.
Expand Down
Loading
Loading