Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
428 commits
Select commit Hold shift + click to select a range
36668db
feat(desktop): share macOS permission onboarding (#11289)
juliusmarminge Sep 11, 2026
8a2d5f5
fix(test): drain worker broadcasts before restoring browser globals (…
maria-rcks Sep 12, 2026
8461c25
fix(web): disable linked pull requests when none are linked (#11348)
maria-rcks Sep 12, 2026
1f73a89
fix(models): default to astra medium and fable 5.1 medium (#11347)
maria-rcks Sep 12, 2026
4d16e6b
fix(web): align provider settings with shared settings rows (#10571)
maria-rcks Sep 12, 2026
cf1ba3d
feat(settings): configure default permissions for new threads (#11346)
maria-rcks Sep 12, 2026
fd5553f
fix: restore provider history and prompts when rewinding (#11338)
maria-rcks Sep 12, 2026
25da986
fix(web): keep comment actions visible when pr comments are folded (#…
maria-rcks Sep 12, 2026
efccda9
feat: rewind conversations while keeping file changes (#11358)
maria-rcks Sep 12, 2026
3882778
fix(web): keep sidebar scroll position when pinning threads (#10757)
saphid Sep 12, 2026
8eec78c
fix(web): remove pr description reactions (#11361)
maria-rcks Sep 12, 2026
e816064
fix(desktop): keep preview keystrokes out of the composer (#11354)
maria-rcks Sep 12, 2026
4a4c6dd
feat(settings): add open source license notices (#8962)
juliusmarminge Sep 12, 2026
ca6416e
perf(client): reduce repeated sorting and date formatting (#11019)
Bil0000 Sep 12, 2026
4fed6cf
feat: add inline file previews and attachment chips across surfaces (…
chrisdeeming Sep 12, 2026
57b23a0
fix(desktop): preserve long offscreen text in SnapShots (#11250)
Bil0000 Sep 12, 2026
b1e223e
perf(server): avoid workspace scans when loading pull requests (#11299)
Bil0000 Sep 12, 2026
d1d15c6
feat(sidebar): fold the project scope into the search row (#11315)
maria-rcks Sep 12, 2026
18d8cbf
fix(mobile): pin expo-audio so the release smoke patch stays in use (…
ipanasenko Sep 12, 2026
5349522
Delete .pnpm-store/v11 directory
juliusmarminge Sep 12, 2026
a43f9b4
fix(web): preserve snapshot preview size in sent messages (#11429)
Bil0000 Sep 12, 2026
bbedad0
fix(mobile): render photo library picks to a bounded JPEG off the JS …
Nelglor Sep 12, 2026
c542b78
fix(desktop): keep the native preview User-Agent so Turnstile passes …
akriaueno Sep 12, 2026
3486451
fix(chat): keep user input outside collapsed work (#11363)
maria-rcks Sep 12, 2026
cfeaca4
fix(web): preserve preview focus on window return (#11444)
Lucenx9 Sep 12, 2026
03e1355
fix(web): complete thread status icons and keep input threads promine…
maria-rcks Sep 12, 2026
75d8b13
feat(web): tint image chips with their average color (#11468)
maria-rcks Sep 12, 2026
c1ff6ab
fix(web): move viewer controls outside media and restore arrow naviga…
maria-rcks Sep 12, 2026
b0c6c3b
fix(web): tighten sidebar search and footer spacing (#11466)
maria-rcks Sep 12, 2026
c0ddfb3
feat(web): subagent spawns render as an expandable work row (#11433)
maria-rcks Sep 12, 2026
af2bacc
fix(web): keep subagent rows visible under folded turns (#11474)
maria-rcks Sep 12, 2026
fcbe457
fix(usage): make unavailable account limits more visible (#10601)
dominic-r Sep 12, 2026
8ddd9f7
fix(desktop): bound backend shutdown wait during quit (#7599)
ishaanko Sep 12, 2026
36caf20
feat(web): choose the default diff file state (#11484)
maria-rcks Sep 13, 2026
68c2277
feat(composer): fold large pastes into text attachments (#11442)
chrisdeeming Sep 13, 2026
6cdbf76
feat(web): expose each chat message as a heading for screen readers (…
Leos-Khai Sep 13, 2026
2db675a
fix(usage): respect provider account homes (#11485)
maria-rcks Sep 13, 2026
2587c80
feat(web): switch saved environments off instead of removing them (#1…
t3dotgg Sep 13, 2026
5781e2b
fix(mobile): stop crashing on launch when a thread has a PR stack (#1…
juliusmarminge Sep 13, 2026
af0657e
fix(mobile): stop alerting that shared content vanished after sending…
juliusmarminge Sep 13, 2026
0e0ddae
feat(web): add opt-in thread notifications and sounds (#11481)
maria-rcks Sep 13, 2026
c299764
fix(server): open Cursor links in classic IDE mode (#11498)
Yash-Singh1 Sep 13, 2026
6fd68f5
feat(source-control): support Forgejo and Gitea with fj and tea (#11436)
maria-rcks Sep 13, 2026
0c5771d
fix(web): match draft row heights to thread rows (#11512)
Yash-Singh1 Sep 13, 2026
3138f57
fix(grok): emit task lifecycle for monitors and background shells (#9…
Svyk Sep 13, 2026
46140c9
fix(web): unify panel resizing and retain final drag width (#11529)
maria-rcks Sep 13, 2026
2ec59ca
fix(web): hide back button for single linked pull requests (#11520)
maria-rcks Sep 13, 2026
21d53ca
fix(files): browse ignored files and load folders on demand (#11527)
maria-rcks Sep 13, 2026
d7c71f9
feat(web): float the pull request comment composer (#11531)
maria-rcks Sep 13, 2026
8b3ddf5
fix(mobile): stop crashing on launch before the shell snapshot arrive…
juliusmarminge Sep 13, 2026
db6e053
feat(github): route pull request operations across matching accounts …
maria-rcks Sep 13, 2026
20a8f1d
chore(mobile): enable noUncheckedIndexedAccess and noImplicitOverride…
juliusmarminge Sep 13, 2026
0a91b9a
feat(mobile): show startup crashes in Settings → Diagnostics (#11540)
juliusmarminge Sep 13, 2026
17f8e2a
feat(mobile): add pooled subscription usage widgets (#11506)
MatthewFeroz Sep 13, 2026
20363c3
feat(web): add provider selector to pull request toolbar (#11524)
maria-rcks Sep 13, 2026
4a39cad
fix(web): offer recovery from missing pages (#11314)
shivamhwp Sep 13, 2026
e628683
fix(web): retry startup after the server recovers (#11291)
shivamhwp Sep 13, 2026
ca2cc13
feat(web): add optional compact sidebar rail (#11525)
maria-rcks Sep 13, 2026
42b6bcc
feat(web): add opt-in in-app thread notifications (#11570)
Bil0000 Sep 13, 2026
f26198d
feat(web): organize connections by environment (#11542)
maria-rcks Sep 13, 2026
0118b52
fix(web): keep sparse sidebar shelves at the bottom (#11595)
maria-rcks Sep 13, 2026
9bf349c
fix(cursor): preserve internal agent errors without transport labels …
shivamhwp Sep 13, 2026
dd6ba84
fix(server): fall back when new worktrees are unavailable (#6208)
tris203 Sep 13, 2026
6e5e986
feat: badge background thread notifications on desktop and web (#11569)
Bil0000 Sep 13, 2026
77bca8b
feat(web): add compact thread list mode (#9417)
saphid Sep 13, 2026
df7ccc8
feat(web): refine compact thread row badges (#11644)
maria-rcks Sep 13, 2026
7b61099
feat(web): show the linked pull request in the compact sidebar rail (…
maria-rcks Sep 13, 2026
9086a1f
fix(mobile): adopt system glass for Live Activities (#11604)
juliusmarminge Sep 13, 2026
3689c98
fix(web): separate expanded tool output from adjacent hover highlight…
dominic-r Sep 13, 2026
66e39ca
fix(web): apply device settings to selected environments (#11541)
juliusmarminge Sep 14, 2026
c07575f
feat(server): show finished paragraphs and code blocks while the resp…
t3dotgg Sep 14, 2026
2d73746
fix(web): disconnect offline servers from threads (#11671)
t3dotgg Sep 14, 2026
5e961d3
feat(web): flatten the connections page into one environments list (#…
t3dotgg Sep 14, 2026
5647191
fix(mobile): keep usage widget rows consistently sized (#11669)
juliusmarminge Sep 14, 2026
3b75e60
feat(server): add reusable auth token for dev worktrees (#8606)
t3dotgg Sep 14, 2026
1bbca0e
feat(settings): choose how responses stream, with a warning on legacy…
t3dotgg Sep 14, 2026
d81278a
revert(web): remove the compact sidebar (#11685)
maria-rcks Sep 14, 2026
683aa87
build(desktop): bundle the main process and stage only its native ext…
juliusmarminge Sep 14, 2026
06de59b
build(server): make the CLI bundle loadable as a Node single-executab…
juliusmarminge Sep 14, 2026
eb8f6f4
ci(release): build, sign, and publish self-contained CLI archives (#1…
juliusmarminge Sep 14, 2026
8f90b38
feat(server): install preview runtimes from release archives (#11318)
juliusmarminge Sep 14, 2026
13c134c
feat(ssh): run preview builds on remotes from the release archive (#1…
juliusmarminge Sep 14, 2026
c7f23c4
feat(cli): add t3 update for self-contained installs (#11451)
juliusmarminge Sep 14, 2026
af6c138
feat(server): manage runtimes as release archives only, never from np…
juliusmarminge Sep 14, 2026
0754920
feat(desktop): run the WSL backend from the Linux CLI archive (#11511)
juliusmarminge Sep 14, 2026
2c54f2f
ci(release): build CLI archives for five targets, each on its own arc…
juliusmarminge Sep 14, 2026
2f7616e
ci(release): build the JS bundle once and run every platform and arch…
juliusmarminge Sep 14, 2026
91cd91c
feat(release): publish npx t3 as a launcher over per-platform executa…
juliusmarminge Sep 14, 2026
b70015b
feat(cli): add t3 uninstall for self-contained installs (#11659)
juliusmarminge Sep 14, 2026
73b206f
feat(web): show each worktree setup step and let users cancel it (#11…
t3dotgg Sep 14, 2026
1ced38a
fix(server): skip device hosts that resolve to the local machine (#11…
juliusmarminge Sep 14, 2026
8984f81
fix(web): test device hosts across selected environments (#11699)
juliusmarminge Sep 14, 2026
0b54e00
Change input type from 'full_diff' to 'incremental'
juliusmarminge Sep 14, 2026
e3792a5
Update model and input type in ui-consistency.md
juliusmarminge Sep 14, 2026
cba7dd7
feat(desktop): allow disabling the local environment (#9194)
juliusmarminge Sep 14, 2026
d8655ed
feat(cli): add t3 service restart and make t3 update repoint the serv…
juliusmarminge Sep 14, 2026
01e05c1
docs(claude): clarify OpenRouter model selection (#11369)
shivamhwp Sep 14, 2026
0dec07d
fix(web): keep large image previews from stalling composer typing (#1…
shivamhwp Sep 14, 2026
8ef478e
fix(server): avoid extra round trips for terminal output (#11407)
Bil0000 Sep 14, 2026
6f00d38
fix(web): remember panel width for each thread (#11310)
shivamhwp Sep 14, 2026
9375c77
fix(release): preserve updates from npm-based services (#11732)
t3dotgg Sep 14, 2026
8b1ea4d
fix(desktop): restore Node discovery for WSL providers (#11741)
akj Sep 14, 2026
ae67c5b
fix(release): stop npm from pruning the platform packages' shipped no…
juliusmarminge Sep 14, 2026
955b787
fix(server): parse CLI versions with a "v" prefix (#11738)
NikodemNowak Sep 14, 2026
05e3bcb
fix(desktop): keep preview releases out of the nightly update changel…
juliusmarminge Sep 14, 2026
ec5ede5
fix(web): open video attachment thumbnails in the viewer (#11734)
chrisdeeming Sep 14, 2026
494cfac
Allow setting T3CODE_OTLP_HEADERS (#11218)
bahlo Sep 14, 2026
47ace94
fix(web): use consistent PR section toggles (#11763)
Bil0000 Sep 14, 2026
33118d9
Add T3CODE_OTLP_PROTOCOL to allow protobuf protocol (#11224)
bahlo Sep 14, 2026
9130d93
feat(web): add composer and PR number shortcuts (#11615)
Bil0000 Sep 14, 2026
f328db3
chore(server): keep the legacy service entry point to the npm package…
juliusmarminge Sep 14, 2026
112a708
fix(web): use project monograms for automatic icon fallbacks (#11572)
ShpetimA Sep 14, 2026
8d7c700
feat(web): clone repositories in the background instead of holding th…
juliusmarminge Sep 14, 2026
549d182
feat(mobile): clone repositories in the background and gate the draft…
juliusmarminge Sep 14, 2026
9d4bb55
fix(mobile): scale inline pills with Dynamic Type (#11792)
juliusmarminge Sep 14, 2026
bcc2024
chore(deps): bump the Clerk stack to current releases (#11764)
juliusmarminge Sep 14, 2026
0f21fcb
feat(mobile): add a T3 Connect page to the Clerk profile (#11765)
juliusmarminge Sep 14, 2026
dc0869b
feat(server): use Clerk's device authorization grant for headless con…
juliusmarminge Sep 14, 2026
8419238
Add new GitHub user f-trycua
juliusmarminge Sep 14, 2026
7931227
fix(server): stop refreshing providers on every config subscription (…
juliusmarminge Sep 14, 2026
5bf43c9
fix(web): align monogram project icons in menus (#11806)
juliusmarminge Sep 14, 2026
9a49d6d
ci(desktop): sign fork PR macOS previews without exposing signing sec…
juliusmarminge Sep 14, 2026
014016a
fix(web): make copy PR link discoverable in keybindings (#11826)
Bil0000 Sep 15, 2026
3be02ae
feat: add custom snooze dates and durations (#11800)
juliusmarminge Sep 15, 2026
ea6af59
feat(mobile): redesign the Android agent activity card (#11645)
SunkenInTime Sep 15, 2026
6dbea7e
chore(mobile): bump app version to 1.2.0
t3-code[bot] Sep 15, 2026
5ea6439
feat(web): inline worktree setup rows and async setup scripts (#11832)
juliusmarminge Sep 15, 2026
b5b29e7
fix(server): stream tight list items one at a time in paragraph mode …
juliusmarminge Sep 15, 2026
7cafe52
fix(server): keep thread titles tied to user intent (#10720)
t3dotgg Sep 15, 2026
e9b0555
Remove labels from effect service conventions
juliusmarminge Sep 15, 2026
537dc0f
Remove labels from ui-consistency.md
juliusmarminge Sep 15, 2026
970a873
Change conclusion status from failure to neutral
juliusmarminge Sep 15, 2026
8b9f6d3
Change conclusion from 'failure' to 'neutral'
juliusmarminge Sep 15, 2026
08abda9
refactor(server): resolve title links through source control provider…
juliusmarminge Sep 15, 2026
a62e7d6
refactor(server): align title generation with Effect conventions (#11…
juliusmarminge Sep 15, 2026
5623089
fix(server): disable color probes in worktree setup (#11843)
juliusmarminge Sep 15, 2026
0310cbf
fix: keep worktree setup visible after leaving and reopening the thre…
t3dotgg Sep 15, 2026
b20d29d
fix(desktop): prevent startup from running twice (#11857)
juliusmarminge Sep 15, 2026
26b8f98
feat(mobile): add iPad keyboard shortcuts and command palette (#11679)
bmdavis419 Sep 15, 2026
2c19283
feat(server): persist the worktree setup send and progress on the thr…
juliusmarminge Sep 15, 2026
cc839c4
feat(web): queue messages sent client-side while the agent is working…
t3dotgg Sep 15, 2026
5b377e2
fix(server): bound Git process bursts to keep connections responsive …
Bil0000 Sep 15, 2026
a37b852
perf(server): speed up worktree fetch and checkout (#11633)
Bil0000 Sep 15, 2026
9ea892e
fix(client): show thread state changes before remote replies (#11408)
Bil0000 Sep 15, 2026
6ecc15f
fix(mobile): restrict row highlighting to pointer input (#11863)
juliusmarminge Sep 15, 2026
50ff4c3
fix(mobile): ensure a compatible native client before verification (#…
juliusmarminge Sep 15, 2026
3c4c9a1
fix(web): restore composer focus after closing option menus (#11884)
Bil0000 Sep 15, 2026
bf3be75
fix(web): center refresh devices in the empty state (#11808)
shivamhwp Sep 15, 2026
e33b710
fix(mobile): match command palette colors to sheets (#11861)
juliusmarminge Sep 15, 2026
ae53072
fix(web): keep the composer ready during background worktree setup (#…
Bil0000 Sep 15, 2026
c1b2210
fix(desktop): keep the sidebar brand and window buttons aligned (#11906)
shivamhwp Sep 15, 2026
9a6b57b
fix(web): drop the filled well behind the sidebar header buttons (#11…
flamboh Sep 15, 2026
2a264ad
fix(server): explain how to configure a missing Codex executable (#11…
shivamhwp Sep 15, 2026
d1790aa
fix(mobile): add missing thread rename action (#11503)
Michel-Liao Sep 15, 2026
caf8b5d
fix(mobile): wait for thread deep link hydration (#11502)
Michel-Liao Sep 15, 2026
d07ffbe
fix(mobile): keep iOS chat rows aligned after measurement (#11813)
dominic-r Sep 15, 2026
438465d
feat: add customizable soft-tint project monograms (#11845)
eimexdev Sep 15, 2026
24b711b
fix: multiple UI and server bug fixes (#11593)
kridaydave Sep 15, 2026
7235701
fix(server): release preview hosts after unanswered requests (#11381)
yashranaway Sep 15, 2026
3efdcc5
Preserve diff tree order and collapsed folders (#11931)
juliusmarminge Sep 15, 2026
a5da327
fix(client-runtime): preserve cached turns and older-page loading (#8…
lnieuwenhuis Sep 15, 2026
844203d
chore(deps): bump Clerk stack to latest stable versions (#11956)
juliusmarminge Sep 15, 2026
b18a560
fix(mobile): update Reanimated and Worklets (#11957)
juliusmarminge Sep 15, 2026
96bddf8
fix(desktop): paste as text no longer doubles the pasted text (#11958)
TonybynMp4 Sep 15, 2026
719a76c
feat(web): choose queue or steer for follow-up messages (#11964)
Bil0000 Sep 15, 2026
e6ae764
feat(mobile): add v2 preview store builds (#11966)
juliusmarminge Sep 15, 2026
2c16c1d
fix(mobile): block incompatible server connections (#11974)
juliusmarminge Sep 15, 2026
f0a0ead
fix(web): keep PR controls readable in narrow panels (#11962)
Bil0000 Sep 15, 2026
b84f63b
fix(server): block updates under legacy service launchers (#11940)
Gigioxx Sep 15, 2026
f4600d7
fix: reduce GitHub quota use with sharing enabled (#11888)
Bil0000 Sep 15, 2026
87a12b5
fix(usage): refresh limits when the tab opens (#11928)
Bil0000 Sep 15, 2026
6f7aaff
fix(contracts): avoid Intl.Segmenter in monogram validation (Hermes c…
bompus Sep 15, 2026
37a8ab2
feat(lint): extend Hermes API bans with a configurable API list (#11982)
juliusmarminge Sep 15, 2026
b12c92f
fix(server): reuse Git index metadata during checkpoint capture (#10792)
im-kvijay Sep 15, 2026
7a368fe
refactor: give project monograms their own icon variant (#11993)
juliusmarminge Sep 16, 2026
935c55b
fix(clients): disable incompatible environments during discovery (#11…
juliusmarminge Sep 16, 2026
8c18b5b
fix(antigravity): stop health checks from filling the disk with _MEI …
t3dotgg Sep 16, 2026
0ec2b08
fix(mobile): bare t3code:// links no longer reset navigation to Home …
SunkenInTime Sep 16, 2026
eed974c
fix(server): keep Claude rewind when fork history length changes (#11…
maria-rcks Sep 16, 2026
f8500f1
fix(mobile): use native toolbar search for licenses (#12011)
juliusmarminge Sep 16, 2026
0bf2d6b
chore(release): prepare v0.0.41
t3-code[bot] Sep 16, 2026
47ef017
Revert "chore(release): prepare v0.0.41"
juliusmarminge Sep 16, 2026
3060cc4
fix(release): restrict stable channels to main
juliusmarminge Sep 16, 2026
53612cc
fix(server): detect unsupported legacy Android command-line tools (#1…
Yash-Singh1 Sep 16, 2026
fe896e6
chore(release): prepare v0.0.42
t3-code[bot] Sep 16, 2026
0f5a151
fix(web): stop the worktree setup card from flashing and shifting (#1…
juliusmarminge Sep 16, 2026
c1b2ed6
fix(clients): show unsupported environments as neutral rows with thei…
juliusmarminge Sep 16, 2026
6ee0324
fix(clients): hold the discovered machine icon across relay refreshes…
juliusmarminge Sep 16, 2026
bf55408
fix(server): resolve Node for standalone helper scripts (#12033)
juliusmarminge Sep 16, 2026
b900fc9
feat(web): reveal timestamps on tool rows and turn folds (#8641)
saphid Sep 16, 2026
ccf220b
docs: make the standalone installer the primary way to get the CLI (#…
juliusmarminge Sep 16, 2026
f45c6b4
fix(web): submit PR comments with Cmd/Ctrl+Enter (#11994)
flamboh Sep 16, 2026
e8ca3a8
refactor(web): centralize pull request icon state presentation (#11144)
flamboh Sep 16, 2026
0b83045
feat(providers): expose native slash commands across clients (#11519)
maria-rcks Sep 16, 2026
f4ef515
feat(web): add send shortcut and follow-up controls (#12075)
Bil0000 Sep 16, 2026
052c7ae
feat(chat): show provider thinking traces (#11784)
maria-rcks Sep 16, 2026
eff44be
feat(usage): show OpenCode Go, Cursor, and Grok subscription limits (…
maria-rcks Sep 16, 2026
d1a6448
fix(web): dropped folders become path chips on the local environment …
SunkenInTime Sep 16, 2026
384de08
fix(web): adapt provider settings to available content width (#12138)
tris203 Sep 16, 2026
32e8b25
fix(web): show private repository media in pull request tabs (#11706)
maria-rcks Sep 16, 2026
aae361c
fix(review): show complete counts and load large diffs progressively …
tris203 Sep 16, 2026
52ad70e
fix(web): prioritize linked pull requests over automatic diffs (#12142)
maria-rcks Sep 16, 2026
f1b497a
feat(cli): show installer and update download progress (#12044)
juliusmarminge Sep 16, 2026
01e6419
fix(web): simplify agent approval prompts (#12082)
Bil0000 Sep 16, 2026
dda44ed
fix(web): show tooltips for composer environment and workspace contro…
flamboh Sep 16, 2026
22539f2
fix(chat): group thoughts into the changing tool activity line (#12147)
maria-rcks Sep 16, 2026
ed12389
fix(web): keep tool timestamps before disclosure chevrons (#12152)
Yash-Singh1 Sep 16, 2026
394af73
fix(web): default diff panel to working tree (#12139)
maria-rcks Sep 16, 2026
e106fe9
design(mobile): unify Android Material layouts and native controls (#…
PixPMusic Sep 17, 2026
9686cd9
feat(web): choose themes from chat with color previews (#12143)
maria-rcks Sep 17, 2026
e47a11e
fix(web): align follow-up and license settings controls (#12167)
Bil0000 Sep 17, 2026
892b86d
fix(web): align composer task rows (#12165)
maria-rcks Sep 17, 2026
ed88937
fix(mobile): prevent Android compose FAB animation jitter (#12169)
PixPMusic Sep 17, 2026
c1738f1
fix(server): keep large sparse checkouts on the fast checkpoint path …
vedprakash2302 Sep 17, 2026
c12ba75
feat(web): make pull request comments easier to scan (#12150)
maria-rcks Sep 17, 2026
19ee856
fix(server): propagate linked pr changes and settle threads immediate…
maria-rcks Sep 17, 2026
d612d12
fix(web): reuse cached GitHub PR details across entry points (#12168)
maria-rcks Sep 17, 2026
315b723
Remove `new` badge from Fable 5.1 (#12173)
juliusmarminge Sep 17, 2026
962bf62
fix(web): show author avatars in pull request previews (#12125)
extoci Sep 17, 2026
3bee4c2
fix(server): settle cancelled worktree setup before rollback (#12176)
juliusmarminge Sep 17, 2026
4abb07e
feat(mobile): port worktree setup progress and agent handoff (#12177)
juliusmarminge Sep 17, 2026
8130a9f
fix(server): flush checkpoint objects and refs before publishing them…
Mnigos Sep 17, 2026
88d0c40
chore(mobile): bump app version to 1.2.1
t3-code[bot] Sep 17, 2026
d42a3bd
fix(server): keep ready checkpoints when a later placeholder arrives …
Adolanium Sep 17, 2026
901db89
fix(server): keep VCS waits from blocking turn completion (#11970)
Vrtak-CZ Sep 17, 2026
573a8f2
fix(web): keep header spacing stable when sidebar drawer opens (#12162)
flamboh Sep 17, 2026
df466c7
fix(web): fall back when pull request avatars fail (#11728)
tastelessjolt Sep 17, 2026
d359e94
feat(web): enable rich text composer by default (#12160)
juliusmarminge Sep 17, 2026
71d12d8
feat(web): make keybindings searchable from settings search (#12175)
maria-rcks Sep 17, 2026
f17165a
fix(web): preserve thread reading positions (#12144)
maria-rcks Sep 17, 2026
6d1d549
fix(diff): collapse files by default (#12190)
maria-rcks Sep 17, 2026
886c834
fix(web): folder links from chat open the file tree instead of a brok…
pc-style Sep 17, 2026
712f8ca
feat(web): command palette search matches thread IDs (#11185)
saphid Sep 17, 2026
01eb4b9
fix(web): align notification icons with titles (#12202)
maria-rcks Sep 17, 2026
2a47fc9
fix(skills): support unicode currency symbols as skill aliases (#12098)
WilgotM Sep 17, 2026
c4ca1b0
feat(settings): add automatic storage cleanup per machine and project…
maria-rcks Sep 17, 2026
c0dded8
feat(web): command palette finds the pull requests and usage pages (#…
flamboh Sep 17, 2026
0150c6a
feat(web): start new threads with multiple models in separate worktre…
maria-rcks Sep 17, 2026
dd9528a
fix(mobile): keep screen awake during dictation (#12227)
juliusmarminge Sep 17, 2026
298f8c9
feat(mobile): add favorites to model picker (#12231)
juliusmarminge Sep 17, 2026
1ab2dfb
fix(desktop): keep preview picking active across subframe navigation …
Lucenx9 Sep 17, 2026
d4d5d12
fix(shared): keep the newest shared usage scan (#10315)
yashranaway Sep 17, 2026
fbc8b96
fix(web): keep thoughts and failed tool calls in one activity row (#1…
maria-rcks Sep 17, 2026
2d8378b
fix(web): avoid reopening settled threads when adding projects (#11804)
dominic-r Sep 17, 2026
c25c3e0
feat(mobile): make Settings easier to navigate and scope (#12272)
juliusmarminge Sep 17, 2026
8db3c25
fix(mobile): prevent overlapping text and UI on Android chat messages…
Exotic209093 Sep 17, 2026
0395008
feat(web): pull request files can be marked as viewed (#7721)
yordis Sep 17, 2026
4749035
fix(web): keep composer banners compact and readable (#12166)
Bil0000 Sep 17, 2026
a82d1ab
chore: sync with upstream pingdotgg/t3code main
yordis Sep 17, 2026
9579d86
fix(client-runtime): keep background work sorting within what Hermes …
yordis Sep 17, 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
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
2 changes: 2 additions & 0 deletions .agents/skills/ios-debugger-agent/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ Avoid generic Mac window automation for switching among Simulator windows. Expli

## Choose build or launch

For T3 Code Mobile, run `node scripts/mobile-native-client.ts ensure ios <simulator-udid>` from the checkout on the simulator host first. It checks the local Expo native fingerprint against the installed client and builds/installs when stale, missing, or unknown. Then launch with the intended Metro bundle. Authorized verification includes native builds and installs; do not stop because the existing client is old. Use `check` instead of `ensure` only when the user explicitly prohibits rebuilding or requests a read-only check.

- Use `build_run_sim` when native source, native dependencies, entitlements, or project configuration changed.
- Use `test_sim` for the smallest relevant native test target or test cases; do not run an entire workspace test matrix routinely.
- Use `launch_app_sim` when a compatible app is already installed and no native rebuild is needed.
Expand Down
32 changes: 17 additions & 15 deletions .agents/skills/test-t3-mobile/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,28 @@ Inspect the host and the affected code before launching processes:

- On macOS with Xcode, prefer one representative iOS Simulator when the change is cross-platform so the user can watch through serve-sim. Load and follow [`ios-debugger-agent`](../ios-debugger-agent/SKILL.md), and load [`ios-simulator-browser`](../ios-simulator-browser/SKILL.md) when live streaming is available.
- On macOS, Linux, or Windows with the Android SDK, use one Android Emulator when Android is the affected surface or iOS tooling is unavailable.
- When the change is platform-specific, test that platform. When neither platform is viable, report the missing SDK, emulator, or dev-client prerequisite rather than claiming verification.
- When the change is platform-specific, test that platform. When neither platform is viable, report the missing SDK or emulator prerequisite rather than claiming verification. A missing development client is a build step, not a blocker.

Do not treat unavailable iOS tooling as a blocker when Android is a valid representative target.

## Choose the lightest valid launch path
## Ensure a compatible native client

- For JavaScript, TypeScript, or asset-only changes, reuse a compatible installed development client and start Metro. Do not rebuild native code merely to load a new bundle.
- For native source, native dependencies, entitlements, config plugins, or generated project changes, rebuild the affected platform.
- Use `vp run ios:dev` or `vp run android:dev` only when an Expo clean prebuild is actually required; both commands regenerate the native project.
- If the user requested no native rebuild and no compatible app is installed, reuse an existing compatible `.app` or `.apk` artifact when available. Otherwise report the missing dev client instead of silently rebuilding.
Authorized mobile verification includes building and installing a development client. A missing, stale, or unknown native client is not a reason to skip verification or leave a PR in draft. Build and install it, then continue. Respect an explicit user instruction not to rebuild; otherwise do not ask for separate permission.

The development identity on both platforms is:
Run this from the checkout being tested, on the machine that hosts the selected simulator or emulator. Select and boot one explicit iOS UDID or Android emulator serial first:

- App: `T3 Code Dev`
- Bundle/package identifier: `com.t3tools.t3code.dev`
- URL scheme: `t3code-dev`
```bash
node scripts/mobile-native-client.ts ensure ios <simulator-udid>
node scripts/mobile-native-client.ts ensure android <emulator-serial>
```

`ensure` compares the checkout's local Expo development fingerprint and the installed app's binary contents against the last successful build record. It reuses a matching client; otherwise it runs a clean prebuild, builds and installs the development app, and records the successful result. It does not start Metro. Start Metro below after it succeeds. On hosts with an `agent-job` requirement, run the entire `ensure` command through that queue.

For a read-only decision, use `check` in place of `ensure`. Exit 0 means compatible, 2 means build required, and 1 means an operational error. An app installed outside this helper is initially unknown and gets rebuilt once. Records are local to the simulator host under `~/.cache/t3code/native-clients` and work across checkouts. Do not copy records between machines or write them manually.

A JavaScript-only diff, bundle identifier, app version, or recent install date does not prove native compatibility. Always check the whole checkout. Expo fingerprints are computed locally with `APP_VARIANT=development`; no EAS credentials or cloud build are required. Generated `ios/` and `android/` directories are excluded by `.fingerprintignore`, so edit native source modules or config plugins rather than generated output.

Bundle or package presence proves the correct variant, not native compatibility. Reuse it only when the current changes did not alter its Expo SDK, native dependencies, config plugins, entitlements, generated project, or native source.
The development identity is `T3 Code Dev`, bundle/package `com.t3tools.t3code.dev`, scheme `t3code-dev`. If a build fails, investigate the build error and fix the local prerequisites. Report the concrete failure if it cannot be resolved, not “no compatible client.”

## Start one disposable T3 environment

Expand Down Expand Up @@ -98,21 +102,19 @@ Use `ios-debugger-agent` to select one UDID and set these XcodeBuildMCP session
- Simulator ID: the selected UDID
- Bundle ID: `com.t3tools.t3code.dev`

Check the installed client with:
After `ensure` succeeds, open the Metro URL:

```bash
xcrun simctl get_app_container <simulator-udid> com.t3tools.t3code.dev app
xcrun simctl openurl <simulator-udid> <printed-dev-client-url>
```

Accept the iOS confirmation prompt and dismiss the developer menu when it obscures the app.

### Android launch

Select one running emulator serial from `adb devices` and check the installed client:
Use the emulator serial already checked by `ensure`:

```bash
adb -s <emulator-serial> shell pm path com.t3tools.t3code.dev
adb -s <emulator-serial> reverse tcp:<metro-port> tcp:<metro-port>
adb -s <emulator-serial> shell am start -W \
-a android.intent.action.VIEW \
Expand Down
1 change: 1 addition & 0 deletions .github/VOUCHED.td
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ github:D3OXY
github:dbalders
github:eggfriedrice24
github:extoci
github:f-trycua
github:flamboh
github:FllipEis
github:gbarros-dev
Expand Down
45 changes: 44 additions & 1 deletion .github/scripts/check-nightly-release.cjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,43 @@
const MINIMUM_RELEASE_GAP_MS = 6 * 60 * 60 * 1000;

function repositoryDefaultBranch(context) {
const branch = context.payload.repository?.default_branch;
if (!branch) {
throw new Error("GitHub did not provide the repository default branch.");
}
return branch;
}

async function assertCommitOnDefaultBranch({ github, context, sha }) {
const defaultBranch = repositoryDefaultBranch(context);
const { data: comparison } = await github.rest.repos.compareCommitsWithBasehead({
...context.repo,
basehead: `${sha}...${defaultBranch}`,
per_page: 1,
});
if (comparison.status !== "ahead" && comparison.status !== "identical") {
throw new Error(
`Release commit ${sha} is not contained in ${defaultBranch} (${comparison.status}).`,
);
}
}

async function assertReleaseSource({ github, context, releaseChannel }) {
if (releaseChannel === "preview") return;
if (releaseChannel !== "stable" && releaseChannel !== "nightly") {
throw new Error(`Unsupported release channel: ${releaseChannel}`);
}

const defaultBranch = repositoryDefaultBranch(context);
if (context.eventName === "workflow_dispatch" && context.ref !== `refs/heads/${defaultBranch}`) {
throw new Error(
`${releaseChannel} releases must be dispatched from ${defaultBranch}; selected ${context.ref}. Use the preview channel for branch builds.`,
);
}

await assertCommitOnDefaultBranch({ github, context, sha: context.sha });
}

const isNightlyTag = (tag) => /^v.*-nightly\./.test(tag) || tag.startsWith("nightly-v");

// Newest published nightly by publication time, or undefined when none exists.
Expand Down Expand Up @@ -64,4 +102,9 @@ async function resolveLatestNightlyCommit({ github, context, core }) {
return { tag, sha: commit.sha, version };
}

module.exports = { shouldReleaseNightly, resolveLatestNightlyCommit };
module.exports = {
assertCommitOnDefaultBranch,
assertReleaseSource,
shouldReleaseNightly,
resolveLatestNightlyCommit,
};
77 changes: 76 additions & 1 deletion .github/scripts/check-nightly-release.test.cjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
const assert = require("node:assert/strict");
const test = require("node:test");
const { shouldReleaseNightly } = require("./check-nightly-release.cjs");
const {
assertCommitOnDefaultBranch,
assertReleaseSource,
shouldReleaseNightly,
} = require("./check-nightly-release.cjs");

const now = Date.parse("2026-09-05T12:00:00Z");
const hour = 60 * 60 * 1000;
Expand All @@ -11,6 +15,77 @@ const nightly = (hoursAgo, overrides = {}) => ({
...overrides,
});

function releaseSourceFixture({
comparisonStatus = "ahead",
eventName = "workflow_dispatch",
ref = "refs/heads/main",
sha = "candidate",
} = {}) {
const calls = [];
return {
calls,
options: {
context: {
eventName,
payload: { repository: { default_branch: "main" } },
ref,
repo: { owner: "example", repo: "app" },
sha,
},
github: {
rest: {
repos: {
async compareCommitsWithBasehead(params) {
calls.push(params);
return { data: { status: comparisonStatus } };
},
},
},
},
},
};
}

test("allows preview releases from any branch without consulting main", async () => {
const { options, calls } = releaseSourceFixture({ ref: "refs/heads/feature" });
await assertReleaseSource({ ...options, releaseChannel: "preview" });
assert.equal(calls.length, 0);
});

for (const releaseChannel of ["stable", "nightly"]) {
test(`rejects a manual ${releaseChannel} release from a feature branch`, async () => {
const { options, calls } = releaseSourceFixture({ ref: "refs/heads/feature" });
await assert.rejects(
assertReleaseSource({ ...options, releaseChannel }),
new RegExp(`${releaseChannel} releases must be dispatched from main`),
);
assert.equal(calls.length, 0);
});

test(`allows a manual ${releaseChannel} release from main`, async () => {
const { options, calls } = releaseSourceFixture();
await assertReleaseSource({ ...options, releaseChannel });
assert.equal(calls[0].basehead, "candidate...main");
});
}

for (const comparisonStatus of ["behind", "diverged"]) {
test(`rejects a release commit that is ${comparisonStatus} from main`, async () => {
const { options } = releaseSourceFixture({ comparisonStatus, eventName: "push" });
await assert.rejects(
assertCommitOnDefaultBranch({ ...options, sha: "release-commit" }),
new RegExp(`not contained in main \\(${comparisonStatus}\\)`),
);
});
}

test("accepts a release commit already contained in main", async () => {
for (const comparisonStatus of ["ahead", "identical"]) {
const { options } = releaseSourceFixture({ comparisonStatus, eventName: "push" });
await assertCommitOnDefaultBranch({ ...options, sha: "release-commit" });
}
});

function fixture({ releases = [nightly(7)], comparisonStatus = "ahead" } = {}) {
const calls = [];
return {
Expand Down
76 changes: 76 additions & 0 deletions .github/scripts/stage-preview-bundle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""Stage an untrusted preview ZIP without letting it replace packaging code."""

import shutil
import stat
import sys
import zipfile
from pathlib import Path

ROOTS = ("server/dist", "desktop/dist-electron")
REQUIRED_FILES = {
"server/dist/bin.mjs",
"server/dist/client/index.html",
"desktop/dist-electron/main.cjs",
}
# The current bundle is about 32 MiB compressed. Bound extraction on the
# trusted runner even when the PR replaces the uploader entirely.
MAX_ARCHIVE_BYTES = 512 * 1024 * 1024
MAX_EXPANDED_BYTES = 2 * 1024 * 1024 * 1024
MAX_ENTRIES = 50_000


def stage_bundle(archive: Path, destination: Path):
if archive.stat().st_size > MAX_ARCHIVE_BYTES:
raise ValueError("Preview archive is too large")
with zipfile.ZipFile(archive) as bundle:
entries = bundle.infolist()
if len(entries) > MAX_ENTRIES:
raise ValueError("Preview archive has too many entries")
if sum(entry.file_size for entry in entries) > MAX_EXPANDED_BYTES:
raise ValueError("Expanded preview bundle is too large")
seen = set()
files = set()
for entry in entries:
name = entry.filename.removesuffix("/")
parts = name.split("/")
# Reject ambiguous paths before normalization, including names
# that would alias on the macOS signing runner.
if (
entry.orig_filename != entry.filename
or any(part in ("", ".", "..") for part in parts)
or any(char in name for char in "\\:")
or not name.isascii()
or any(ord(char) < 32 or ord(char) == 127 for char in name)
):
raise ValueError(f"Unsafe preview path: {entry.filename!r}")
allowed = any(name.startswith(root + "/") for root in ROOTS)
if entry.is_dir():
allowed |= any(root == name or root.startswith(name + "/") for root in ROOTS)
if not allowed:
raise ValueError(f"Unexpected preview path: {name!r}")
kind = stat.S_IFMT(entry.external_attr >> 16)
if kind not in (0, stat.S_IFDIR if entry.is_dir() else stat.S_IFREG):
raise ValueError(f"Non-regular preview entry: {name!r}")
if name.casefold() in seen:
raise ValueError(f"Duplicate preview path: {name!r}")
seen.add(name.casefold())
if not entry.is_dir():
files.add(name)
if not REQUIRED_FILES <= files:
raise ValueError("Preview bundle is missing required entry points")
# Validate all names before writing anything. This is a fresh directory
# outside the checkout; neither pre-existing links nor trusted files
# can be followed or overwritten. ZIP permissions are never restored.
destination.mkdir(parents=True, exist_ok=False)
for entry in entries:
target = destination / entry.filename
if entry.is_dir():
target.mkdir(parents=True, exist_ok=True)
else:
target.parent.mkdir(parents=True, exist_ok=True)
with bundle.open(entry) as source, target.open("xb") as output:
shutil.copyfileobj(source, output)


if __name__ == "__main__":
stage_bundle(Path(sys.argv[1]), Path(sys.argv[2]))
Loading
Loading