Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
378 commits
Select commit Hold shift + click to select a range
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
38c187b
fix(pi): preserve tool images and structured results (#17851)
StiensWout Oct 10, 2026
a8bdfdb
fix(server): Claude 5 task lists reach the tasks drawer (#14964)
Mnigos Oct 10, 2026
f92afe7
fix(web): find bar and thread details panel stop covering each other …
MatthewFeroz Oct 10, 2026
0442f5b
fix(web): use server metadata for file chip icons (#17923)
Yash-Singh1 Oct 10, 2026
c8b89a0
fix(desktop): copy images from HTML previews (#17555)
Bil0000 Oct 10, 2026
e408cac
docs(pi): update installation and remote login guidance (#17836)
StiensWout Oct 10, 2026
7e8071f
fix(pi): preserve native abort outcomes (#17853)
StiensWout Oct 10, 2026
160b18c
fix(pi): keep thinking defaults specific to each model (#17835)
StiensWout Oct 10, 2026
62da1cd
fix(pi): preserve shell command exit codes (#17834)
StiensWout Oct 10, 2026
6e9c5a8
fix(pi): expire and cancel extension approvals (#17840)
StiensWout Oct 10, 2026
9afde1c
feat(pi): include native sessions in usage reports (#17848)
StiensWout Oct 10, 2026
818e2be
fix(server): route Copilot ACP subagent output into subagent threads …
maria-rcks Oct 10, 2026
74dfbb6
fix(web): composer banner titles truncate beside their icon instead o…
maria-rcks Oct 10, 2026
953edee
fix(server): Muse turns no longer fail on Windows (#17163)
ntindle Oct 10, 2026
5f7294d
fix(pi): allow known read-only T3 tools without approval (#17852)
StiensWout Oct 10, 2026
4772822
fix: worktree threads keep their worktree when the agent starts, and …
maria-rcks Oct 11, 2026
e4ef8d3
fix(server): keep Claude workflows alive while they report progress (…
maria-rcks Oct 11, 2026
0ecb25a
fix(web): media preview centers its content and pins the close button…
maria-rcks Oct 11, 2026
c73b454
fix(server): threads without a project no longer need Git installed (…
t3dotgg Oct 11, 2026
1cfd1c1
fix(web): toggling tools and thinking at the bottom keeps you at the …
t3dotgg Oct 11, 2026
c727d12
fix(web): Compact chip follows Claude's real prompt cache TTL (#17945)
t3dotgg Oct 11, 2026
75c439f
fix(usage): bound OpenCode history reads to prevent backend OOM (#17961)
Yash-Singh1 Oct 11, 2026
0f36a11
refactor: format diff line counts through one shared helper (#17948)
maria-rcks Oct 11, 2026
72fbad7
fix: new projects start their first thread in the project folder, not…
t3dotgg Oct 11, 2026
cf8479e
perf(server): drive shell last-error lookup from thread bindings (#17…
only21mil Oct 11, 2026
7f0b789
perf(server): skip parsing plain terminal history output (#17179)
StiensWout Oct 11, 2026
1c7b267
perf(server): batch terminal history writes every 250 ms (#17183)
StiensWout Oct 11, 2026
4258c8f
perf(server): storage cleanup no longer runs a full status or size wa…
tris203 Oct 11, 2026
febe1b2
perf(usage): usage scans skip OpenCode legacy messages older than the…
tris203 Oct 11, 2026
9ec472c
perf(usage): OpenCode legacy walk stats entries before checking for s…
tris203 Oct 11, 2026
29e09df
fix(web): MCP app permission prompts no longer overflow the screen (#…
juliusmarminge Oct 11, 2026
716357c
feat(provider-antigravity): support subscription quota and usage limi…
Maseeek Oct 11, 2026
43888b5
fix(desktop): keep generated annotation styles in sync (#17838)
t3-code[bot] Oct 11, 2026
a70ee2a
fix(web): Resume continues on the model picked in the composer (#17867)
akbarakma Oct 11, 2026
3410e43
fix(devices): bump agent-device to 0.21.24 for native Windows hosts (…
TanJeeSchuan Oct 11, 2026
c448e63
fix(web): keybinding group headings no longer touch the group above (…
fixfon Oct 11, 2026
e7db61f
feat(web): configure OpenTelemetry exports in diagnostics (#12538)
MatthewFeroz Oct 11, 2026
08f9b56
docs: update user count to 500k (#17783)
Kamkmgamer Oct 11, 2026
a2f4c7f
fix(mobile): working pill no longer bulges on its right end (#16143)
id0Sch Oct 11, 2026
b467be4
perf(opencode): stop retaining every message of a loaded OpenCode thr…
tris203 Oct 11, 2026
e61eba4
fix(web): switch thumbs stay in their track while scrolling (#15240)
raphaelpra Oct 11, 2026
77c8747
fix(keybindings): thread jumps no longer overlap model picker jumps (…
Fluffy-Bunny-23 Oct 11, 2026
d404a30
fix(mobile): restore QR scanning in iPad pairing sheet (#16019)
arhammahajan Oct 11, 2026
a4a1a80
fix(server): delegated Muse tasks no longer ask approval for every co…
t3dotgg Oct 11, 2026
0eef5d0
fix(codex): prevent unsupported agent history in ChatGPT sharing (#17…
connwalk Oct 11, 2026
4baba3b
fix(server): disabled providers stop checking for CLI updates (#16772)
yordis Oct 11, 2026
758d54a
fix(mobile): round Android queued message sheet corners (#14934)
PixPMusic Oct 11, 2026
584af5a
fix(ssh): record the archive lock owner's real PID (#14598)
Gigioxx Oct 11, 2026
bfbdfed
fix(desktop): keep annotation comment direction independent of host p…
abdelrhmanehab10 Oct 11, 2026
5ce5a8f
fix(ssh): qualify runner script builders in tunnel test (#18078)
juliusmarminge Oct 11, 2026
6c13016
fix(web): keep thread links open until the shell is live (#14697)
saphid Oct 11, 2026
75fca7d
fix(web): scope PR title collapse to tab scrollers (#14644)
Adamulek123 Oct 11, 2026
6cf0526
fix(server): detect fork PRs for branches without upstreams (#13894)
Adamulek123 Oct 11, 2026
a908a7a
fix(search): find threads by their branch PR number (#14658)
tris203 Oct 11, 2026
b9afba5
feat(web): show Claude workflow phases and members in Lineage (#12598)
Bil0000 Oct 11, 2026
2e194f8
fix(mobile): round Android Agents sheet corners (#14925)
PixPMusic Oct 11, 2026
b4542c5
fix(web): the Usage page sends a signed-out browser to pairing (#17938)
AdEx-Partners-DE Oct 11, 2026
cb7d073
fix(server): OpenCode 2 continuations end after a reconnect took a St…
juliusmarminge Oct 11, 2026
ae5fd18
fix(server): OpenCode 2 continuations replay only their own backgroun…
juliusmarminge Oct 11, 2026
f0a47b3
fix(server): ACP reapplies a model after a switch away from it failed…
juliusmarminge Oct 11, 2026
f769e01
fix(web): focus settings search with command-f (#17859)
extoci Oct 11, 2026
5047ee7
fix(mobile): keep Android project paths on one line (#14178)
wellorbetter Oct 11, 2026
0cb3840
fix(web): unpin preview dragging on narrow chat canvases (#15556)
MatthewFeroz Oct 11, 2026
8f43ced
fix(web): thread details toggle no longer covers the thread title on …
freddy-d Oct 11, 2026
8dfee38
fix(server): a directory no longer resolves as the resource monitor b…
Furox-Art Oct 11, 2026
119e61b
fix(server): a Claude usage limit no longer resets the context meter …
Vantrongs Oct 11, 2026
bf725cb
fix(server): GitLab merge requests can expand unchanged lines (#17528)
ScottN-PV Oct 11, 2026
6fa0dd8
fix(provider-cursor): a skill tree deeper than the scan limit no long…
ScottN-PV Oct 11, 2026
5310a4a
fix(web): pass hex theme colors to HTML renders (#16325)
RustedAperture Oct 11, 2026
7808950
fix(web): align the API estimate info icon (#15655)
RakshithBhat03 Oct 11, 2026
cf82199
test(server): ACP teardown tests pass on Windows hosts (#17080)
sheehanmunim Oct 11, 2026
bb9b9aa
fix(server): sync device tool license versions with installer pins (#…
Yash-Singh1 Oct 11, 2026
f845895
fix: sync model favorites and visibility across clients (#16816)
jakeleventhal Oct 11, 2026
4b6d9a0
chore(deps-dev): bump compression from 1.8.1 to 1.8.2 in the npm_and_…
dependabot[bot] Oct 11, 2026
5584d21
fix(server): update fff to stop runaway watcher rescans (#14543)
realhasanshoaib Oct 11, 2026
2025430
fix(mobile): license generation works with filtered installs (#18127)
Yash-Singh1 Oct 11, 2026
8d199b4
fix(mobile): image-only messages ask the agent to respond, like deskt…
whoisaldo Oct 11, 2026
1f6df6b
feat(pull-requests): guided reviews, a beta tour of a pull request (#…
juliusmarminge Oct 11, 2026
18656a3
feat(mcp): agents can write and read pull request review guides (#18143)
juliusmarminge Oct 11, 2026
ed0f7b9
fix(server): Sol Ultrafast stops vanishing from the Codex model picke…
t3dotgg Oct 11, 2026
2625327
fix(usage): say resets momentarily in the final minute (#17869)
extoci Oct 11, 2026
c09c235
fix(server): preserve ambient Cursor MCP servers (#15875)
aravhawk Oct 11, 2026
243c999
fix(server): skip Windows cleanup for exited child processes (#16007)
Alb11747 Oct 11, 2026
8ac6846
feat(settings): providers can be turned on or off per project (#17879)
yordis Oct 11, 2026
f23d008
perf(github): resolve credentials once per GraphQL request (#18289)
juliusmarminge Oct 11, 2026
4946602
fix(server): refresh linked PRs without a checkout (#17167)
PixPMusic Oct 11, 2026
328dc27
fix(mobile): add compose to the single-column iPad list (#18157)
PixPMusic Oct 11, 2026
4bd0ecc
fix(mobile): let sheet lists scroll before dismissal (#17177)
PixPMusic Oct 11, 2026
b4af602
fix(mobile): restore compact iPad trackpad scrolling (#13665)
PixPMusic Oct 11, 2026
b9bf609
fix(mobile): preserve filters across layout changes (#13085)
PixPMusic Oct 11, 2026
80cd575
fix(mobile): separate unfolded thread list from header (#13088)
PixPMusic Oct 11, 2026
a1f81a4
fix(android): Match thread fallback layouts to the loaded pane (#14669)
PixPMusic Oct 11, 2026
74f9df3
fix(mobile): size inline MCP apps to their content (#17040)
PixPMusic Oct 11, 2026
b147dc9
fix(mobile): preserve iPad search chrome across layout changes (#13667)
PixPMusic Oct 11, 2026
2e19207
fix(client): apply host color scheme to saved MCP apps (#17026)
PixPMusic Oct 11, 2026
8863990
fix(android): Use MD3 loading spinners (#14282)
PixPMusic Oct 11, 2026
8de61d4
fix(client): merge No project filters across environments (#17050)
PixPMusic Oct 11, 2026
ac2cc78
fix(client): tolerate blocked cookies in MCP app sandboxes (#17027)
PixPMusic Oct 11, 2026
5495cc4
feat(mobile): browse and review pull requests natively (#18126)
juliusmarminge Oct 11, 2026
bed9239
feat(mobile): guided reviews for pull requests (#18267)
juliusmarminge Oct 11, 2026
5cbe82a
fix(devices): refresh backlogged iOS video and require input admissio…
juliusmarminge Oct 11, 2026
d07a07f
feat(mobile): keep pull requests available offline (#18351)
juliusmarminge Oct 11, 2026
81dbc87
fix(mobile): keep bot badges out of PR attachments (#18347)
juliusmarminge Oct 11, 2026
cafe620
fix(desktop): tooltips no longer open under the Windows and Linux win…
flamboh Oct 11, 2026
1d270be
fix(web): revert trailing toast icons (#18356)
t3-code[bot] Oct 11, 2026
f43f6dd
fix(web): even 4px inset around rows in the PR badge tooltip (#18352)
SunkenInTime Oct 11, 2026
c0c495e
ci(mobile): publish nightly Android APKs to a GitHub prerelease (#16271)
SunkenInTime Oct 11, 2026
3f70c83
fix(server): Claude 5.1+ text before a tool call shows as assistant t…
Gigioxx Oct 11, 2026
c1d528a
feat(provider-muse): native subagents open in their own child threads…
bmdavis419 Oct 11, 2026
662148d
fix(desktop): tooltips no longer open under the macOS traffic lights …
flamboh Oct 11, 2026
55fc13f
fix(web): Cite button stays anchored to the selected text (#17650)
flamboh Oct 11, 2026
9e8c720
fix(web): terminal selection drags scroll at the window edge (#17653)
flamboh Oct 11, 2026
c9181d8
fix(web): scrolling over the thread minimap scrolls the chat (#17652)
flamboh Oct 11, 2026
f6fa477
perf(web): panel toggles no longer re-render the timeline and compose…
flamboh Oct 11, 2026
ca728ec
fix(web): composer keeps its border while resting and expanding (#18333)
flamboh Oct 11, 2026
aaf83ee
fix(web): center the empty-thread placeholder above the composer (#18…
flamboh Oct 11, 2026
2c8e85e
fix(web): PR badge tooltip opens after a thread gains a second PR (#1…
flamboh Oct 11, 2026
83fbbc1
fix(web): timeline keeps live-following after returning from Settings…
flamboh Oct 11, 2026
1d58b82
fix(web): update toast download badge no longer hides behind the prov…
t3dotgg Oct 11, 2026
2783962
fix(shared): preserve generated branch namespaces (#15615)
maria-rcks Oct 11, 2026
6ba6a0d
fix(provider-muse): run on Muse 1.4.6, with linked web search hits an…
t3dotgg Oct 12, 2026
c5d7309
feat(mobile): replace custom Markdown rendering with Enriched (#16979)
juliusmarminge Oct 12, 2026
07993f3
chore(mobile): sync Screens fork with upstream v5 fixes (#18396)
juliusmarminge Oct 12, 2026
6ec6376
docs(mobile): point fork links to pingdotgg (#18433)
juliusmarminge Oct 12, 2026
7ab28a3
perf(web): reuse the collator when sorting diff files (#18420)
saphid Oct 12, 2026
8569ce9
perf(web): avoid quadratic markdown link scans (#18387)
saphid Oct 12, 2026
499a53c
perf(server): expired PR diffs no longer stay in memory until restart…
tris203 Oct 12, 2026
7f02b84
perf(usage): the first usage scan skips decoding transcript lines tha…
tris203 Oct 12, 2026
aa2bfc6
fix(mobile): preserve browser prompt replies across control updates (…
saphid Oct 12, 2026
f570294
fix(web): closed popovers no longer stay on screen and click-through …
akbarakma Oct 12, 2026
821a6d7
fix(web): keybinding settings label Focus URL with a capitalized acro…
RakshithBhat03 Oct 12, 2026
0fd7d2d
fix(web): long commands no longer overflow the Add Action dialog (#18…
fixfon Oct 12, 2026
fded2ca
fix(web): provider Runtime controls follow the settings row layout (#…
ScottN-PV Oct 12, 2026
6bbb72c
perf(web): Thinking shimmer steps instead of drawing every frame (#18…
realhasanshoaib Oct 12, 2026
808bee7
chore(typecheck): typecheck with tsc-rs (#16704)
t3dotgg Oct 12, 2026
9b9792e
test(server): finish workflow reads before changing transcripts (#18192)
lastobelus Oct 12, 2026
6a99eb3
test(server): Claude sign-in message test passes on Windows hosts (#1…
AdEx-Partners-DE Oct 12, 2026
63eaa79
fix(web): context menus no longer scroll when they fit the window (#1…
kacigaya Oct 12, 2026
a5331e4
fix(server): checkpoint restore keeps a nested workspace on Windows (…
JonasFocus Oct 12, 2026
ee2763e
Reject unknown params in t3_thread_read (#17823)
mfazekas Oct 12, 2026
d45d1a1
fix(desktop): Option-click on a chat link opens the system browser (#…
whoisaldo Oct 12, 2026
b8d03ba
fix(mobile): new thread draft names its repo and says it is a new thr…
kaovilai Oct 12, 2026
4a90c1c
fix(web): keep queued threads subscribed (#15293)
ANSHSINGH050404 Oct 12, 2026
4ff8b07
test(server): Claude reset tests are skipped on Windows hosts, where …
AdEx-Partners-DE Oct 12, 2026
fd6d9dd
fix(web): hide stash menu behind maximized panel (#18115)
Saikrishna1876 Oct 12, 2026
df78114
fix(web): sidebar toggle no longer sits under the macOS window button…
realhasanshoaib Oct 12, 2026
f79f37a
fix(server): missing agent binaries report launch failure
Moinax Oct 12, 2026
397a461
feat(android): add Pull Requests tab (#18372)
PixPMusic Oct 12, 2026
12b34e8
fix(mobile): Forgejo change requests ask for the summary they require…
flamboh Oct 12, 2026
b9ad3da
fix(server): cap automatic thread continuations and turn them on by d…
t3dotgg Oct 12, 2026
c32ade4
feat(mobile): stock tab bar, glass filter pills, and saved list filte…
juliusmarminge Oct 12, 2026
52f9046
fix(mobile): keep PR surfaces and Android tab selection visible acros…
PixPMusic Oct 12, 2026
4ab4cdf
fix(mobile): keep preview count badges inside the working pill (#18449)
RVZO6 Oct 12, 2026
2e24ec4
fix(mobile): show rounded pull request selection in the sidebar (#18480)
PixPMusic Oct 12, 2026
e688034
feat(web): model options for source control writer and review guide m…
juliusmarminge Oct 12, 2026
eec69e1
chore(sync): merge upstream through e688034b5f
NicholasZolton Oct 12, 2026
a27573b
docs(sync): record branch integration and retained boundaries
NicholasZolton Oct 12, 2026
dac1fb2
fix(build): remove obsolete native build approval placeholder
NicholasZolton Oct 12, 2026
ec01737
chore(sync): remove unnecessary upstream differences
NicholasZolton Oct 12, 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
  •  
  •  
  •  
189 changes: 189 additions & 0 deletions .github/scripts/mirror-play-apk.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
// Mirrors the newest build on a Google Play track to a rolling GitHub
// prerelease as a universal APK. Play generates and signs that APK from the
// uploaded bundle with the app signing key, so it carries the same signature
// as the Play Store install. Run by .github/workflows/mobile-android-apk.yml.
const { execFileSync } = require("node:child_process");
const crypto = require("node:crypto");
const fs = require("node:fs");
const os = require("node:os");
const path = require("node:path");
const { Readable } = require("node:stream");
const { pipeline } = require("node:stream/promises");

const PLAY_API = "https://androidpublisher.googleapis.com/androidpublisher/v3/applications";

function requireEnv(name) {
const value = process.env[name];
if (!value) throw new Error(`${name} is required.`);
return value;
}

// Service account key -> OAuth access token via a self-signed JWT grant.
async function playAccessToken(key) {
const now = Math.floor(Date.now() / 1000);
const encode = (value) => Buffer.from(JSON.stringify(value)).toString("base64url");
const unsigned = `${encode({ alg: "RS256", typ: "JWT" })}.${encode({
iss: key.client_email,
scope: "https://www.googleapis.com/auth/androidpublisher",
aud: key.token_uri,
iat: now,
exp: now + 600,
})}`;
const signature = crypto.sign("RSA-SHA256", Buffer.from(unsigned), key.private_key);
const response = await fetch(key.token_uri, {
method: "POST",
body: new URLSearchParams({
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
assertion: `${unsigned}.${signature.toString("base64url")}`,
}),
});
if (!response.ok) {
throw new Error(`Google token exchange failed: ${response.status} ${await response.text()}`);
}
return (await response.json()).access_token;
}

async function play(token, method, url) {
const response = await fetch(url, { method, headers: { authorization: `Bearer ${token}` } });
if (!response.ok) {
throw new Error(`${method} ${url} failed: ${response.status} ${await response.text()}`);
}
return response;
}

// Highest version code the track serves, with its release name. Play names a
// release after the bundle's versionName unless the uploader sets one. This
// endpoint reads without opening an edit; an edit would invalidate any open
// EAS Submit edit made with the same service account.
async function newestTrackBuild(token, appUrl, trackName) {
const { releases = [] } = await (
await play(token, "GET", `${appUrl}/tracks/${trackName}/releases`)
).json();
let newest;
for (const release of releases) {
if (release.releaseLifecycleState !== "RELEASE_LIFECYCLE_STATE_PUBLISHED") continue;
for (const { versionCode } of release.activeArtifacts ?? []) {
if (!newest || versionCode > newest.versionCode) {
newest = { versionCode, versionName: release.releaseName || String(versionCode) };
}
}
}
return newest;
}

function gh(...args) {
return execFileSync("gh", args, { encoding: "utf8", stdio: ["ignore", "pipe", "inherit"] });
}

function readRelease(tag) {
try {
return JSON.parse(gh("release", "view", tag, "--json", "assets,body"));
} catch {
return undefined;
}
}

// Downloads the build's universal APK and uploads it, creating the release on
// first use. Returns false when Play lists no universal APK, which happens
// while it is still processing a fresh upload.
async function uploadApk({ token, appUrl, build, tag, apkName, notes, release }) {
const generated = await (
await play(token, "GET", `${appUrl}/generatedApks/${build.versionCode}`)
).json();
// One entry per app signing key. More than one means a key rotation, so
// fail rather than guess which signature testers should get.
const universal = (generated.generatedApks ?? []).filter((entry) => entry.generatedUniversalApk);
if (universal.length === 0) return false;
if (universal.length > 1) {
throw new Error(`Play returned ${universal.length} universal APKs, one per signing key.`);
}
const { downloadId } = universal[0].generatedUniversalApk;

const apkPath = path.join(fs.mkdtempSync(path.join(os.tmpdir(), "apk-")), apkName);
const download = await play(
token,
"GET",
`${appUrl}/generatedApks/${build.versionCode}/downloads/${encodeURIComponent(downloadId)}:download?alt=media`,
);
await pipeline(Readable.fromWeb(download.body), fs.createWriteStream(apkPath));

if (!release) {
// Prerelease with a non-v tag: release.yml, the desktop updater, the CLI,
// and the marketing site's latest-release lookup all ignore it.
gh(
"release",
"create",
tag,
"--prerelease",
"--latest=false",
"--title",
"T3 Code for Android (nightly)",
"--notes",
notes,
);
}
// --clobber replaces an asset a failed upload left behind.
gh("release", "upload", tag, apkPath, "--clobber");
return true;
}

async function main() {
const packageName = requireEnv("PACKAGE_NAME");
const trackName = requireEnv("PLAY_TRACK");
const tag = requireEnv("RELEASE_TAG");
const key = JSON.parse(requireEnv("GOOGLE_PLAY_SERVICE_ACCOUNT_JSON"));
const summary = (line) =>
process.env.GITHUB_STEP_SUMMARY &&
fs.appendFileSync(process.env.GITHUB_STEP_SUMMARY, `${line}\n`);

const token = await playAccessToken(key);
const appUrl = `${PLAY_API}/${packageName}`;
const build = await newestTrackBuild(token, appUrl, trackName);
if (!build) {
console.log(`The ${trackName} track has no live release.`);
return;
}

const safeName = build.versionName.replace(/[^0-9A-Za-z.]+/g, "-").replace(/^-|-$/g, "");
const apkName = `t3code-android-${safeName}-${build.versionCode}.apk`;
const notes = [
`T3 Code for Android that works with nightly servers, mirrored from the Google Play ${trackName} track. Current build: ${build.versionName} (${build.versionCode}).`,
"",
"The Play Store release can't connect to a nightly server yet. Install this APK if you can't join the Play testing group. Only the newest build is kept here.",
].join("\n");

const release = readRelease(tag);
const assets = release?.assets ?? [];
// A failed upload can leave an empty asset under the final name.
const published = assets.some(
(asset) => asset.name === apkName && asset.state === "uploaded" && asset.size > 0,
);
if (published) {
console.log(`${apkName} is already published.`);
} else if (await uploadApk({ token, appUrl, build, tag, apkName, notes, release })) {
console.log(`Published ${apkName}.`);
summary(`:white_check_mark: Published \`${apkName}\` to the \`${tag}\` release.`);
} else {
// The next run retries.
console.log(`Play lists no universal APK for ${build.versionCode}.`);
summary(
`:hourglass: Play lists no universal APK for ${build.versionName} (${build.versionCode}).`,
);
return;
}

// Reconciled on every run so an interrupted cleanup finishes on the next one.
for (const stale of assets) {
if (stale.name.endsWith(".apk") && stale.name !== apkName) {
gh("release", "delete-asset", tag, stale.name, "--yes");
}
}
if (release && release.body.replace(/\r\n/g, "\n").trim() !== notes) {
gh("release", "edit", tag, "--notes", notes);
}
}

main().catch((error) => {
console.error(error);
process.exit(1);
});
59 changes: 59 additions & 0 deletions .github/workflows/mobile-android-apk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Mobile Android APK

# Publishes the newest nightly-compatible Android build as a sideloadable APK
# on the rolling "android-nightly" prerelease, for nightly users who can't join
# the Play testing group. Play re-signs uploaded bundles with the app signing
# key, so its universal APK matches the Play Store install and needs no signing
# secrets here. EAS submits asynchronously (--no-wait), so this polls Play
# instead of chaining off mobile-eas-production.yml; runs with nothing new exit
# early.
on:
schedule:
# Avoid minute zero, when GitHub scheduled jobs are busiest.
- cron: "23 * * * *"
workflow_dispatch:

concurrency:
group: mobile-android-apk
cancel-in-progress: false

jobs:
mirror:
name: Mirror Play APK
runs-on: blacksmith-2vcpu-ubuntu-2404
timeout-minutes: 10
permissions:
contents: write
env:
PACKAGE_NAME: com.t3tools.t3code
# eas.json submits v2-preview builds to this closed testing track; they
# speak the orchestration protocol nightly servers use, which the Play
# Store release can't.
PLAY_TRACK: v2
RELEASE_TAG: android-nightly
steps:
- id: credentials
name: Check for Play credentials
env:
GOOGLE_PLAY_SERVICE_ACCOUNT_JSON: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}
run: |
if [ -n "$GOOGLE_PLAY_SERVICE_ACCOUNT_JSON" ]; then
echo "present=true" >> "$GITHUB_OUTPUT"
else
echo "present=false" >> "$GITHUB_OUTPUT"
echo "GOOGLE_PLAY_SERVICE_ACCOUNT_JSON is not available; skipping APK mirror."
fi

- name: Checkout
if: steps.credentials.outputs.present == 'true'
uses: actions/checkout@v6
with:
sparse-checkout: .github/scripts

- name: Mirror the newest APK
if: steps.credentials.outputs.present == 'true'
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
GOOGLE_PLAY_SERVICE_ACCOUNT_JSON: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}
run: node .github/scripts/mirror-play-apk.cjs
2 changes: 2 additions & 0 deletions .github/workflows/mobile-eas-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ jobs:
uses: expo/expo-github-action/continuous-deploy-fingerprint@main
env:
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
# The Expo action otherwise suppresses the EAS command's failure output.
RUNNER_DEBUG: "1"
with:
profile: preview:dev
branch: pr-${{ github.event.pull_request.number }}
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ You can think of T3 Code as an open source "bring-your-own-subscription" alterna

## What makes T3 Code special?

We have over 400,000 users who love T3 Code. It's important we maintain the things they love as we continue to iterate on the product. Here's a brief list of the things we can never compromise on.
We have over 500,000 users who love T3 Code. It's important we maintain the things they love as we continue to iterate on the product. Here's a brief list of the things we can never compromise on.

### 1. Open at the core

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
8 changes: 5 additions & 3 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"scripts": {
"ensure:electron": "node scripts/ensure-electron-runtime.mjs",
"start": "node scripts/start-electron.mjs",
"typecheck": "tsc --noEmit",
"typecheck": "tsc-rs --noEmit",
"test": "vp test run --passWithNoTests",
"smoke-test": "node scripts/smoke-test.mjs"
},
Expand All @@ -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 @@ -35,6 +36,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 @@ -277,13 +279,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 @@ -330,6 +335,7 @@ const startup = Effect.gen(function* () {
});
}
yield* appIdentity.configure;
yield* previewPasskeys.configure;
yield* applicationMenu.configure;
yield* updates.configure;
yield* DesktopRemoteUpdates.listen;
Expand Down
Loading
Loading