Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
274 commits
Select commit Hold shift + click to select a range
6eed953
perf(mobile): remove unused Home project sorting (#16177)
juliusmarminge Oct 8, 2026
7873504
perf(mobile): reduce move-menu index allocations (#16256)
juliusmarminge Oct 8, 2026
6c1ce06
perf(mobile): skip impossible thread-key lookups (#16263)
juliusmarminge Oct 8, 2026
c001e19
fix(mobile): collect UI runtime garbage on iOS memory warnings (#16296)
juliusmarminge Oct 8, 2026
5c2798d
fix(mobile): stop Git sheet refresh loop (#16305)
juliusmarminge Oct 8, 2026
4fec120
fix(mobile): refresh Git status after reconnect (#16329)
juliusmarminge Oct 8, 2026
833a03a
fix(mobile): update the iOS Git header menu when status changes (#16330)
juliusmarminge Oct 8, 2026
b402f5f
perf(mobile): reuse the settled sort when settled rows are unchanged …
juliusmarminge Oct 8, 2026
33afd5a
perf(mobile): highlight source files in small batches that keep gramm…
juliusmarminge Oct 8, 2026
12865b4
feat(web): quote chips show what you said about the quote (#15703)
flamboh Oct 8, 2026
ff9eb8b
feat(web): projectless threads show their machine in the sidebar (#17…
flamboh Oct 8, 2026
57f96e6
fix(lineage): keep agent effort and speed after completion (#16925)
Bil0000 Oct 8, 2026
97a65a3
fix(mobile): align diff scrolling with glass headers (#17085)
juliusmarminge Oct 8, 2026
73e097b
fix(web): workspace page headers can no longer grow past the top-bar …
maria-rcks Oct 8, 2026
30cc788
feat(mobile): redesign the Add environment sheet (#17092)
juliusmarminge Oct 8, 2026
d6f47ff
feat(providers): run Muse Code as a native provider (#17082)
t3dotgg Oct 8, 2026
0647c48
feat(web): compact-before-send is a chip that shows the token count (…
t3dotgg Oct 8, 2026
2ea7684
fix(clients): copy button is back in its old spot, before fork (#17137)
t3dotgg Oct 8, 2026
4d1f24b
fix(usage): repeat usage scans no longer decode unchanged Antigravity…
t3dotgg Oct 8, 2026
1f31906
fix(server): shell snapshots no longer block other database reads whi…
t3dotgg Oct 8, 2026
10e29a2
perf(server): ACP tool updates no longer persist a snapshot per strea…
darjss Oct 8, 2026
13c5328
feat(web): filter the Usage page to just the providers you want (#16970)
t3dotgg Oct 8, 2026
9381533
fix(usage): Cursor account history loads about 4x faster (#17140)
t3dotgg Oct 8, 2026
0ce6b9d
fix(server): threads settle as soon as branch status sees their PR me…
t3dotgg Oct 8, 2026
8597558
perf(usage): the Usage page shows numbers in under a second and dims …
t3dotgg Oct 8, 2026
37eaf5d
fix(server): an agent can settle its own thread when its turn ends (#…
t3dotgg Oct 8, 2026
5e22256
feat(web): Add provider button sits with the provider list (#17152)
t3dotgg Oct 8, 2026
a4c9494
fix(web): link pull requests to threads in folders that aren't Git re…
shivamhwp Oct 8, 2026
12069ee
feat(web): find messages and plans in the current thread (#10439)
Noojuno Oct 8, 2026
9a3070b
feat(web): improve terminal scrollback navigation and snapshots (#17091)
StiensWout Oct 8, 2026
a65b438
docs(internals): add a checklist for adding a provider (#17229)
juliusmarminge Oct 8, 2026
a6ec88f
fix(mobile): keep native screens ordered during stack pops (#17231)
juliusmarminge Oct 8, 2026
4daec10
fix(server): pairing tokens work on Node versions that cannot bind bo…
chisewaguri Oct 8, 2026
61b9790
fix(mobile): HTML pages in a thread no longer trap scrolling on Andro…
SunkenInTime Oct 8, 2026
07a8b9e
fix(web): centered scrollers no longer shift when the scrollbar appea…
maria-rcks Oct 8, 2026
62a5d37
fix(web): distinguish thread search matches from code tints (#17263)
Yash-Singh1 Oct 8, 2026
f999eb2
fix(server): Pi extension wakes get an owned continuation turn (#17214)
StiensWout Oct 8, 2026
de72286
fix(server): Pi discovers optional T3 tools on demand (#17220)
StiensWout Oct 8, 2026
eb1cf7b
fix(web): stack merge dialog closes as soon as you confirm (#17116)
flamboh Oct 8, 2026
e8f5850
fix(server): Pi editor dialogs prefill the answer composer (#17206)
StiensWout Oct 8, 2026
a0066d5
fix(desktop): generate valid User-Agent that follows RFC 9110 guideli…
jztmanyl Oct 8, 2026
0b6ec43
fix(server): Pi discovers workspace skills and commands (#17190)
StiensWout Oct 8, 2026
805967a
fix(mobile): preserve navigation after native swipe back (#17268)
juliusmarminge Oct 8, 2026
fd25c42
fix(server): keep newly discovered models out of legacy groups (#14314)
Bil0000 Oct 8, 2026
df616cc
feat(editors): open remote projects in JetBrains IDEs over SSH (#17271)
juliusmarminge Oct 8, 2026
740f591
test(desktop): expect JetBrains IDEs among remote editors (#17291)
juliusmarminge Oct 8, 2026
cdd331b
fix(server): recognize authenticated GitHub Enterprise hosts (#11059)
alimek Oct 8, 2026
2a93885
fix(connect): relay client updates itself and skips incompatible clou…
juliusmarminge Oct 8, 2026
bd565bd
fix(shared): relay client install waits out a brief Windows file lock…
ScottN-PV Oct 8, 2026
c377d1c
fix(shared): release relay install locks on cancellation (#10585)
yashranaway Oct 8, 2026
af3d842
chore(shared): bump managed cloudflared to 2026.10.0 (#11184)
bompus Oct 8, 2026
5809487
fix(shared): bound cloudflared download with 10-minute timeout (#14139)
kvnloo Oct 8, 2026
9eea28b
refactor(provider-core): add provider-core and provider-testing packa…
juliusmarminge Oct 8, 2026
2c11607
refactor(settings): drop the legacy per-driver providers map (#17300)
juliusmarminge Oct 8, 2026
9b0df13
refactor(provider-pi): move Pi into its own provider package (#17302)
juliusmarminge Oct 8, 2026
7b57b72
feat(models): tell users when a CLI update unlocks a new model (#17307)
juliusmarminge Oct 8, 2026
48b71f0
fix(web): collapsed composer reserves room for wide send actions (#17…
maria-rcks Oct 8, 2026
d81afa0
fix(muse): workflow subagents no longer stall on hidden approvals (#1…
t3dotgg Oct 8, 2026
e38b6a1
refactor(provider-core): share attachment prompts, notifications, and…
juliusmarminge Oct 8, 2026
741377c
fix(web): file previews handle downloads, in-page links, and repo pat…
juliusmarminge Oct 8, 2026
5754121
fix(server): environment-hosted browser tabs behave like a normal bro…
juliusmarminge Oct 8, 2026
d9f7c0c
fix(desktop): browser tab fixes for fullscreen, shortcuts, links, rel…
juliusmarminge Oct 8, 2026
66298aa
fix(web): desktop opens remote environments' browser tabs locally (#1…
juliusmarminge Oct 8, 2026
3bfbc37
fix(desktop): the t3 command warns instead of installing behind anoth…
juliusmarminge Oct 8, 2026
e0c80c1
fix(web): images, video, HTML and PDF preview in a thread before its …
juliusmarminge Oct 8, 2026
5b78b34
refactor(provider-muse): move Muse Code into its own provider package…
juliusmarminge Oct 8, 2026
6308db4
fix(web): semantic branch naming hint lines up with its setting (#16972)
limineol Oct 8, 2026
393ff4c
fix(mobile): restore chat image previews in the v5 stack (#17361)
juliusmarminge Oct 8, 2026
c724c7c
feat(mobile): fade working threads and match web's status labels (#17…
juliusmarminge Oct 9, 2026
dbd8343
fix(server): agent browser tools stop bloating history, fall back sen…
juliusmarminge Oct 9, 2026
29980a3
fix(web): add room for thread timeline markers (#17372)
Yash-Singh1 Oct 9, 2026
b0ee7dd
fix(web): drop sidebar context before cancelling pointer drag (#17373)
Yash-Singh1 Oct 9, 2026
2c7a446
refactor(providers): namespace-import service modules in core, Muse, …
juliusmarminge Oct 9, 2026
456930a
fix(auth): show connection permissions and enforce session lifetime (…
juliusmarminge Oct 9, 2026
e62161b
refactor(provider-opencode): move OpenCode into its own provider pack…
juliusmarminge Oct 9, 2026
b5e4f1e
refactor(provider-cursor): move Cursor into its own provider package …
juliusmarminge Oct 9, 2026
664bd5e
refactor(provider-acp): move the shared ACP adapter into its own pack…
juliusmarminge Oct 9, 2026
b707eeb
refactor(provider-grok): move Grok into its own provider package (#17…
juliusmarminge Oct 9, 2026
42c6623
fix(server): speed up long thread message sync (#17387)
Yash-Singh1 Oct 9, 2026
c9fa136
fix(desktop): cancel backend pipe reads to avoid slow shutdown (#17386)
Yash-Singh1 Oct 9, 2026
b000eac
refactor(providers): adapter factories yield their services (#17381)
juliusmarminge Oct 9, 2026
5785df1
fix(web): show a row spinner instead of a banner when expanding a fol…
juliusmarminge Oct 9, 2026
8f76037
fix(server): a timed-out browser drag no longer exits the server (#17…
ScottN-PV Oct 9, 2026
563645c
fix(server): a logged-out Claude CLI no longer reports as authenticat…
yordis Oct 9, 2026
3b6af0b
fix(server): Pi loads every selected skill without losing prompt text…
StiensWout Oct 9, 2026
c908cea
fix(server): keep the Claude MCP token out of process arguments (#17408)
juliusmarminge Oct 9, 2026
7a2b1c7
fix(server): reconcile Pi native session rewinds (#13839)
StiensWout Oct 9, 2026
cb46c62
test(provider-pi): cover continuation offers through the driver (#17407)
juliusmarminge Oct 9, 2026
43f8a8d
refactor(provider-acp-registry): move the ACP Registry into its own p…
juliusmarminge Oct 9, 2026
101f8b2
fix(server): relay client updates no longer drop the host off T3 Conn…
t3dotgg Oct 9, 2026
ec80933
fix(connect): Cloudflare and other VPN addresses no longer show as Ta…
shivamhwp Oct 9, 2026
2cf0ff0
fix(web): Local environment switch stays reachable after turning it o…
ScottN-PV Oct 9, 2026
c5d4d2d
fix(web): keep chat banners inside the lane beside the docked details…
macodev00 Oct 9, 2026
a947f7c
fix(web): settled and snoozed lines line up with the messages above t…
RakshithBhat03 Oct 9, 2026
22ccf8a
fix(web): distinguish project filter from new project (#12113)
voltcrash Oct 9, 2026
b150867
feat(web): assign a thread details panel shortcut (#16694)
maria-rcks Oct 9, 2026
a669827
fix(web): chat content keeps pace with sidebar resizing (#17383)
flamboh Oct 9, 2026
2c1915b
refactor(provider-core): expose model metadata through a ModelCatalog…
juliusmarminge Oct 9, 2026
b66dd40
refactor(provider-core): follow the Effect service conventions throug…
juliusmarminge Oct 9, 2026
68ab16f
refactor(provider-core): latest-version lookups go through a Provider…
juliusmarminge Oct 9, 2026
784b562
refactor(provider-core): MCP provider sessions live in a McpProviderS…
juliusmarminge Oct 9, 2026
31b04e2
refactor(provider): bring opencode, muse, pi, core and testing in lin…
juliusmarminge Oct 9, 2026
f853d51
refactor(provider-acp): ACP, ACP Registry and Grok follow the Effect …
juliusmarminge Oct 9, 2026
33806e7
refactor(provider-cursor): follow the Effect service conventions (#17…
juliusmarminge Oct 9, 2026
6497246
fix(marketing): use app wordmark in header (#13240)
voltcrash Oct 9, 2026
aa8c666
fix(web): pr merge actions stay visible while the stack refreshes (#1…
maria-rcks Oct 9, 2026
91a6646
chore(deps): upgrade Effect to 4.0.2 (#17571)
juliusmarminge Oct 9, 2026
ecfb734
fix(devices): recover stalled video without losing simulator input (#…
juliusmarminge Oct 9, 2026
7856908
fix(web): keep checkout stable while pr actions load (#16625)
maria-rcks Oct 9, 2026
1fd558d
fix(mobile): show waiting thread status (#16693)
maria-rcks Oct 9, 2026
5722496
feat(web): add parent thread breadcrumb navigation (#16666)
maria-rcks Oct 9, 2026
0a4d789
fix(server): restart inactivity after snoozed threads wake (#16674)
maria-rcks Oct 9, 2026
454b94a
feat(desktop): passkeys in the in-app browser on macOS (#16952)
juliusmarminge Oct 9, 2026
a1db449
fix(client): load earlier turns works for MCP threads over T3 Connect…
juliusmarminge Oct 9, 2026
0e7abea
refactor(client): sign relay request URLs built from the HttpApi cont…
juliusmarminge Oct 9, 2026
28f11ed
refactor(source-control): add @t3tools/source-control-core (#17573)
juliusmarminge Oct 9, 2026
f6e4502
refactor(source-control): Forgejo lives in @t3tools/source-control-fo…
juliusmarminge Oct 9, 2026
d01febb
refactor(source-control): Azure DevOps lives in @t3tools/source-contr…
juliusmarminge Oct 9, 2026
eb459b5
refactor(source-control): GitLab lives in @t3tools/source-control-git…
juliusmarminge Oct 9, 2026
8d1858d
refactor(source-control): Bitbucket lives in @t3tools/source-control-…
juliusmarminge Oct 9, 2026
507361b
refactor(source-control): GitHub lives in @t3tools/source-control-git…
juliusmarminge Oct 9, 2026
e5dca23
refactor(usage): transcript readers come from their drivers (#17576)
juliusmarminge Oct 9, 2026
23957c7
refactor(usage): OpenCode usage comes from provider-opencode (#17577)
juliusmarminge Oct 9, 2026
5a9c664
refactor(usage): Cursor account usage comes from provider-cursor (#17…
juliusmarminge Oct 9, 2026
9a0766b
refactor(usage): Antigravity usage is a reader on its driver (#17579)
juliusmarminge Oct 9, 2026
b1ec4b3
refactor(usage): usage readers use Effect FileSystem and SqlClient (#…
juliusmarminge Oct 9, 2026
6586a01
fix(web): composer context strip pads both edges evenly (#17562)
limineol Oct 9, 2026
a0a0e94
test(usage): v4 cache upgrade test waits for the migrated cache write…
Mnigos Oct 9, 2026
c85dc64
feat(mobile): support Duo in the shared iOS app (#12648)
juliusmarminge Oct 9, 2026
49f849e
refactor(source-control): GitManager reads provider resolvers, not ho…
juliusmarminge Oct 9, 2026
2ce3e4a
refactor(source-control): PullRequestService reads GitHub resolvers, …
juliusmarminge Oct 9, 2026
51347ac
refactor(source-control): Forgejo identity and Azure DevOps addressin…
juliusmarminge Oct 9, 2026
58916b6
refactor: home directory comes from a HostProcessHomeDirectory refere…
juliusmarminge Oct 9, 2026
e308522
refactor(shared): host process references live in a HostProcess modul…
juliusmarminge Oct 9, 2026
6cd02e9
feat(web): filter PR comments by bots and resolved threads (#17645)
juliusmarminge Oct 9, 2026
0c40120
fix(clients): remove redundant prefix from PR watch status (#17635)
extoci Oct 9, 2026
99d2651
fix(web): pending requests wait until you stop typing (#17637)
maria-rcks Oct 9, 2026
08e18b7
fix(models): remove new badges from Claude Opus and Sonnet 5.5 (#17646)
extoci Oct 9, 2026
5dcb59e
fix(ui): keep focus and selection borders visible across the app (#16…
maria-rcks Oct 9, 2026
5fe9d02
fix(mobile): prevent row presses during native back swipes (#17648)
juliusmarminge Oct 9, 2026
140ee14
fix(server): Codex shadow homes replace stray sqlite maintenance lock…
juliusmarminge Oct 10, 2026
3857132
feat(desktop): T3 Code can be your default web browser on macOS (#17587)
juliusmarminge Oct 10, 2026
202b954
test(server): the ACP process-tree test no longer collides with the r…
yordis Oct 10, 2026
cc62349
fix(web): keep branch restore action inline in narrow composers (#14811)
Saikrishna1876 Oct 10, 2026
3e94afa
fix(web): composer banner actions stay inline whenever they fit (#17640)
maria-rcks Oct 10, 2026
b744bde
feat(web): draft screen project picker is searchable (#17664)
juliusmarminge Oct 10, 2026
b87b13d
fix(server): report incomplete transcript usage scans (#15661)
maria-rcks Oct 10, 2026
d970607
fix(web): every resize-driven layout commits in the same frame (#17656)
maria-rcks Oct 10, 2026
ca40de0
fix(web): right panel and terminal drawer follow the pointer while dr…
maria-rcks Oct 10, 2026
42e1a0f
fix(web): terminal drawer keeps its height after the window shrinks (…
maria-rcks Oct 10, 2026
033866c
perf(web): sidebar drags restyle only the sidebar (#17659)
maria-rcks Oct 10, 2026
eddc8fb
fix(web): server browser page resizes while the panel is dragged (#17…
maria-rcks Oct 10, 2026
0caa95d
fix(storage): make worktree cleanup work and show why it skipped (#17…
maria-rcks Oct 10, 2026
e858ddb
test(usage): usage service tests keep their state directory until cac…
tris203 Oct 10, 2026
f3a69c7
fix(checkpoint): pulls and rebases no longer flood a turn's changed f…
t3dotgg Oct 10, 2026
07b8080
fix(web): place notification icons after titles (#12209)
voltcrash Oct 10, 2026
0b9623f
fix(web): attachments on an open question are visible again (#15537)
tiliakoos Oct 10, 2026
f34adad
fix(web): scale Files tree with interface font size (#8011)
Umais-Adeed Oct 10, 2026
318201c
fix(server): probe only owned preview listeners (#16687)
maria-rcks Oct 10, 2026
ed4ea10
fix(chat): surface pending subagent questions on parents (#16634)
maria-rcks Oct 10, 2026
c1f21e5
fix(web): section header chevrons point up when collapsed (#14273)
ZenderGoD Oct 10, 2026
e08c31e
fix(web): timeline divider pill shows a pointer, visible hover and fo…
jonesfionn101-dotcom Oct 10, 2026
6e4ca6c
fix(git): allow creating prs from dirty worktrees (#15625)
maria-rcks Oct 10, 2026
b822420
docs(install): polish binary install destination phrasing (#15732)
ege-arhan Oct 10, 2026
0981e6b
perf(server): keep passive terminal output flowing (#17178)
StiensWout Oct 10, 2026
b6aa268
fix(web): stop button icon no longer shifts on hover (#16012)
NK-Works Oct 10, 2026
9bbbbba
fix(web): add bottom padding to expanded tool panels (#16525)
12ya Oct 10, 2026
2def3de
fix(web): keep incremental highlighter return type portable (#17259)
luke2x Oct 10, 2026
391f813
fix(web): sidebar "Code" label no longer clips its letter tops (#16134)
akbarakma Oct 10, 2026
699da95
fix(tests): use POSIX paths for the simulated macOS device host (#17241)
Quicksaver Oct 10, 2026
88edfac
fix(mobile): Android composer keeps the caret in view on AOSP-based k…
bitmvk Oct 10, 2026
467fea9
test(web): allow cold timeline imports on CI (#16608)
lastobelus Oct 10, 2026
aa165e9
fix(mobile): pinch zooms chat images on Android (#15047)
AKolenda Oct 10, 2026
d1e56e7
fix(web): selected provider ring no longer clipped during panel resiz…
jfortez Oct 10, 2026
d50a2a6
docs(usage): OpenCode Go limits need a Go API key (#15664)
nexxeln Oct 10, 2026
c116dac
fix(web): improve usage scanning indicator alignment (#15498)
AksharP5 Oct 10, 2026
97009b0
fix(server): print pairing credential expiry as ISO timestamp (#14128)
kvnloo Oct 10, 2026
2cc55f2
chore(ci): use GPT 6.1 Sol Max for check agents (#14312)
ishaanko Oct 10, 2026
8b81a88
fix(mobile): honor requested terminal native architectures (#10709)
bompus Oct 10, 2026
5c715c6
fix(server): keep preview browser connected after operation timeouts …
juliusmarminge Oct 10, 2026
aacefcd
fix(web): timeline divider focus ring stays inside the pill (#17702)
t3dotgg Oct 10, 2026
03bd839
perf(desktop): reuse the prepared shell environment in the local back…
Yash-Singh1 Oct 10, 2026
f02002a
fix(web): align settings page widths (#12158)
diegoarff Oct 10, 2026
a3d1505
test(server): resolve the temp dir before matching the symlinked entr…
ylcn91 Oct 10, 2026
6e83160
fix(web): keep inline code pills intact when they wrap (#12038)
satyalyadav Oct 10, 2026
2aa033b
Revert "chore(ci): use GPT 6.1 Sol Max for check agents" (#17698)
maria-rcks Oct 10, 2026
f55c66b
fix(web): show the correct new thread shortcut in command palette (#8…
vaishnavsm Oct 10, 2026
c1ade7d
fix(desktop): declare macOS local network usage (#11922)
jsilets Oct 10, 2026
968ac2e
docs: add Scoop as Windows installation method (#10509)
Mostafa-Ben-Git Oct 10, 2026
a0a601c
fix(server): agents run in their own systemd scopes so an OOM kill sp…
t3dotgg Oct 10, 2026
4ea7356
fix(web): welcome wizard says where imported projects come from (#14584)
UzEE Oct 10, 2026
d02e292
fix(web): cite works on responses that end before a tool call (#17713)
maria-rcks Oct 10, 2026
fa9f936
fix(desktop): sign Windows native addons (#8206)
Lumbreras2306 Oct 10, 2026
c572cb7
fix(server): track resumed subagent follow-ups as separate tasks (#17…
Yash-Singh1 Oct 10, 2026
c2a301b
fix(web): nested corners follow their container's radius (#17695)
maria-rcks Oct 10, 2026
1f093d1
feat(web): pr panel actions confirm in place (#17710)
maria-rcks Oct 10, 2026
4107930
feat(web): reorder right panel tabs by dragging (#17730)
eimexdev Oct 10, 2026
c899a0c
fix(azure-devops): list pull requests with token sign-in and check ou…
maria-rcks Oct 10, 2026
0be20c8
fix(usage): keep one email in two workspaces as two accounts (#17711)
maria-rcks Oct 10, 2026
c3243f0
feat(pull-requests): hosts can report edit and resolve permissions pe…
juliusmarminge Oct 10, 2026
9cc5768
perf(server): run Git for Windows' real git.exe, not its launcher (#1…
SunkenInTime Oct 10, 2026
a7223f3
fix(clients): restart continuations show as a T3 Code notice, not ano…
juliusmarminge Oct 10, 2026
57b3780
fix(mobile): browser picture in picture opens from the header button …
juliusmarminge Oct 10, 2026
65d3317
feat(source-control): GitCafe lives in @t3tools/source-control-gitcaf…
juliusmarminge Oct 10, 2026
500cb42
fix(web): add provider wizard no longer shifts sideways while it grow…
flamboh Oct 10, 2026
42f71df
fix(web): PR search keeps the caret where you type (#17675)
flamboh Oct 10, 2026
6d5ea19
fix(server): thread PR badges catch up when another environment reads…
flamboh Oct 10, 2026
bd2346e
fix(server): refuse editor paths with line breaks or quotes when the …
juliusmarminge Oct 10, 2026
c77a7b7
fix(web): align compact button touch targets (#17748)
Yash-Singh1 Oct 10, 2026
6266af3
fix(server): t3_thread_launch refuses a new worktree whose base ref h…
tris203 Oct 10, 2026
d6f3af7
fix(web): omit underlines on markdown image links (#17728)
Saikrishna1876 Oct 10, 2026
4606f9d
fix(server): restore auto resume for wrapped Claude gateway rate limi…
tzachbon Oct 10, 2026
e1ad595
fix(opencode): name OpenCode 2 sessions after their thread (#17414)
nkoynov Oct 10, 2026
472ea7e
fix(web): find update settings from the command palette (#17396)
sergical Oct 10, 2026
7b09ac7
fix(provider-opencode): tell OpenCode Zen and Go models apart (#17424)
mr-karan Oct 10, 2026
adbecda
fix(server): a pull that fast-forwards no longer fails on large Git o…
ScottN-PV Oct 10, 2026
91474e5
fix(web): cancel question auto-advance after navigation (#17364)
maxwellyoung Oct 10, 2026
33c1e36
fix(server): a bare repository name resolves to the signed-in account…
ScottN-PV Oct 10, 2026
71f6f1d
fix(web): a maximized right panel stays maximized when you return to …
jamesvillarrubia Oct 10, 2026
02612c2
fix(mobile): allow starting a task with only an image (#17409)
Claudesaul Oct 10, 2026
a418075
fix(server): PR watch no longer reports passed while a second run of …
ScottN-PV Oct 10, 2026
a5b4824
fix(server): say why a thread can't be settled (#17258)
DylanTX Oct 10, 2026
03b2105
fix(server): prevent busy terminals from starving history persistence…
StiensWout Oct 10, 2026
de49d63
feat(server): use macOS .icns app icons as project icons (#17149)
psv2522 Oct 10, 2026
a1dee8b
fix(mobile): usage reset icon lines up with its row (#17175)
Aforno Oct 10, 2026
ee7924f
fix(web): paths pasted after @ keep their underscores (#16619)
derektrimm Oct 10, 2026
dd4549e
fix(server): settle every OpenCode subagent call one report answers (…
nkoynov Oct 10, 2026
8bf0a38
perf(web): switching project keeps Diagnostics and Providers mounted …
flamboh Oct 10, 2026
f7664fd
perf(web): Open Source Licenses downloads its manifest once per sessi…
flamboh Oct 10, 2026
94d1a8e
fix(server): restore OpenCode adapter test typecheck (#17810)
Yash-Singh1 Oct 10, 2026
98beed1
fix(server): Claude subagents show the reasoning effort they run at (…
RakshithBhat03 Oct 10, 2026
8c777fb
feat(server): stop Claude subagents without stopping their owner (#17…
Yash-Singh1 Oct 10, 2026
afd98d7
fix(server): stopped native subagents no longer read as Running (#17223)
im-kvijay Oct 10, 2026
a11f464
perf(server): t3_thread_list reads only the listed project's threads …
only21mil Oct 10, 2026
cfbd145
fix(server): show diffs for projects outside the server cwd (#17724)
maria-rcks Oct 10, 2026
50647de
fix(server): check the specific scope for scripts, preview input, and…
juliusmarminge Oct 10, 2026
dacd2cb
fix(source-control): stop Forgejo status refresh from scanning every …
loispostula Oct 10, 2026
fd3549c
refactor(contracts): source control provider kind is an open branded …
juliusmarminge Oct 10, 2026
7bc7328
feat(source-control): each host package ships a client definition (#1…
juliusmarminge Oct 10, 2026
c8a6033
refactor(client-runtime): add project clone sources come from host de…
juliusmarminge Oct 10, 2026
579159d
refactor(web): host presentation and behavior come from client defini…
juliusmarminge Oct 10, 2026
b0249ac
refactor(source-control): reference parsing and project matching are …
juliusmarminge Oct 10, 2026
9b40d37
feat(pull-requests): quick actions follow each host's capabilities, n…
juliusmarminge Oct 10, 2026
a4c8745
feat(projects): new projects can be published to any ready host (#17860)
juliusmarminge Oct 10, 2026
f82796a
fix(server): send Claude MCP servers over the control channel (#17898)
juliusmarminge Oct 10, 2026
ec43786
fix(web): a finished reply replaced by a steer is no longer labeled p…
juliusmarminge Oct 10, 2026
61eb4af
fix(client-runtime): queued runs that start after a steer show up in …
juliusmarminge Oct 10, 2026
2a4ee33
feat(mobile): choose the microphone order for voice input (#17896)
juliusmarminge Oct 10, 2026
4f63275
feat(source-control): host settings live on each host's definition, w…
juliusmarminge Oct 10, 2026
c091df8
Merge upstream v0.0.46-nightly.20261010.2948 into custom/usage-badge
Oct 11, 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
  •  
  •  
  •  
23 changes: 1 addition & 22 deletions .coderabbit.config.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
import { defineConfig, type CodeRabbitContext } from "@coderabbitai/config";

const approvability = `Fail when a maintainer should read this pull request before CodeRabbit approves it, and name the rule and file. Fail if it:

- Changes a product default: a setting's default value, or what users get without opting in. Making a feature do what it already promises is a bug fix, not a default change.
- Adds or broadens a directive that disables or suppresses a lint, type-checker, LSP, or other static-analysis diagnostic, including file-level, line-level, and configuration-level overrides.
- Adds a subsystem or user workflow, or is a large refactor across apps or packages.
- Changes packages/contracts or persisted data in a way that existing clients or stored data might not accept.
- Changes authentication, pairing, credentials, secrets, or remote connection trust.
- Adds or changes an external side effect, such as acting on GitHub, publishing a release, or calling a webhook.
- Adds, upgrades, or patches a dependency.
- Changes CI or release configuration, agent or contributor instructions, or any review tool's configuration, including .github/, AGENTS.md, CONTRIBUTING.md, .agents/, and .coderabbit.config.ts.

Otherwise pass. A focused bug fix, copy or layout fix, revert, or docs-only or test-only change passes unless a rule above applies. If you cannot decide, fail rather than report inconclusive. When failing, say that the pull request needs a maintainer's review.
`;

// Org members and collaborators merge their own pull requests. On anyone else's, CodeRabbit
// requests changes until its comments are resolved and its checks pass, then approves.
// requests changes until its comments are resolved, then approves.
const UNGATED_AUTHORS = new Set(["OWNER", "MEMBER", "COLLABORATOR"]);
const isGated = ({ pr }: CodeRabbitContext) => !UNGATED_AUTHORS.has(pr?.authorAssociation ?? "");

Expand All @@ -31,13 +17,6 @@ export default defineConfig((ctx) => ({
pre_merge_checks: {
docstrings: { mode: "off" },
override_requested_reviewers_only: isGated(ctx),
custom_checks: [
{
name: "Approvability",
mode: isGated(ctx) ? "error" : "off",
instructions: approvability,
},
],
},
path_filters: [
// Vendored read-only reference checkouts of upstream Effect and Alchemy
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ Install the latest version of the desktop app from [GitHub Releases](https://git
winget install T3Tools.T3Code
```

#### Windows (`scoop`)

```bash
scoop install extras/t3code
```

#### macOS (Homebrew)

```bash
Expand Down
6 changes: 4 additions & 2 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@
"@t3tools/tailscale": "workspace:*",
"dbus-next": "0.10.2",
"effect": "catalog:",
"electron": "44.4.2",
"electron": "44.4.5",
"electron-store": "^8.2.0",
"electron-updater": "^6.8.9",
"electron-webauthn": "catalog:",
"ffi-rs": "1.3.2",
"playwright-core": "1.60.0",
"react-grab": "^0.1.32"
"react-grab": "^0.1.32",
"tldts": "catalog:"
},
"devDependencies": {
"@effect/vitest": "catalog:",
Expand Down
8 changes: 7 additions & 1 deletion apps/desktop/src/app/DesktopApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import * as DesktopAppIdentity from "./DesktopAppIdentity.ts";
import * as DesktopClerk from "./DesktopClerk.ts";
import * as DesktopApplicationMenu from "../window/DesktopApplicationMenu.ts";
import * as DesktopWindow from "../window/DesktopWindow.ts";
import * as PreviewPasskeys from "../preview/Passkeys.ts";
import * as DesktopBackendPool from "../backend/DesktopBackendPool.ts";
import * as DesktopEnvironment from "./DesktopEnvironment.ts";
import * as DesktopLegacyLocalStorage from "./DesktopLegacyLocalStorage.ts";
Expand All @@ -34,6 +35,7 @@ import * as DesktopUpdates from "../updates/DesktopUpdates.ts";
import * as DesktopSnapShot from "../snapShot/DesktopSnapShot.ts";
import * as DesktopWslBackend from "../wsl/DesktopWslBackend.ts";
import * as DesktopRendererHistory from "../telemetry/DesktopRendererHistory.ts";
import * as HostProcess from "@t3tools/shared/HostProcess";

const DEFAULT_DESKTOP_BACKEND_PORT = 3773;
const MAX_TCP_PORT = 65_535;
Expand Down Expand Up @@ -276,13 +278,16 @@ const startup = Effect.gen(function* () {
const safeStorage = yield* ElectronSafeStorage.ElectronSafeStorage;
const updates = yield* DesktopUpdates.DesktopUpdates;
const environment = yield* DesktopEnvironment.DesktopEnvironment;
const previewPasskeys = yield* PreviewPasskeys.PreviewPasskeys;

yield* shellEnvironment.installIntoProcess;
const hasCommandLinePasswordStore =
preReadyElectronOptions.linuxPasswordStoreCommandLine !== null;
const linuxElectronOptions =
environment.platform === "linux" && !hasCommandLinePasswordStore
? DesktopPreReadyPlatform.resolveEarlyLinuxElectronOptionsFromProcess()
? DesktopPreReadyPlatform.resolveEarlyLinuxElectronOptionsFromProcess(
yield* HostProcess.HomeDirectory,
)
: preReadyElectronOptions.linux;
if (linuxElectronOptions !== null && !hasCommandLinePasswordStore) {
if (
Expand Down Expand Up @@ -329,6 +334,7 @@ const startup = Effect.gen(function* () {
});
}
yield* appIdentity.configure;
yield* previewPasskeys.configure;
yield* applicationMenu.configure;
yield* updates.configure;
yield* DesktopRemoteUpdates.listen;
Expand Down
18 changes: 9 additions & 9 deletions apps/desktop/src/app/DesktopAppActivation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
type DesktopAppActivationResponse,
} from "@t3tools/contracts";
import { resolveDesktopAppControlAddress } from "@t3tools/shared/desktopAppControl";
import { HostProcessPlatform, HostProcessUserId } from "@t3tools/shared/hostProcess";
import * as HostProcess from "@t3tools/shared/HostProcess";
import { it } from "@effect/vitest";
import * as Effect from "effect/Effect";
import { afterEach, describe, expect } from "vite-plus/test";
Expand Down Expand Up @@ -83,8 +83,8 @@ function exchange(address: string, payload: DesktopAppActivationRequest) {
describe("desktop app control server", () => {
it.effect("roundtrips a request and removes its socket on shutdown", () =>
Effect.gen(function* () {
const platform = yield* HostProcessPlatform;
const userId = yield* HostProcessUserId;
const platform = yield* HostProcess.Platform;
const userId = yield* HostProcess.UserId;
yield* Effect.promise(async () => {
const root = await NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "t3-app-control-test-"));
const target = makeTarget(NodePath.join(root, "userdata"), platform, userId);
Expand Down Expand Up @@ -123,8 +123,8 @@ describe("desktop app control server", () => {

it.effect("cancels a queued request when the client disconnects", () =>
Effect.gen(function* () {
const platform = yield* HostProcessPlatform;
const userId = yield* HostProcessUserId;
const platform = yield* HostProcess.Platform;
const userId = yield* HostProcess.UserId;
yield* Effect.promise(async () => {
const root = await NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "t3-app-cancel-test-"));
const target = makeTarget(NodePath.join(root, "userdata"), platform, userId);
Expand Down Expand Up @@ -162,8 +162,8 @@ describe("desktop app control server", () => {
// Two desktop apps can share one state dir, such as nightly and a preview build.
it.effect("keeps a newer app's socket when an older app on the same state dir quits", () =>
Effect.gen(function* () {
const platform = yield* HostProcessPlatform;
const userId = yield* HostProcessUserId;
const platform = yield* HostProcess.Platform;
const userId = yield* HostProcess.UserId;
if (platform === "win32") return;
yield* Effect.promise(async () => {
const root = await NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "t3-app-takeover-test-"));
Expand All @@ -183,8 +183,8 @@ describe("desktop app control server", () => {

it.effect("binds its address again after the socket file is removed", () =>
Effect.gen(function* () {
const platform = yield* HostProcessPlatform;
const userId = yield* HostProcessUserId;
const platform = yield* HostProcess.Platform;
const userId = yield* HostProcess.UserId;
if (platform === "win32") return;
yield* Effect.promise(async () => {
const root = await NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "t3-app-reclaim-test-"));
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/src/app/DesktopAppActivation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
type DesktopAppActivationResponse,
} from "@t3tools/contracts";
import { resolveDesktopAppControlAddress } from "@t3tools/shared/desktopAppControl";
import { HostProcessUserId } from "@t3tools/shared/hostProcess";
import * as HostProcess from "@t3tools/shared/HostProcess";
import * as Context from "effect/Context";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
Expand Down Expand Up @@ -315,7 +315,7 @@ export const make = Effect.gen(function* () {
const desktopWindow = yield* DesktopWindow.DesktopWindow;
const electronWindow = yield* ElectronWindow.ElectronWindow;
const path = yield* Path.Path;
const userId = yield* HostProcessUserId;
const userId = yield* HostProcess.UserId;
const runPromise = Effect.runPromiseWith(yield* Effect.context<never>());
const address = resolveDesktopAppControlAddress({
stateDir: path.resolve(desktopEnvironment.stateDir),
Expand Down
35 changes: 34 additions & 1 deletion apps/desktop/src/app/DesktopAppIdentity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ describe("DesktopAppIdentity", () => {
const identity = yield* DesktopAppIdentity.DesktopAppIdentity;
yield* identity.configure;

assert.deepEqual(calls.setName, ["T3 Code (Alpha)"]);
assert.deepEqual(calls.setName, ["T3 Code Alpha"]);
assert.equal(calls.setAboutPanelOptions[0]?.applicationName, "T3 Code (Alpha)");
assert.equal(calls.setAboutPanelOptions[0]?.applicationVersion, "1.2.3");
assert.equal(calls.setAboutPanelOptions[0]?.version, "0123456789ab");
Expand All @@ -237,6 +237,39 @@ describe("DesktopAppIdentity", () => {
);
});

it.effect.each([
{ stage: "Alpha", environment: {} },
{
stage: "Nightly",
environment: { appVersion: "0.0.43-nightly.20260929.2428" },
},
{
stage: "Dev",
environment: { env: { VITE_DEV_SERVER_URL: "http://localhost:5173" } },
},
])("uses a valid native User-Agent product name for $stage", ({ stage, environment }) => {
const calls: ElectronAppCalls = {
setAboutPanelOptions: [],
setDockIcon: [],
setName: [],
};

return withIdentity(
Effect.gen(function* () {
const identity = yield* DesktopAppIdentity.DesktopAppIdentity;
yield* identity.configure;

const runtimeName = calls.setName[0];
assert.isDefined(runtimeName);
assert.equal(runtimeName, `T3 Code ${stage}`);
// RFC 9110's token grammar, after Electron removes ASCII spaces.
assert.match(runtimeName.replaceAll(" ", ""), /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/);
assert.equal(calls.setAboutPanelOptions[0]?.applicationName, `T3 Code (${stage})`);
}),
{ calls, environment },
);
});

it.effect("sets the dock icon only when running unpackaged", () => {
const calls: ElectronAppCalls = {
setAboutPanelOptions: [],
Expand Down
7 changes: 6 additions & 1 deletion apps/desktop/src/app/DesktopAppIdentity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,12 @@ export const make = Effect.gen(function* () {

const configure = Effect.gen(function* () {
const commitHash = yield* resolveAboutCommitHash;
yield* electronApp.setName(environment.displayName);
// Electron removes spaces from this name to build the native User-Agent
// product token, but leaves parentheses intact. Keep the runtime name valid
// without rewriting preview sessions (which breaks Turnstile, #7110).
yield* electronApp.setName(
`${environment.branding.baseName} ${environment.branding.stageLabel}`,
);
yield* electronApp.setAboutPanelOptions({
applicationName: environment.displayName,
applicationVersion: environment.appVersion,
Expand Down
64 changes: 61 additions & 3 deletions apps/desktop/src/app/DesktopClerk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as NodeHttp from "node:http";
import * as NodePath from "@effect/platform-node/NodePath";
import { codexAuthHandoffUrl, readCodexAuthDelivery } from "@t3tools/shared/codexAuthHandoff";
import { EnvironmentId, ProviderInstanceId } from "@t3tools/contracts";
import { HostProcessArguments } from "@t3tools/shared/hostProcess";
import * as HostProcess from "@t3tools/shared/HostProcess";
import { assert, describe, it } from "@effect/vitest";
import * as Cause from "effect/Cause";
import * as Effect from "effect/Effect";
Expand Down Expand Up @@ -35,9 +35,16 @@ import * as ElectronApp from "../electron/ElectronApp.ts";
import * as ElectronShell from "../electron/ElectronShell.ts";
import * as ElectronWindow from "../electron/ElectronWindow.ts";
import * as DesktopClerk from "./DesktopClerk.ts";
import * as DesktopWebLinks from "./DesktopWebLinks.ts";
import * as DesktopEnvironment from "./DesktopEnvironment.ts";
import * as DesktopPreReadyFileSystem from "./DesktopPreReadyFileSystem.ts";

/** Clerk forwards web links; tests that are not about links ignore them. */
const ignoreWebLinks = DesktopWebLinks.DesktopWebLinks.of({
receive: () => Effect.void,
setRendererReady: () => Effect.void,
});

const layerDesktopClerk = (
isDevelopment = true,
events: string[] = [],
Expand Down Expand Up @@ -220,11 +227,12 @@ describe("DesktopClerk", () => {

assert.isTrue(Exit.isSuccess(exit));
assert.equal(quit.mock.calls.length, 0);
assert.deepEqual(registeredEvents, ["open-url", "second-instance"]);
assert.deepEqual(registeredEvents, ["open-url", "open-file", "second-instance"]);
}).pipe(
Effect.provide(layerDesktopClerk()),
Effect.provideService(ElectronApp.ElectronApp, electronApp),
Effect.provideService(ElectronWindow.ElectronWindow, electronWindow),
Effect.provideService(DesktopWebLinks.DesktopWebLinks, ignoreWebLinks),
);
});

Expand Down Expand Up @@ -253,6 +261,7 @@ describe("DesktopClerk", () => {
Effect.provide(layerDesktopClerk()),
Effect.provideService(ElectronApp.ElectronApp, electronApp),
Effect.provideService(ElectronWindow.ElectronWindow, electronWindow),
Effect.provideService(DesktopWebLinks.DesktopWebLinks, ignoreWebLinks),
);
});
});
Expand Down Expand Up @@ -299,6 +308,7 @@ it.effect(
Effect.provide(layerDesktopClerk()),
Effect.provideService(ElectronApp.ElectronApp, electronApp),
Effect.provideService(ElectronWindow.ElectronWindow, electronWindow),
Effect.provideService(DesktopWebLinks.DesktopWebLinks, ignoreWebLinks),
);
},
);
Expand Down Expand Up @@ -375,12 +385,60 @@ it.effect.each(["startup", "open-url"] as const)(
assert.strictEqual(delivery?.returnUrl, request.returnUrl);
}).pipe(
Effect.provide(layerDesktopClerk(true, [], "darwin", undefined, shell)),
Effect.provideService(HostProcessArguments, entry === "startup" ? ["t3", link] : ["t3"]),
Effect.provideService(HostProcess.Arguments, entry === "startup" ? ["t3", link] : ["t3"]),
Effect.provideService(ElectronApp.ElectronApp, electronApp),
Effect.provideService(
ElectronWindow.ElectronWindow,
{} as ElectronWindow.ElectronWindow["Service"],
),
Effect.provideService(DesktopWebLinks.DesktopWebLinks, ignoreWebLinks),
);
}).pipe(Effect.scoped),
);

it.effect("hands a web link to the renderer and leaves other links alone", () =>
Effect.gen(function* () {
storageMock.mockReturnValue(storageAdapter);
createClerkBridgeMock.mockReturnValue({ cleanup: vi.fn(), isPrimaryInstance: true });
const listeners = new Map<string, (...args: unknown[]) => void>();
const electronApp = {
whenReady: Effect.void,
on: (name: string, listener: (...args: unknown[]) => void) =>
Effect.sync(() => {
listeners.set(name, listener);
}),
} as unknown as ElectronApp.ElectronApp["Service"];
const received: Array<string> = [];
yield* Effect.gen(function* () {
const clerk = yield* DesktopClerk.DesktopClerk;
yield* clerk.configure;
const open = (url: string) => {
const event = { preventDefault: vi.fn() };
listeners.get("open-url")!(event, url);
return event.preventDefault.mock.calls.length;
};
// macOS hands the default browser every web link.
assert.strictEqual(open("https://example.com/page"), 1);
assert.strictEqual(open("http://localhost:3000/"), 1);
// Anything else is not a web page; Electron keeps its own handling.
assert.strictEqual(open("mailto:hello@example.com"), 0);
yield* Effect.yieldNow;
assert.deepStrictEqual(received, ["https://example.com/page", "http://localhost:3000/"]);
}).pipe(
Effect.provide(layerDesktopClerk(true, [], "darwin")),
Effect.provideService(HostProcess.Arguments, ["t3"]),
Effect.provideService(ElectronApp.ElectronApp, electronApp),
Effect.provideService(
ElectronWindow.ElectronWindow,
{} as ElectronWindow.ElectronWindow["Service"],
),
Effect.provideService(
DesktopWebLinks.DesktopWebLinks,
DesktopWebLinks.DesktopWebLinks.of({
receive: (url) => Effect.sync(() => void received.push(url)),
setRendererReady: () => Effect.void,
}),
),
);
}).pipe(Effect.scoped),
);
Loading