Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
410 commits
Select commit Hold shift + click to select a range
d899bdd
fix(gitlab): long merge request descriptions no longer break the list…
fixfon Nov 14, 2026
4c47315
fix(server): overlapping VCS status refreshes share one follow-up ref…
only21mil Nov 14, 2026
25c5032
fix(devices): require a complete Android SDK on SSH hosts (#24566)
juliusmarminge Nov 14, 2026
6d94997
fix(opencode): support explicit background waits (#35272)
AndreiShenets Nov 14, 2026
aecad62
fix(opencode): a failed steer no longer leaves the turn running forev…
only21mil Nov 14, 2026
033bb5a
fix(ssh): failed launches report only their own output (#35717)
saphid Nov 14, 2026
83d2382
fix(opencode): OpenCode 1.x background subagents no longer show as do…
Mach1212 Nov 14, 2026
99071c4
fix(codex): delegate_task children start as Codex subagents (#36525)
juliusmarminge Nov 14, 2026
8247952
fix(marketing): route mobile downloads to app stores (#24577)
juliusmarminge Nov 14, 2026
cee16bd
fix(desktop): start WSL backends in Linux home (#35719)
satyalyadav Nov 14, 2026
96051c6
fix(server): prevent legacy terminal history collisions across thread…
juliusmarminge Nov 14, 2026
cf60628
fix(client-runtime): cache running threads when their view closes (#2…
maria-rcks Nov 14, 2026
0893180
fix(server): report the actual preview snapshot timeout (#24130)
Wosca Nov 14, 2026
a81ec88
fix(clients): allow portable provider handoffs after detach (#24641)
juliusmarminge Nov 14, 2026
bf9b8b7
fix(server): Claude on Bedrock runs the model picked in the composer …
only21mil Nov 14, 2026
70be204
fix: re-ticking a file after a push no longer shows it Viewed (#24151)
only21mil Nov 14, 2026
1ed6e32
fix(ssh): ignore alias commands and TTY requests for T3 connections (…
juliusmarminge Nov 14, 2026
fe873f8
fix(web): confirm before deleting scheduled tasks (#23578)
only21mil Nov 14, 2026
a8e60d4
fix(release): require complete updater manifests (#23700)
parmartejass Nov 14, 2026
ac18091
fix(web): seeded models yield to started thread selections (#24619)
juliusmarminge Nov 14, 2026
33372a2
fix(pi): info notifications no longer render as warnings (#23506)
0xCUB3 Nov 14, 2026
ca7a944
fix(client-runtime): Reconnect works while the network reports offlin…
only21mil Nov 14, 2026
294e061
fix(shared): IPv6 SCP remotes match SSH repository identities (#36547)
StiensWout Nov 14, 2026
5abf383
fix(server): prevent lossy edits of non-UTF-8 workspace files (#36545)
StiensWout Nov 14, 2026
a760a3a
fix(desktop): keyboard-opened message link menus select their first i…
only21mil Nov 14, 2026
e80468b
fix(server): report invalid provider events without a second schema f…
StiensWout Nov 14, 2026
a3477a5
fix(server): branch refresh no longer waits for detailed Git status (…
MINIlaolao Nov 14, 2026
1f55acf
fix(client-runtime): refresh settled counts when threads move project…
StiensWout Nov 14, 2026
00ec286
fix(mobile): adaptive SVG project icons follow the app's color scheme…
tomhmoses Nov 14, 2026
efae4e9
fix(client): retry unread thread visits after reconnect (#36559)
StiensWout Nov 14, 2026
46b508d
fix(web): keep long ACP registry searches within the query limit (#23…
only21mil Nov 14, 2026
248f5b6
fix(preview): browser tabs follow the default appearance (#24658)
juliusmarminge Nov 14, 2026
d530d96
fix(desktop): inherit login-shell Android SDK selection (#24623)
juliusmarminge Nov 14, 2026
a8777e4
fix(server): held agent messages no longer block settling (#24891)
mkantautas Nov 14, 2026
9e180e5
fix(server): file editor saves keep a UTF-8 BOM (#36552)
StiensWout Nov 14, 2026
86d49da
fix(server): open stable Zed when a prerelease Zed is first on PATH (…
only21mil Nov 14, 2026
b2259d3
fix(web): show working state while provider sessions start (#23590)
only21mil Nov 14, 2026
7bf7527
fix(devices): agents can test the mobile app on remote device hosts (…
t3dotgg Nov 14, 2026
410177c
fix(gitlab): create fork merge requests in the source project (#23439)
yashranaway Nov 14, 2026
8b30961
fix(server): allow slow worktree base fetches to finish (#24604)
juliusmarminge Nov 14, 2026
f315da3
fix(shared): PASS and FAIL badges stay readable in dark command outpu…
WesleySmits Nov 14, 2026
947c056
fix(web): a context submenu near the right edge no longer covers its …
Brechard Nov 14, 2026
3fe0fbb
fix(web): keep file uploads when returning a draft to its environment…
StiensWout Nov 14, 2026
fd0ffd0
fix(web): a stale tab no longer erases finalized stashed images (#36574)
StiensWout Nov 14, 2026
2f2730c
fix(server): task_status says starting until the child's provider sta…
only21mil Nov 14, 2026
d2bdd58
fix(server): npm provider updates only offer versions npm will instal…
davisonio Nov 14, 2026
5e06246
fix(web): recovered queued edits keep their mentions and context (#36…
StiensWout Nov 14, 2026
35d01dc
perf(acp): long ACP threads reopen without per-chunk history copies (…
only21mil Nov 14, 2026
4d5d5f8
fix(source-control): preserve .git in Azure DevOps repository names (…
StiensWout Nov 14, 2026
4652544
fix(server): interrupted checkpoints no longer leak temporary packs (…
razzeee Nov 14, 2026
306914f
fix(client-runtime): grouped projects no longer take one folder's nam…
ThomasVuNguyen Nov 14, 2026
bebaf3e
fix(pi): resumed threads run in the worktree after a handoff (#36586)
juliusmarminge Nov 14, 2026
d0a494f
fix(server): honor the configured push remote on tracked branches (#2…
only21mil Nov 14, 2026
000d82d
fix(web): Esc closes the theme editor, not Settings (#25130)
AatmanAJ Nov 14, 2026
c0b140b
fix(server): file changes with an empty list keep their file name (#3…
MinitJain Nov 14, 2026
b4c1bd1
fix(web): re-picking the current model in Settings keeps its traits (…
f4llenz Nov 14, 2026
2b6145b
fix(web): browser tests no longer pick a port Windows has reserved (#…
Zacharon Nov 14, 2026
e4688f7
fix(server): find files in newline-named nested worktrees (#36588)
StiensWout Nov 14, 2026
28f1786
fix(web): recreated folders no longer show deleted files (#36590)
StiensWout Nov 14, 2026
3b18dc2
fix(web): manual compaction counts history beyond the loaded page (#2…
jason5545 Nov 14, 2026
2fa77fb
fix(web): horizontal table scrolling preserves timeline follow (#24045)
nateEc Nov 14, 2026
83a276d
fix(server): setup scripts complete with shell line editors (#25472)
maria-rcks Nov 14, 2026
a61291e
fix(shared): one-letter link schemes no longer become file links on W…
Zacharon Nov 14, 2026
4192234
fix(usage): distinct email-less hub accounts no longer collapse (#36561)
StiensWout Nov 14, 2026
75c544a
fix(pi): async pi-subagents workflow, chain and parallel members show…
juliusmarminge Nov 14, 2026
651accb
fix(web): new browser tabs open at your default zoom and appearance (…
BilalIrfanContact Nov 14, 2026
9e19b7f
feat(server): resume stopped provider threads natively (#36526)
Yash-Singh1 Nov 14, 2026
4574c60
fix(web): preserve saved notebook traceback frame boundaries (#36602)
StiensWout Nov 14, 2026
d6244ac
fix(web): preserve literal entities in EPUB CDATA (#36595)
StiensWout Nov 14, 2026
953ce60
fix(web): changed root files with a leading space open in the diff pa…
StiensWout Nov 14, 2026
43ba62b
fix(server): thread reads wait for pending background work (#36610)
StiensWout Nov 14, 2026
91fa913
fix(server): partial import retries no longer certify missing message…
StiensWout Nov 14, 2026
4b99420
fix(server): background subagents stop running when their Claude sess…
juliusmarminge Nov 14, 2026
b37c959
fix(server): open colon-number project folders correctly in VS Code (…
StiensWout Nov 14, 2026
4121b30
fix(mobile): the open button no longer covers inline page headings (#…
saphid Nov 14, 2026
02e29ce
perf(usage): show saved totals before scanning history (#25711)
hieu-lee Nov 14, 2026
89f1acb
fix(pi): text generation uses the thinking level picked in Settings (…
MarcoDotIO Nov 14, 2026
0fee26d
fix(mobile): launch terminal commands after the measured resize (#36584)
StiensWout Nov 14, 2026
13f89ae
fix(server): repeated imports reach older worktree history (#36608)
StiensWout Nov 14, 2026
8a072ca
fix(ci): pin unenv so release smoke installs resolve its exact peer (…
juliusmarminge Nov 14, 2026
38b3fee
fix(server): cached refs include a newly checked-out external branch …
StiensWout Nov 14, 2026
820f620
fix(web): model picks no longer inherit another model’s traits (#36621)
StiensWout Nov 14, 2026
298c38d
fix(server): subagent hover cards show reasoning effort again (#35333)
Bil0000 Nov 14, 2026
f3b43ef
fix(server): a hung Codex app-server no longer blocks every later Cod…
MahirAbbas Nov 14, 2026
df8c1a1
fix(web): Narrator highlights the sidebar thread title where it is dr…
SunkenInTime Nov 14, 2026
f2764f7
fix(desktop): desktop tests no longer race to install Electron (#26654)
Moinax Nov 14, 2026
9ff435b
fix(server): pause service restart when disk is full (#25924)
gyurix Nov 14, 2026
4c2f04d
fix(web): queued runs, relationships and changed files no longer re-r…
Batuhan1999 Nov 14, 2026
487733b
fix(server): recover Claude cooldown reset times from proxy errors (#…
juliusmarminge Nov 14, 2026
5958d00
perf(web): Update everything downloads a server's update while provid…
Bil0000 Nov 14, 2026
6be1bd6
perf(cursor): long command output streams without copying its tail pe…
hieu-lee Nov 14, 2026
c5f842d
fix(server): regenerate titles on fresh run forks (#36637)
StiensWout Nov 14, 2026
6aa14d3
fix(server): short search prefixes find accented messages (#36632)
StiensWout Nov 14, 2026
060ac23
fix(devices): explain missing npm during tool updates (#27084)
kristofkatzenberger Nov 14, 2026
5ba3a84
fix(server): a locked database no longer leaves a thread stuck in "st…
juliusmarminge Nov 14, 2026
0a8aaa3
fix(server): retained forks keep inherited shell item counts after so…
juliusmarminge Nov 14, 2026
bc1dc2a
fix(mobile): keep the thread column out of the iPhone Duo fold (#26923)
chekdotdev Nov 14, 2026
77ad2eb
fix(server): end obsolete link cards after a matching retry succeeds …
stevan-borus Nov 14, 2026
071ae4e
fix(server): deleted projects keep their worktree cleanup policy (#36…
StiensWout Nov 14, 2026
179c032
fix(server): include managed Claude skills in the skill menu (#26732)
greyxp1 Nov 14, 2026
3d3275b
fix(server): PR checkout respects restricted fetch mappings (#27853)
amartani Nov 14, 2026
121f0cf
fix(server): t3_thread_list clamps an oversized limit instead of fail…
MarcoDotIO Nov 14, 2026
0c306f4
fix(ssh): wait for a boot service's server instead of starting a seco…
juliusmarminge Nov 14, 2026
ae49f4d
fix(server): honor custom Claude thinking choices (#28024)
chisewaguri Nov 14, 2026
8cb551a
fix(web): saved files show external edits after a failed reload (#36664)
StiensWout Nov 14, 2026
1159aa2
fix(client-runtime): preserve PR reference links across embedded medi…
StiensWout Nov 14, 2026
913d7fc
fix(web): PageUp and PageDown shortcut labels no longer read Pageup a…
only21mil Nov 14, 2026
1535f3f
fix(desktop): theme changes no longer stop at windows without a title…
swsammy Nov 14, 2026
bb9fde6
fix(scripts): test:cached no longer crashes when vp writes no cache s…
only21mil Nov 14, 2026
8a45c51
fix(desktop): Browser Screenshot saves fresh pixels while T3 Code is …
Quicksaver Nov 14, 2026
92c91aa
fix(client-runtime): keep inherited qualifier values as PR search tex…
Motaghi Nov 14, 2026
0acca1d
fix(server): Resume keeps unaccepted replacement images (#36677)
StiensWout Nov 14, 2026
6effe74
fix(web): show repeated table rows and cells in ODT previews (#36689)
StiensWout Nov 14, 2026
f161a4d
fix(shared): preserve literal ampersands in citation Markdown paths (…
Motaghi Nov 14, 2026
fd6d0ea
fix(web): stashing waits for pasted images to finish compressing (#28…
only21mil Nov 14, 2026
ead133c
fix(web): SSH port field no longer turns 22.5 into port 22 (#28297)
only21mil Nov 14, 2026
ae83739
fix(server): analytics record the thread binding a scheduled task act…
only21mil Nov 14, 2026
e096dee
fix(web): the publish-repository path no longer submits on an IME com…
only21mil Nov 14, 2026
96735d7
fix(web): picking a sidebar search result scrolls the list to that th…
tsmith165 Nov 14, 2026
c3517ec
fix(shared): theme CSS checks allow url() inside a quoted data: addre…
juliusmarminge Nov 14, 2026
0e5e0bb
fix(mobile): removing an environment no longer fails when a queued me…
only21mil Nov 14, 2026
19f6438
fix(server): interrupted checkpoint restores no longer leave files st…
StiensWout Nov 14, 2026
71c2410
fix(web): thread details slides in on close (#28929)
Claudesaul Nov 14, 2026
f4e65cd
fix(contracts): a null model selection options value is treated as om…
jieyuexing Nov 14, 2026
250e502
fix(mobile): scheduled-task edits made in quick succession are no lon…
tcrapts Nov 14, 2026
dafd053
fix(mobile): closed PR numbers match their red icon in the thread lis…
tris203 Nov 14, 2026
13a6782
fix(web): ODS time cells without display text show their value (#36685)
StiensWout Nov 14, 2026
0fdc99c
fix(web): notebook previews strip ANSI colors from saved tracebacks (…
juliusmarminge Nov 14, 2026
414d938
fix(server): publish Create PR branches to split push URLs (#36695)
StiensWout Nov 14, 2026
0200dcf
perf(shared): queued SQLite reads stop waiting on one reader while an…
Pyseph Nov 14, 2026
b28dc0e
perf(mobile): Changes tab no longer redraws every file when one chang…
Yuruzuu Nov 14, 2026
243d66a
fix(server): first commit dialog shows net file changes (#36716)
StiensWout Nov 14, 2026
740a7cc
fix(marketing): download page shows its Releases fallback when the Gi…
only21mil Nov 14, 2026
cb6670b
fix(server): a timed-out Git check no longer turns off threads withou…
jux310 Nov 14, 2026
666631e
fix(web): copied inline code keeps meaningful edge spaces (#36712)
StiensWout Nov 14, 2026
b90ffea
fix(mobile): drop duplicate attachments, as on web (#29143)
ahalekelly Nov 14, 2026
e2f164d
fix(web): let subagent lists pass scrolling to the details panel (#28…
Alb11747 Nov 14, 2026
a678948
fix(web): pending-question digit shortcuts ignore dialogs, menus and …
only21mil Nov 14, 2026
d9973dc
fix(mobile): a shared file no longer fails to send with "Too much con…
derektrimm Nov 14, 2026
0e250fa
fix(server): selected-file commits keep a conflicted multi-commit che…
only21mil Nov 14, 2026
20d21cf
fix(mobile): disabled send arrow no longer darkens where its strokes …
RVZO6 Nov 14, 2026
5fa95d9
fix(opencode): wait for the whole listening line before reading the s…
only21mil Nov 14, 2026
35483c1
fix(opencode): show usage-limit warnings while OpenCode 2 retries (#2…
only21mil Nov 14, 2026
5e27bae
fix(web): a stashed prompt keeps its machine mentions (#28780)
only21mil Nov 14, 2026
a575d45
fix(web,server): the branch label no longer flips back after a switch…
Yuruzuu Nov 14, 2026
77d3358
fix(server): ACP teardown survives processes exiting during the /proc…
juliusmarminge Nov 14, 2026
e72dd50
fix(client): closed terminal views release the shared grid (#36647)
StiensWout Nov 14, 2026
cc0a7bb
fix(shared): file links with parentheses in the path keep their paren…
Abhishek-B-R Nov 14, 2026
f84ad6f
fix(web): discarded drafts stay discarded after image compression (#3…
StiensWout Nov 14, 2026
96ca66f
fix(server): a nested repository with no commits no longer breaks the…
Abhishek-B-R Nov 14, 2026
e26e21c
fix(web,mobile): bound scheduled tasks no longer offer a model their …
juliusmarminge Nov 14, 2026
0788555
fix(shared): honor Windows PATHEXT regardless of key casing (#29376)
luke2x Nov 14, 2026
acd192f
fix(web): removing an environment dismisses its notification toasts (…
StiensWout Nov 14, 2026
2b596b8
fix(web): context meter no longer keeps the retired provider's usage …
karrambol Nov 14, 2026
76748e9
test(web): wait for Settings focus before testing the theme editor's …
juliusmarminge Nov 14, 2026
e53417b
fix(server): selected-file commits work again with Git older than 2.2…
only21mil Nov 14, 2026
64d70f8
fix(mobile): sort pull request lists and timelines by time (#28391)
only21mil Nov 14, 2026
db0ae7b
fix(acp): a blank line from an ACP agent no longer ends the session (…
only21mil Nov 14, 2026
3d9aeaf
fix(shared): preview semicolon-separated CSV files as tables (#36738)
SouthCarpet Nov 14, 2026
34a7c0d
fix(cursor): preserve catalog aliases in model discovery (#36752)
StiensWout Nov 14, 2026
68bc281
fix(desktop): Settings opens while the separate preview window has fo…
StiensWout Nov 14, 2026
629242b
fix(server): long scheduled-task titles no longer end in a broken cha…
only21mil Nov 14, 2026
616067d
fix(web): pressing Enter in the Add CLIProxyAPI hub dialog adds the h…
preetsuthar17 Nov 14, 2026
3b816cf
fix(web): ChatGPT sign-in error no longer points to a missing redirec…
juliusmarminge Nov 14, 2026
12102c7
fix(web,mobile): Linked environments shows links made outside the app…
Nabil372 Nov 14, 2026
719042d
fix(server): MCP-launched threads no longer flash in Inbox before Wor…
mmmattG Nov 14, 2026
566370f
fix(server): storage cleanup no longer reports idle threads on a bran…
only21mil Nov 14, 2026
9441a72
fix(mobile): Reconnect and Retry now on a switched-off environment sw…
only21mil Nov 14, 2026
77a39e9
fix(server): cancelling worktree setup removes its unclaimed worktree…
StiensWout Nov 14, 2026
5fe2f7e
fix(web): diagnostics no longer shows near-second spans as "1000 ms" …
M0xoo Nov 14, 2026
313f601
fix(server): Browser tab titles follow page title changes (#36764)
StiensWout Nov 14, 2026
10a44f5
fix(web): RTF previews keep named spaces, hyphens and joiners (#36767)
StiensWout Nov 14, 2026
0351dbb
fix(acp): refused and limit-stopped turns no longer show as completed…
only21mil Nov 14, 2026
6cb47ac
fix(web): Escape that cancels a thread rename no longer also closes t…
preetsuthar17 Nov 14, 2026
3908c4e
fix(terminal): answer OSC color queries so CLIs pick light colors (#3…
juliusmarminge Nov 14, 2026
f52e5c1
fix(server): expand Windows home-relative file paths consistently (#2…
luke2x Nov 14, 2026
081a5d9
fix(clients): the folder picker finds folders with accented names on …
saphid Nov 14, 2026
cebdf39
fix(web): cancelled queued-message edits release their staged uploads…
saphid Nov 14, 2026
0c6f421
perf(desktop): stop rebroadcasting preview ownership on every key (#2…
voltcrash Nov 14, 2026
c666345
fix(web): subagent previews drop image marks and full link URLs (#29637)
saphid Nov 14, 2026
c0ee5a1
fix(server): pushing a branch whose remote branch was deleted publish…
saphid Nov 14, 2026
4ce60c1
fix(mobile): @path search no longer offers the previous worktree's fi…
juliusmarminge Nov 14, 2026
e330593
fix(web): bare URLs no longer swallow Arabic commas and question mark…
newer97 Nov 14, 2026
e5d4322
fix(server): expand unchanged lines beside Git ident keywords (#36774)
StiensWout Nov 14, 2026
c2b06f9
perf(server): Cursor turns no longer write every streamed token to pr…
saphid Nov 14, 2026
4747472
fix(web): clear failed badges when threads are opened (#28616)
BilalIrfanContact Nov 14, 2026
43a71d9
fix(web): a terminal reopened while its open is pending no longer clo…
Salloxy Nov 14, 2026
1c18c16
perf(server): ACP subagent replies no longer rewrite the database on …
M0xoo Nov 14, 2026
4954322
fix(web): don't send completion notifications for snoozed threads (#2…
maximkes Nov 14, 2026
cc578d5
fix(server): settling a usage-limited thread disarms recovery and nam…
EhsanulHaqueSiam Nov 14, 2026
45ff3f5
fix(desktop): bound screencast delivery to slow consumers (#28518)
HomemadeToast57 Nov 14, 2026
1fcb245
fix(server): Claude API-key logins show as Claude API Key in provider…
saphid Nov 14, 2026
86ec940
fix(mobile): a failed archive or delete keeps the earlier Undo (#29628)
saphid Nov 14, 2026
66a40c7
fix(server): turns stuck in provider retries for 10 minutes fail inst…
jieyuexing Nov 14, 2026
382312a
fix(web): the sidebar shortcut honors terminal and preview focus cond…
saphid Nov 14, 2026
b05c505
fix(mobile): review comment cards keep a trailing blank line in their…
saphid Nov 14, 2026
f751c84
fix(web): the new-thread project picker follows the manual project or…
saphid Nov 14, 2026
0f50b5f
fix(mobile): deleting a thread clears its unsent draft (#29564)
saphid Nov 14, 2026
997b304
fix(server): editing a queued message deletes the attachments you rem…
saphid Nov 14, 2026
c342f3d
fix(web): settled threads no longer offer a PR watch the server refus…
saphid Nov 14, 2026
0457241
fix(clients): a one-hour snooze no longer reads "2h left" (#36785)
juliusmarminge Nov 14, 2026
732198d
fix(web): a disabled Push names the real reason when there are local …
juliusmarminge Nov 14, 2026
b5df3c1
fix(web): a scheduled task with a cleared run time no longer saves as…
juliusmarminge Nov 14, 2026
60e4be4
fix(shared): open relative Codex citations with filename punctuation …
StiensWout Nov 14, 2026
8b633d9
fix(web): PDF find matches curly quotes when you type straight ones (…
saphid Nov 14, 2026
d3d7ad9
fix(mobile): merging a PR uses the project's default merge method (#2…
saphid Nov 14, 2026
0487654
fix(web): diagnostics CPU time no longer reads "60s" or "60m" (#29395)
M0xoo Nov 14, 2026
8871c26
fix(cursor): shell commands that exit non-zero are recorded as failed…
saphid Nov 14, 2026
5583b26
fix(server,client): preserve literal JSON command output (#36793)
StiensWout Nov 14, 2026
1e9f93a
fix(mobile): stop showing "cannot control this task" while permission…
torztomasz Nov 14, 2026
ee4ef06
fix(web): use optimistic updates for settings across environments (#2…
flamboh Nov 14, 2026
170c1f7
fix(web): Push on the default branch no longer offers a feature branc…
saphid Nov 14, 2026
154c501
fix(web): long preview annotation comments are no longer dropped from…
saphid Nov 14, 2026
554c893
fix(mobile): long pull request searches on iOS no longer fail the lis…
saphid Nov 14, 2026
043d712
fix(shared): atomic saves handle long filenames (#33250)
Lucenx9 Nov 14, 2026
48afc47
fix(server): message search no longer finds rolled-back turns or canc…
saphid Nov 14, 2026
776698a
fix(web): OpenDocument slide previews no longer print speaker notes (…
geezoria Nov 14, 2026
0d585f7
fix(mobile): cancelled PR checks count as failing in the checks summa…
saphid Nov 14, 2026
2eb8829
fix(mobile): .markdown, .mdown and .mkd files open with a Markdown pr…
saphid Nov 14, 2026
49eb9c8
fix(web,mobile): pull request project filter lists pinned projects fi…
saphid Nov 14, 2026
be2a287
fix(server): Claude Fable 5.2 is offered only from Claude Code 2.1.32…
juliusmarminge Nov 14, 2026
7b26203
fix(mobile): scheduled tasks due within the hour no longer read "Next…
saphid Nov 14, 2026
cfd825c
test(server): title change test ignores a probe pending at browser cl…
t3dotgg Nov 14, 2026
d109866
fix(server): agents can read documents a guest attaches (#29760)
saphid Nov 14, 2026
f05cd35
fix(web): opening a very large folder no longer freezes the Files pan…
thelogicmatrix Nov 14, 2026
abac683
fix(gitlab): a fork's same-named branch no longer hides the branch's …
saphid Nov 14, 2026
b779d40
fix(editors): Open in Zed no longer finds the ZFS event daemon (#33461)
danjdewhurst Nov 14, 2026
77b38f9
fix(server): preview hover and drag fail within their timeout, not up…
only21mil Nov 14, 2026
5a15495
fix(server): skills from CLAUDE_CODE_PLUGIN_DIRS plugins show in the …
DavidMendesOS Nov 14, 2026
284fb23
fix(gitlab): `glab mr new` links the new merge request to the thread …
aravhawk Nov 14, 2026
949dc23
fix(mobile): Android section headers show the collapse arrow when exp…
juccul Nov 14, 2026
7bc4746
fix(claude): tools running at Stop show as stopped, not failed (#29801)
saphid Nov 14, 2026
69525bf
fix(web): a pull request whose title holds a numeric search ranks abo…
only21mil Nov 14, 2026
ff75365
fix(acp-registry): a uv-installed agent launches its managed command,…
Marve10s Nov 14, 2026
d2a9414
fix(server): refuse unresolved UTF-16 merge commits (#36817)
StiensWout Nov 14, 2026
29d517d
fix(server): remove worktrees through their owning repository (#33586)
matallui Nov 14, 2026
73fb6cd
fix(server): RTF attachment text keeps joiners and direction marks (#…
StiensWout Nov 14, 2026
3ceed62
fix(server): scheduled tasks in a non-Git project run in its folder i…
moenzuel Nov 14, 2026
76ae36e
fix(web): deleting a thread with side chats offers to delete its work…
juliusmarminge Nov 14, 2026
dd50613
perf(web): completed Markdown blocks no longer render twice (#33794)
voltcrash Nov 14, 2026
f968db1
perf(web): opening a thread from a draft only renders its sidebar row…
dominikzabcik Nov 14, 2026
ed01784
fix(usage): refetch cached rates early for a model they do not list (…
DrSeedon Nov 14, 2026
bf74669
fix(web): copied email links keep their destination (#36830)
StiensWout Nov 14, 2026
314f1e2
fix(server): message search finds smart apostrophes when scanning (#3…
StiensWout Nov 14, 2026
ccf7ead
fix(shared): preserve whitespace in POSIX PATH directories (#33840)
Lucenx9 Nov 14, 2026
73cbc6b
fix(web): dropdown hover fills expanded Git action rows (#35527)
Dragesia Nov 14, 2026
a4bf792
fix(clients): undoing a settle puts the thread back where you placed …
saphid Nov 14, 2026
1f45f14
fix(web): queued images open in the image viewer (#33298)
OpeOginni Nov 14, 2026
46c9d93
chore(coil): merge upstream/main 1f45f14ae8 (408 commits)
radroid Nov 14, 2026
270d3a1
ci(coil): skip upstream's test that reads the retired macOS preview w…
radroid Nov 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
13 changes: 9 additions & 4 deletions .agents/skills/test-t3-mobile/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,15 @@ prints one JSON line; on failure it names the next command. Mobile verification
includes that step unless the user prohibits it.

For a device you opened in an agent-device session elsewhere (a device pool,
cloud, or remote host), run `vp run mobile:install <ios|android> --session <s>`
from the directory you opened the session in. It installs the cached build into
that session (`--abi arm64-v8a` for an ARM Android device; `--metro <url>` also
opens it against Metro) and never builds.
cloud, or remote host), run `vp run mobile:install <ios|android> --session <s>
--config <file>` from the directory you opened the session in, passing the
`--config` file from `device_open`'s `targetArgs`. Without it, a device pool's
gateway refuses the install, wrongly saying agent-device is too old. It installs
the cached build into that session (`--abi arm64-v8a` for an ARM Android device;
pool Android emulators are x86_64, the default; `--metro <url>` also opens it
against Metro). Without a cached build for this checkout it builds first, which can
outlast the lease, so run `vp run mobile:install <ios|android> --prepare` (with
the same `--abi`) before you open the device.

Start `vp run dev:client` from `apps/mobile`, or reuse a healthy Metro belonging
to this checkout. Open its printed development-client URL with AgentDevice
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/coil-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,10 @@ jobs:
run: vp run --filter @t3tools/desktop ensure:electron

# `@t3tools/monorepo` is the root package; its `test` script is `vp run -r test`.
# The `-t` skips upstream's test that reads desktop-macos-preview-publish.yml, which the fork
# retires. Keep in sync with `scripts/coil/sync-upstream.sh`.
- name: Test
run: vp run --filter '!t3' --filter '!@t3tools/monorepo' --filter '!@t3tools/web' test --testTimeout=120000 --hookTimeout=120000
run: vp run --filter '!t3' --filter '!@t3tools/monorepo' --filter '!@t3tools/web' test --testTimeout=120000 --hookTimeout=120000 -t '^(?!.*packages\sthe\smacOS\spreview.s\sPR\sbundle\sas\suntrusted)'

# Split in two because one headless Chromium running all ~585 web files on these runners lost its
# page late in the run in 5 of 6 runs on 2026-11-13 (`Browser connection was closed`), with no
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/mobile-dev-client.yml
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ jobs:
ios:
name: iOS simulator
if: github.repository == 'pingdotgg/t3code' && (github.event_name != 'workflow_dispatch' || inputs.platform == 'ios')
runs-on: blacksmith-12vcpu-macos-26
runs-on: blacksmith-12vcpu-macos-27
timeout-minutes: 60
concurrency:
group: mobile-dev-client-ios-${{ github.event_name == 'pull_request' && github.event.pull_request.number || inputs.fingerprint || github.sha }}
Expand Down
4 changes: 4 additions & 0 deletions apps/desktop/scripts/ensure-electron-runtime.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ export function ensureElectronRuntime() {
return electronPath;
}

export function setup() {
ensureElectronRuntime();
}

// `file://${argv[1]}` never matches on Windows (drive letters need `file:///C:/`).
if (process.argv[1] && NodeURL.pathToFileURL(process.argv[1]).href === import.meta.url) {
const electronPath = ensureElectronRuntime();
Expand Down
18 changes: 15 additions & 3 deletions apps/desktop/src/app/DesktopApp.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ it.effect.each([false, true])(
const historyStarted = yield* Deferred.make<void>();
const releaseHistory = yield* Deferred.make<void>();
const quitting = yield* Ref.make(false);
const tokenRequested = yield* Deferred.make<void>();
const events: string[] = [];
const record = (event: string) =>
Effect.sync(() => {
Expand Down Expand Up @@ -145,7 +146,7 @@ it.effect.each([false, true])(
configure: Effect.void,
} as PreviewPasskeys.PreviewPasskeys["Service"]),
Effect.provideService(DesktopApplicationMenu.DesktopApplicationMenu, {
configure: Effect.void,
configure: record("menu"),
}),
Effect.provideService(DesktopUpdates.DesktopUpdates, {
configure: Effect.void,
Expand Down Expand Up @@ -224,7 +225,12 @@ it.effect.each([false, true])(
Layer.mock(DesktopClientSettings.DesktopClientSettings, {}),
Layer.mock(DesktopConnectionCatalogStore.DesktopConnectionCatalogStore, {}),
Layer.mock(DesktopIpc.DesktopIpc, {}),
Layer.mock(DesktopLocalEnvironmentAuth.DesktopLocalEnvironmentAuth, {}),
Layer.mock(DesktopLocalEnvironmentAuth.DesktopLocalEnvironmentAuth, {
getBearerToken: record("token").pipe(
Effect.andThen(Deferred.succeed(tokenRequested, undefined)),
Effect.as("token"),
),
}),
Layer.mock(DesktopManagedPolicy.DesktopManagedPolicy, {}),
Layer.succeed(DesktopPrimaryPaste.DesktopPrimaryPaste, { enabled: true }),
Layer.mock(DesktopSshEnvironment.DesktopSshEnvironment, {}),
Expand Down Expand Up @@ -255,7 +261,13 @@ it.effect.each([false, true])(
);
yield* Deferred.await(registrationStarted);
yield* Deferred.await(windowStarted);
assert.deepEqual(events, ["identity", "ready", "identity", "backend", "window"]);
yield* Deferred.await(tokenRequested);
// The backend spawns before menus, and its token is minted without waiting for the renderer.
assert.deepEqual(
events.filter((event) => event !== "token"),
["identity", "ready", "identity", "backend", "menu", "window"],
);
assert.isAbove(events.indexOf("token"), events.indexOf("backend"));
assert.isFalse(yield* Deferred.isDone(registrationStopped));
const shutdown = yield* DesktopShutdown.DesktopShutdown;
yield* shutdown.request;
Expand Down
130 changes: 81 additions & 49 deletions apps/desktop/src/app/DesktopApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import * as PreviewPasskeys from "../preview/Passkeys.ts";
import * as DesktopBackendManager from "../backend/DesktopBackendManager.ts";
import * as DesktopBackendPool from "../backend/DesktopBackendPool.ts";
import * as DesktopHomeOwner from "../backend/DesktopHomeOwner.ts";
import * as DesktopLocalEnvironmentAuth from "../backend/DesktopLocalEnvironmentAuth.ts";
import * as DesktopEnvironment from "./DesktopEnvironment.ts";
import * as DesktopLegacyLocalStorage from "./DesktopLegacyLocalStorage.ts";
import * as DesktopLifecycle from "./DesktopLifecycle.ts";
Expand Down Expand Up @@ -168,13 +169,12 @@ const stopAllPoolInstances = Effect.fn("desktop.app.stopAllPoolInstances")(
},
);

const bootstrap = Effect.gen(function* () {
// Spawns the local backend as soon as the protocol, IPC, and legacy storage that every window needs exist.
const startLocalBackend = Effect.gen(function* () {
const state = yield* DesktopState.DesktopState;
const environment = yield* DesktopEnvironment.DesktopEnvironment;
const desktopSettings = yield* DesktopAppSettings.DesktopAppSettings;
const desktopWindow = yield* DesktopWindow.DesktopWindow;
const snapShot = yield* DesktopSnapShot.DesktopSnapShot;
const appActivation = yield* DesktopAppActivation.DesktopAppActivation;
yield* logBootstrapInfo("bootstrap start");

const settings = yield* desktopSettings.get;
Expand All @@ -193,32 +193,13 @@ const bootstrap = Effect.gen(function* () {
yield* (yield* DesktopAppIdentity.DesktopAppIdentity).resolveUserDataPath,
);

yield* snapShot.initialize;
// Only the user's own login shell PATH shows every t3 a new terminal runs; a fresh install has
// no cached one. Without it, the command is left to Settings.
const installCli = (yield* DesktopCliCommand.DesktopCliCommand).installOnFirstLaunch;
yield* Effect.forkScoped(
(yield* DesktopShellEnvironment.DesktopShellEnvironment).awaitUserShellDiscovery.pipe(
Effect.flatMap((found) =>
found || environment.platform === "win32"
? installCli
: logBootstrapInfo("skipped installing the t3 command without the shell PATH"),
),
),
);

if (!settings.localEnvironmentEnabled) {
yield* logBootstrapInfo("bootstrap skipping local environment (disabled in settings)");
if (!(yield* Ref.get(state.quitting))) {
yield* desktopWindow.createMainIfBackendReady;
}
return;
return false;
}

const pool = yield* DesktopBackendPool.DesktopBackendPool;
const primaryBackend = yield* pool.primary;
const primaryBackend = yield* (yield* DesktopBackendPool.DesktopBackendPool).primary;
const serverExposure = yield* DesktopServerExposure.DesktopServerExposure;
const wslBackend = yield* DesktopWslBackend.DesktopWslBackend;

if (environment.isDevelopment && Option.isNone(environment.configuredBackendPort)) {
return yield* new DesktopDevelopmentBackendPortRequiredError();
Expand All @@ -237,7 +218,8 @@ const bootstrap = Effect.gen(function* () {
"This T3 home is unavailable",
DesktopHomeOwner.homeOwnedMessage(owner),
);
return yield* (yield* ElectronApp.ElectronApp).quit;
yield* (yield* ElectronApp.ElectronApp).quit;
return false;
}

const backendPortSelection = yield* resolveDesktopBackendPort(environment.configuredBackendPort);
Expand Down Expand Up @@ -275,29 +257,73 @@ const bootstrap = Effect.gen(function* () {
);
}

if (!(yield* Ref.get(state.quitting))) {
if (settings.wslOnly === true && settings.wslBackendEnabled === true) {
yield* desktopWindow.showConnectingSplash;
}
yield* primaryBackend.start;
yield* logBootstrapInfo("bootstrap backend start requested");
// WSL-only fallback can change the primary endpoint before readiness.
const config = yield* primaryBackend.currentConfig;
if (
!environment.isDevelopment &&
!settings.wslOnly &&
Option.isSome(config) &&
Option.isNone(config.value.preflightFailure)
) {
yield* desktopWindow.ensureMain;
if (yield* Ref.get(state.quitting)) {
return false;
}
if (settings.wslOnly === true && settings.wslBackendEnabled === true) {
yield* desktopWindow.showConnectingSplash;
}
yield* primaryBackend.start;
yield* logBootstrapInfo("bootstrap backend start requested");
// The renderer asks for this token first; minting it at readiness saves a round trip.
yield* Effect.forkScoped(
(yield* DesktopLocalEnvironmentAuth.DesktopLocalEnvironmentAuth).getBearerToken.pipe(
Effect.ignore,
),
);
return true;
}).pipe(Effect.withSpan("desktop.startLocalBackend"));

const bootstrap = Effect.fn("desktop.bootstrap")(function* (backendStarted: boolean) {
const state = yield* DesktopState.DesktopState;
const environment = yield* DesktopEnvironment.DesktopEnvironment;
const desktopSettings = yield* DesktopAppSettings.DesktopAppSettings;
const desktopWindow = yield* DesktopWindow.DesktopWindow;
const snapShot = yield* DesktopSnapShot.DesktopSnapShot;
const appActivation = yield* DesktopAppActivation.DesktopAppActivation;
const settings = yield* desktopSettings.get;
if (settings.localEnvironmentEnabled && (!backendStarted || (yield* Ref.get(state.quitting)))) {
return;
}

yield* snapShot.initialize;
// Only the user's own login shell PATH shows every t3 a new terminal runs; a fresh install has
// no cached one. Without it, the command is left to Settings.
const installCli = (yield* DesktopCliCommand.DesktopCliCommand).installOnFirstLaunch;
yield* Effect.forkScoped(
(yield* DesktopShellEnvironment.DesktopShellEnvironment).awaitUserShellDiscovery.pipe(
Effect.flatMap((found) =>
found || environment.platform === "win32"
? installCli
: logBootstrapInfo("skipped installing the t3 command without the shell PATH"),
),
),
);

if (!settings.localEnvironmentEnabled) {
if (!(yield* Ref.get(state.quitting))) {
yield* desktopWindow.createMainIfBackendReady;
}
yield* appActivation.start.pipe(
Effect.tap(() => logBootstrapInfo("desktop app control socket ready")),
Effect.catch((error) => logStartupError("desktop app control socket unavailable", { error })),
);
yield* Effect.forkScoped(wslBackend.reconcile);
return;
}
}).pipe(Effect.withSpan("desktop.bootstrap"));

const primaryBackend = yield* (yield* DesktopBackendPool.DesktopBackendPool).primary;
// WSL-only fallback can change the primary endpoint before readiness.
const config = yield* primaryBackend.currentConfig;
if (
!environment.isDevelopment &&
!settings.wslOnly &&
Option.isSome(config) &&
Option.isNone(config.value.preflightFailure)
) {
yield* desktopWindow.ensureMain;
}
yield* appActivation.start.pipe(
Effect.tap(() => logBootstrapInfo("desktop app control socket ready")),
Effect.catch((error) => logStartupError("desktop app control socket unavailable", { error })),
);
yield* Effect.forkScoped((yield* DesktopWslBackend.DesktopWslBackend).reconcile);
});

const startup = Effect.gen(function* () {
const appIdentity = yield* DesktopAppIdentity.DesktopAppIdentity;
Expand Down Expand Up @@ -369,14 +395,20 @@ const startup = Effect.gen(function* () {
});
}
yield* appIdentity.configure;
yield* previewPasskeys.configure;
yield* applicationMenu.configure;
// Sets canInstallUpdates, which the backend bootstrap payload reads.
yield* updates.configure;
yield* DesktopRemoteUpdates.listen;
yield* DesktopStartupRecovery.listen;
const backendStarted = yield* startLocalBackend.pipe(
Effect.catchCause((cause) => fatalStartupCause("bootstrap", cause)),
);
yield* previewPasskeys.configure;
yield* applicationMenu.configure;
// Portal identity is prepared pre-ready; MIME helpers must not gate the backend or window.
yield* linuxUrlHandler.register.pipe(Effect.forkScoped);
yield* bootstrap.pipe(Effect.catchCause((cause) => fatalStartupCause("bootstrap", cause)));
yield* bootstrap(backendStarted).pipe(
Effect.catchCause((cause) => fatalStartupCause("bootstrap", cause)),
);
}).pipe(Effect.withSpan("desktop.startup"));

const scopedProgram = Effect.scoped(
Expand Down
29 changes: 29 additions & 0 deletions apps/desktop/src/app/DesktopLinuxUrlHandler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,35 @@ describe("DesktopLinuxUrlHandler", () => {
assert.include(entry, "Icon=/home/al ice/icons/T3\\\\x.png");
});

it.each([
{ from: "T3-Code-0.1.8-x86_64.AppImage", to: "T3-Code-x86_64.AppImage", restored: true },
{
from: "T3-Code-0.1.9-nightly.20261110.4449-arm64.AppImage",
to: "T3-Code-Nightly-arm64.AppImage",
restored: true,
},
{ from: "T3-Code-0.1.8-x86_64.AppImage", to: "T3-Code-0.1.9-x86_64.AppImage", restored: false },
{ from: "t3code.AppImage", to: "T3-Code-x86_64.AppImage", restored: false },
{ from: "T3-Code-x86_64.AppImage", to: "T3-Code-x86_64.AppImage", restored: false },
{ from: "../T3-Code-0.1.8-x86_64.AppImage", to: "T3-Code-x86_64.AppImage", restored: false },
])("finds the launch path an update from $from to $to removed", ({ from, to, restored }) => {
for (const dir of ["/home/alice/Applications", '/home/al ice/My "100%" $Apps\\x']) {
const previous = dir + "/" + from;
const previousEntry = DesktopLinuxUrlHandler.renderUrlHandlerDesktopEntry({
displayName: "T3 Code (Beta)",
execTarget: previous,
scheme: "t3code",
});
assert.equal(
DesktopLinuxUrlHandler.replacedVersionedAppImagePath({
previousEntry,
appImagePath: dir + "/" + to,
}),
restored ? previous : null,
);
}
});

it.effect(
"writes the handler entry, refreshes the MIME cache, and claims the scheme default",
() => {
Expand Down
32 changes: 32 additions & 0 deletions apps/desktop/src/app/DesktopLinuxUrlHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,38 @@ export function renderUrlHandlerDesktopEntry(input: {
].join("\n");
}

function parseUrlHandlerExecTarget(entry: string): string | null {
const exec = /^Exec=(.*) %U$/mu.exec(entry)?.[1];
if (exec === undefined) return null;
const unescaped = exec.replace(/\\([\\nrt])/gu, (_, char: string) =>
char === "n" ? "\n" : char === "r" ? "\r" : char === "t" ? "\t" : char,
);
const quoted = /^"(.*)"$/su.exec(unescaped)?.[1];
return (
quoted === undefined ? unescaped : quoted.replace(/\\([\\`$"])/gu, (_, char: string) => char)
).replaceAll("%%", "%");
}

const APPIMAGE_NAME_VERSION = /\d+\.\d+\.\d+/u;

// An updater from before version-free AppImage names deletes its own file and installs the update
// beside it under the new name. The previous launch's entry still names the path launchers use.
export function replacedVersionedAppImagePath(input: {
readonly previousEntry: string;
readonly appImagePath: string;
}): string | null {
const previous = parseUrlHandlerExecTarget(input.previousEntry);
if (previous === null) return null;
const previousName = previous.slice(previous.lastIndexOf("/") + 1);
const currentName = input.appImagePath.slice(input.appImagePath.lastIndexOf("/") + 1);
return previous.startsWith("/") &&
previous.slice(0, -previousName.length) === input.appImagePath.slice(0, -currentName.length) &&
APPIMAGE_NAME_VERSION.test(previousName) &&
!APPIMAGE_NAME_VERSION.test(currentName)
? previous
: null;
}

// Docks may look up the Wayland app id without a desktop entry; icon theme lookups are case-sensitive.
const LINUX_THEME_ICON_SIZE = "256x256";

Expand Down
Loading
Loading