Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
55c9093
fix(mobile): isolate markdown image requests (#7942)
SunkenInTime Aug 23, 2026
9da0fab
feat(web): redesign skills in `$` menu and in `/` menu (#8009)
extoci Aug 23, 2026
09df91f
fix(web): restore right panel toggle clicks after closing on desktop …
UtkarshUsername Aug 23, 2026
5427ca0
fix(web): keep server update banners flush with the composer (#8000)
t3dotgg Aug 23, 2026
fa21900
perf(web): reuse work log rows during streaming (#8006)
Bil0000 Aug 23, 2026
a9cd94e
fix(web): keep provider badge legible in dark themes (#7968)
RakshithBhat03 Aug 23, 2026
69e5ad8
fix(web): treat configured urls with uppercase schemes as secure (#8005)
Lucenx9 Aug 23, 2026
b4be33f
fix(desktop): keep release notes visible while downloading (#6412)
extoci Aug 23, 2026
17dbe8d
fix(web): show only providers with usage in usage views (#7563)
tris203 Aug 24, 2026
643daa5
fix(web): prevent expanded tool calls from hiding thread content (#8052)
t3dotgg Aug 24, 2026
b60a2c0
test(server): remove no-op live activity tests (#8056)
t3-code[bot] Aug 24, 2026
10626c5
fix(web): clarify terminal sidebar grouping (#7967)
StiensWout Aug 24, 2026
7c6163c
fix(codex): show app access approval prompts (#8058)
t3dotgg Aug 24, 2026
e9f50c3
feat(web): upload image attachments before sending (#8048)
t3dotgg Aug 24, 2026
58ba559
fix(server): bound OpenCode skill discovery output (#7675)
Lucenx9 Aug 24, 2026
9eba125
fix(mobile): persist thread shelf collapse state (#5152)
PixPMusic Aug 24, 2026
2d2efff
fix(mobile): restore Android tablet thread controls, clean up header …
PixPMusic Aug 24, 2026
f9a726e
fix(mobile): land the first thread open above the composer on Android…
PollyGlot Aug 24, 2026
be3da50
fix(server): check out submodules in a new worktree (#7674)
Brechard Aug 24, 2026
ba30177
fix(server): preserve merged PR badges after branch deletion (#6216)
tris203 Aug 24, 2026
229b05d
fix(server): return fresh live pull request reads (#6472)
Adamulek123 Aug 24, 2026
6f5c951
fix(web): compare client and server versions as semver, not strings (…
spiky02plateau Aug 24, 2026
c0047c2
fix(web): stop follow-ups from leaving giant blank space (#8068)
t3dotgg Aug 24, 2026
e31e568
fix(marketing): stop automatic Vercel deployments on pull requests (#…
t3dotgg Aug 24, 2026
a002187
chore: vouch repeat contributors (#8071)
t3dotgg Aug 24, 2026
6a26082
fix(server): keep the authoritative subagent model when snapshots rac…
spiky02plateau Aug 24, 2026
04df98d
fix(server): honor auto-accept edits for the OpenCode provider (#7100)
Rishet11 Aug 24, 2026
3fd5064
fix(server): run the CLI on Node versions without import.meta.main (#…
CDVolvik Aug 24, 2026
17822fa
fix(server): recover from provider interrupt failures (#7412)
mrmg Aug 24, 2026
01fc7d2
fix(server): recreate a thread's worktree before starting a turn (#7839)
mackinleysmith Aug 24, 2026
e6a109b
fix(server): thread delete no longer fails on already-removed worktre…
t3dotgg Aug 24, 2026
f035a0f
fix(web): stop update notices showing through the composer (#8083)
t3dotgg Aug 24, 2026
5f1147c
fix(web): detect outdated nightly servers (#8124)
t3dotgg Aug 24, 2026
8287f2c
fix(web): align usage page skeleton layout (#8111)
tris203 Aug 24, 2026
883e1a3
fix(web): make terminal links appear clickable only when clickable (#…
flamboh Aug 24, 2026
a09f921
fix(web): make Windows file links clickable in chat (#8081)
t3dotgg Aug 24, 2026
a1379db
fix(web): sort usage models by token count (#8108)
RakshithBhat03 Aug 24, 2026
9996038
fix: open agent file links in the file viewer (#8098)
StiensWout Aug 24, 2026
c034f51
fix(server): stop routine events from rescanning thread history (#8150)
t3dotgg Aug 25, 2026
2394998
fix(deps): stop pnpm installs from changing the lockfile (#8163)
t3dotgg Aug 25, 2026
143341b
feat(web): settle and restore threads with a keyboard shortcut (#8089)
t3dotgg Aug 25, 2026
63eb042
perf(desktop): cut macOS signing calls by 81% (#8093)
t3dotgg Aug 25, 2026
3c75eb1
feat: link pull requests to threads (#8160)
t3dotgg Aug 25, 2026
bd9ed2b
feat(web): safely attach HEIC photos as JPEG images (#8161)
t3dotgg Aug 25, 2026
bce6809
feat(mobile): track device models and OS versions (#8169)
t3dotgg Aug 25, 2026
afc8342
fix(grok): bound cumulative tool output updates (#7279)
lnieuwenhuis Aug 25, 2026
e6d487e
fix(web): delay thread shortcut hints by 200 ms (#8172)
t3dotgg Aug 25, 2026
43f723f
fix(server): stop probing Cursor until enabled (#8175)
t3dotgg Aug 25, 2026
1a4a759
docs(release): verify remote updates with database migrations (#8177)
t3dotgg Aug 25, 2026
1baf991
fix(server): keep provider CLIs available in the macOS service (#8173)
t3dotgg Aug 25, 2026
c7222ca
feat(claude): compact old threads before they burn through usage (#8144)
t3dotgg Aug 25, 2026
589a9d0
fix(client-runtime): retry queries after connection interruption (#8117)
tris203 Aug 25, 2026
06de9e9
fix(server): keep previously used providers working after upgrades (#…
t3dotgg Aug 25, 2026
c6b8bb8
feat(desktop): build macOS previews from a PR label (#8182)
t3dotgg Aug 25, 2026
5d76653
fix(web): thread jump hints no longer stick after a dictation paste (…
t3dotgg Aug 25, 2026
e67074f
fix(web): keep grouped project renames (#7831)
MohtashamMurshid Aug 25, 2026
082e6ea
feat(web): reveal chat file chips in the system file manager (#7140)
SunkenInTime Aug 25, 2026
994372b
fix(server): push no longer writes a feature branch's commits to its …
t3dotgg Aug 25, 2026
5041777
chore(deps): bump @clerk/electron to 0.0.37 (#8240)
t3dotgg Aug 26, 2026
badae6a
feat(server): fetch legacy model classification from a hosted manifes…
t3dotgg Aug 26, 2026
860caaa
chore(release): prepare v0.0.34
t3-code[bot] Aug 26, 2026
e3cfb92
Merge upstream release train v0.0.34
aaditagrawal Aug 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 28 additions & 7 deletions .github/VOUCHED.td
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,53 @@
#
# Keep entries sorted alphabetically.
github:adityavardhansharma
github:arhxam
github:bil0000
github:binbandit
github:Brechard
github:chrisdeeming
github:chuks-qua
github:cursoragent
github:D3OXY
github:eggfriedrice24
github:extoci
github:gbarros-dev
github:gfsaaser24
github:github-actions[bot]
github:gsimone
github:GuilhermeVieiraDev
github:hwanseoc
github:jakeleventhal
github:jamesx0416
github:jappyjan
github:jasonLaster
github:JoeEverest
github:justsomelegs
github:kridaydave
github:lnieuwenhuis
github:Lucenx9
github:mackinleysmith
github:maria-rcks
github:mwolson
github:nmggithub
github:Noojuno
github:notkainoa
github:PatrickBauer
github:pc-style
github:PixPMusic
github:PollyGlot
github:RakshithBhat03
github:realAhmedRoach
github:Rishet11
github:saphid
github:sethwebster
github:shiroyasha9
github:shivamhwp
github:StiensWout
github:SunkenInTime
github:tarik02
github:tris203
github:UtkarshUsername
github:Yash-Singh1
github:eggfriedrice24
github:yashranaway
github:Ymit24
github:shivamhwp
github:jappyjan
github:justsomelegs
github:UtkarshUsername
github:SunkenInTime
github:bil0000
165 changes: 165 additions & 0 deletions .github/workflows/desktop-macos-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
name: Desktop macOS Preview

on:
pull_request:
types: [labeled, synchronize, reopened]

permissions:
contents: read
pull-requests: write

concurrency:
group: desktop-macos-preview-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
build:
name: Build macOS Apple Silicon preview
if: >-
github.event.pull_request.head.repo.full_name == github.repository &&
contains(github.event.pull_request.labels.*.name, 'preview:mac') &&
(github.event.action != 'labeled' || github.event.label.name == 'preview:mac')
runs-on: macos-26
timeout-minutes: 45
steps:
- name: Checkout
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha }}
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false

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

- name: Install desktop dependencies
run: vp install --filter=@t3tools/desktop... --filter=t3... --filter=@t3tools/scripts...

- name: Cache resource monitor
id: resource_monitor_cache
uses: actions/cache@v6
with:
path: native/resource-monitor/target/aarch64-apple-darwin/release/t3-resource-monitor
key: resource-monitor-aarch64-apple-darwin-${{ hashFiles('native/resource-monitor/Cargo.lock', 'native/resource-monitor/Cargo.toml', 'native/resource-monitor/src/**') }}

- name: Setup Rust
if: steps.resource_monitor_cache.outputs.cache-hit != 'true'
uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-apple-darwin

- id: version
name: Set preview version and public configuration
shell: bash
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
set -euo pipefail

base_version="$(node -p "require('./apps/desktop/package.json').version")"
preview_version="${base_version}-pr.${PR_NUMBER}.${GITHUB_RUN_NUMBER}"
node scripts/update-release-package-versions.ts "$preview_version"
cp .env.example .env

echo "version=$preview_version" >> "$GITHUB_OUTPUT"

- id: build
name: Build unsigned macOS DMG
shell: bash
env:
T3CODE_DESKTOP_REUSE_RESOURCE_MONITOR: ${{ steps.resource_monitor_cache.outputs.cache-hit == 'true' }}
PREVIEW_VERSION: ${{ steps.version.outputs.version }}
run: |
set -euo pipefail

vp run dist:desktop:artifact \
--platform mac \
--target dmg \
--arch arm64 \
--build-version "$PREVIEW_VERSION" \
--verbose

shopt -s nullglob
dmg_files=(release/*.dmg)
if (( ${#dmg_files[@]} != 1 )); then
printf 'Expected one DMG, found %s.\n' "${#dmg_files[@]}" >&2
exit 1
fi
printf 'dmg_name=%s\n' "$(basename "${dmg_files[0]}")" >> "$GITHUB_OUTPUT"

- id: upload
name: Upload macOS DMG
uses: actions/upload-artifact@v7
with:
path: release/*.dmg
if-no-files-found: error
archive: false
overwrite: true
retention-days: 7

- name: Comment download link
uses: actions/github-script@v8
env:
ARTIFACT_URL: ${{ steps.upload.outputs.artifact-url }}
DMG_NAME: ${{ steps.build.outputs.dmg_name }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PREVIEW_VERSION: ${{ steps.version.outputs.version }}
with:
script: |
const { data: pullRequest } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number,
});
if (pullRequest.head.sha !== process.env.HEAD_SHA) {
core.info("Skipping the outdated macOS preview comment.");
return;
}

const marker = "<!-- desktop-macos-preview -->";
const body = [
marker,
"### macOS preview",
"",
`[Download Apple Silicon DMG](${process.env.ARTIFACT_URL})`,
"",
`Version: ${process.env.PREVIEW_VERSION}`,
`Commit: ${process.env.HEAD_SHA.slice(0, 7)}`,
"",
"Unsigned build. Clear quarantine before opening:",
"```sh",
`xattr -d com.apple.quarantine ~/Downloads/${process.env.DMG_NAME}`,
"```",
"",
"The download requires GitHub access and expires after 7 days.",
].join("\n");

const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
per_page: 100,
});
const existing = comments.find((comment) => comment.body?.includes(marker));

if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body,
});
}
7 changes: 7 additions & 0 deletions .macroscope/check-run-agents/ui-consistency.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ The goal is not to minimize CSS or class counts at any cost. The goal is to put
- Do not treat a screenshot as proof of keyboard, overflow, scrollbar, responsive, or runtime-theme behavior. Pair visual evidence with source, computed-style, emitted-CSS, or interaction checks as appropriate.
- Be alert to shared primitive color indirection. When a primitive routes icon color through a CSS variable, ensure migrated contextual icons retain their intended tone, including pressed and disabled states.

## Environment routing in shared renderers

- A shared renderer that performs an environment-scoped action — a server RPC such as opening or revealing a file, an environment-gated capability check, or an OS-derived label — must resolve its target environment from explicit scope: the bound thread's `environmentId`, or an `environmentId` prop threaded from the owning surface. Never let it silently fall back to the globally active environment. Multi-environment surfaces (pull request panels, review annotations, cross-environment listings) can render content from environment B while environment A is active; a silent fallback sends B's paths to A's server and presents A's platform wording.
- When a call site cannot supply an explicit environment scope, suppress the environment-scoped actions at that call site rather than guessing. A hidden menu item is correct; an item that targets the wrong server is a concrete finding.
- Capability gating, action dispatch, and user-facing labels must all read from the same environment's server config that the action will execute against. Flag a renderer whose label derives from one environment while its RPC targets another.
- Flag new call sites of shared markdown, chip, or menu renderers that trigger environment actions without passing explicit scope, and flag new environment-action props whose default reintroduces an active-environment fallback.

## Change discipline

- Review the pull request's changed scope and directly affected consumers. Do not turn a focused PR into a demand for unrelated legacy cleanup.
Expand Down
1 change: 1 addition & 0 deletions apps/desktop/src/settings/DesktopClientSettings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const clientSettings: ClientSettings = {
fontSmoothing: true,
glassOpacity: 80,
planModeEnabled: false,
showSkillsInSlashMenu: false,
providerModelPreferences: {},
sidebarAutoSettleAfterDays: 3,
sidebarAutoSettleOnMerge: true,
Expand Down
3 changes: 3 additions & 0 deletions apps/marketing/vercel.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type { VercelConfig } from "@vercel/config/v1";

export const config: VercelConfig = {
git: {
deploymentEnabled: false,
},
installCommand: "npm install -g vite-plus && vp install --filter '@t3tools/marketing...'",
buildCommand: "vp run --filter @t3tools/marketing build",
outputDirectory: "dist",
Expand Down
6 changes: 4 additions & 2 deletions apps/mobile/modules/t3-markdown-text/src/markdownLinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import type { MARKDOWN_FILE_ICON_SOURCES } from "./markdownFileIcons.generated";
const WINDOWS_DRIVE_PATH_PATTERN = /^[A-Za-z]:[\\/]/;
const WINDOWS_UNC_PATH_PATTERN = /^\\\\/;
const RELATIVE_PATH_PREFIX_PATTERN = /^(~\/|\.{1,2}\/)/;
const RELATIVE_FILE_PATH_PATTERN = /^[A-Za-z0-9._-]+(?:\/[A-Za-z0-9._-]+)+(?::\d+){0,2}$/;
const RELATIVE_FILE_NAME_PATTERN = /^[A-Za-z0-9._-]+\.[A-Za-z0-9_-]+(?::\d+){0,2}$/;
const RELATIVE_FILE_PATH_PATTERN =
/^(?:[A-Za-z0-9._-]+(?: +[A-Za-z0-9._-]+)*\/)+[A-Za-z0-9._-]+(?: +[A-Za-z0-9._-]+)*(?::\d+){0,2}$/;
const RELATIVE_FILE_NAME_PATTERN =
/^[A-Za-z0-9._-]+(?: +[A-Za-z0-9._-]+)*\.[A-Za-z0-9_-]+(?::\d+){0,2}$/;
const POSITION_SUFFIX_PATTERN = /:\d+(?::\d+)?$/;
const POSIX_FILE_ROOT_PREFIXES = [
"/Users/",
Expand Down
1 change: 1 addition & 0 deletions apps/mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"expo-constants": "~56.0.18",
"expo-crypto": "~56.0.4",
"expo-dev-client": "~56.0.20",
"expo-device": "~56.0.4",
"expo-file-system": "~56.0.8",
"expo-font": "~56.0.7",
"expo-glass-effect": "~56.0.4",
Expand Down
5 changes: 4 additions & 1 deletion apps/mobile/src/components/CompactBrandTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export function brandTitleOffset(nativeLeadingItem: boolean): number {
*/
export function CompactBrandTitle(
props: {
readonly allowFontScaling?: boolean;
readonly nativeLeadingItem?: boolean;
} = {},
) {
Expand All @@ -57,6 +58,7 @@ export function CompactBrandTitle(
>
<T3Wordmark color={iconColor} height={15} />
<Text
allowFontScaling={props.allowFontScaling}
style={{
color: mutedColor,
fontFamily: "DMSans-Medium",
Expand All @@ -75,6 +77,7 @@ export function CompactBrandTitle(
}}
>
<Text
allowFontScaling={props.allowFontScaling}
style={{
color: mutedColor,
fontFamily: "DMSans-Bold",
Expand All @@ -91,7 +94,7 @@ export function CompactBrandTitle(
}

export function renderCompactBrandTitle() {
return <CompactBrandTitle />;
return <CompactBrandTitle allowFontScaling={Platform.OS === "ios"} />;
}

export function renderCompactBrandHeaderItems(): NativeStackHeaderItem[] {
Expand Down
5 changes: 5 additions & 0 deletions apps/mobile/src/features/cloud/linkEnvironment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ vi.mock("expo-constants", () => ({
},
}));

vi.mock("expo-device", () => ({
osVersion: "18.4.1",
modelName: "iPhone 15 Pro",
}));

vi.mock("react-native", () => ({
Platform: {
OS: "ios",
Expand Down
4 changes: 2 additions & 2 deletions apps/mobile/src/features/home/AndroidHomeFab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { SymbolView } from "../../components/AppSymbol";
import { useThemeColor } from "../../lib/useThemeColor";

/**
* Android-only wrapper that overlays a bottom-right new-task FAB on the home
* screen. Other platforms render children unchanged.
* Android-only wrapper that overlays a bottom-right new-task FAB on a thread
* list. Other platforms render children unchanged.
*/
export function AndroidHomeFabLayout(props: {
readonly onStartNewTask: () => void;
Expand Down
31 changes: 19 additions & 12 deletions apps/mobile/src/features/home/HomeRouteScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as Arr from "effect/Array";
import * as Order from "effect/Order";
import { useNavigation } from "@react-navigation/native";
import { useEffect, useMemo, useState } from "react";
import { Platform } from "react-native";

import { NativeHeaderToolbar, NativeStackScreenOptions } from "../../native/StackHeader";
import { useProjects, useThreadShells } from "../../state/entities";
Expand Down Expand Up @@ -106,7 +107,11 @@ export function HomeRouteScreen() {
return (
<>
<NativeStackScreenOptions
options={{ title: "", headerTitle: "", unstable_headerLeftItems: () => [] }}
options={
Platform.OS === "android"
? { headerShown: false }
: { title: "", headerTitle: "", unstable_headerLeftItems: () => [] }
}
/>
<WorkspaceSidebarToolbar
afterSidebarButton={
Expand All @@ -129,18 +134,20 @@ export function HomeRouteScreen() {
onStartNewTask={() => navigation.navigate("NewTaskSheet", { screen: "NewTask" })}
>
<>
{/* Restore the compact title after the split branch blanks the detail
header. The brand slot doubles as the connection status surface:
while an environment reconnects, the lockup fades to a status label
in place (no layout shift in the list below). */}
{/* Restore the header after leaving split view; screen options are
shallow-merged. The brand slot also doubles as the connection
status surface while an environment reconnects. */}
<NativeStackScreenOptions
options={getConnectionAwareBrandHeaderOptions({
onOpenEnvironments: () =>
navigation.navigate("SettingsSheet", {
screen: "SettingsContent",
params: { screen: "SettingsEnvironments" },
}),
})}
options={{
...getConnectionAwareBrandHeaderOptions({
onOpenEnvironments: () =>
navigation.navigate("SettingsSheet", {
screen: "SettingsContent",
params: { screen: "SettingsEnvironments" },
}),
}),
headerShown: true,
}}
/>
<HomeHeader
environments={environments}
Expand Down
Loading
Loading