Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
785 commits
Select commit Hold shift + click to select a range
cfb7cae
feat(web): bindable shortcut to regenerate a thread's title (#33987)
sharanry Nov 10, 2026
3cdc504
fix(server): linked projects keep their repository identity while it …
juliusmarminge Nov 10, 2026
524a531
fix(mobile): tool call commands are highlighted and monospaced like o…
juliusmarminge Nov 10, 2026
20723d6
fix: Claude monitor wakes no longer fire a completion alert per line …
juliusmarminge Nov 10, 2026
81c3da3
fix(server): removed thread worktrees keep their project's skills in …
juliusmarminge Nov 10, 2026
f06bfa6
fix(web): drag command palette threads into the composer (#33990)
Yash-Singh1 Nov 10, 2026
08af12d
fix(shared): show zero seconds in minute durations (#33994)
Yash-Singh1 Nov 10, 2026
350ecd6
fix(web): closing the right panel returns focus to where it was (#32569)
juliusmarminge Nov 10, 2026
1fed70c
fix(server): say why threads without a project are unavailable (#32342)
juliusmarminge Nov 10, 2026
3051b32
fix: chat file links open the file agents cite (#33943)
juliusmarminge Nov 10, 2026
283fa1f
fix(clients): scroll truncated command output notice with logs (#34011)
Yash-Singh1 Nov 10, 2026
a11ad74
fix(web): show app bundle icons and open apps from markdown links
Yash-Singh1 Nov 10, 2026
71a1c49
feat(opencode): project native todo updates into checklists
Yash-Singh1 Nov 10, 2026
e8d3075
fix(antigravity): recognize Gemini 4 Carbon and its quota (#33991)
DrSeedon Nov 10, 2026
05020d6
perf(client): reopening a finished command row no longer refetches it…
juliusmarminge Nov 10, 2026
5f2bb93
perf(server): user-only message reads use the user-message index for …
juliusmarminge Nov 10, 2026
a88a0ad
fix(web): keep HTML previews anchored when accordions expand (#34003)
Yash-Singh1 Nov 10, 2026
44e894f
fix(web): preserve search result titles in drag previews (#34017)
Yash-Singh1 Nov 10, 2026
d256170
fix: file links with line ranges open at their first line (#34006)
juliusmarminge Nov 10, 2026
5be6bc9
fix(codex): show image generation tool calls
Yash-Singh1 Nov 10, 2026
871b009
fix(pi): a steer Pi has not read yet shows as waiting, not steered (#…
juliusmarminge Nov 10, 2026
d756fed
fix(server): provider switches hand off started cancelled runs (#34016)
juliusmarminge Nov 10, 2026
f86e21f
fix(web,mobile): replace sparkles icons and ban them with a lint rule…
flamboh Nov 10, 2026
d290c1f
fix(github): a proxy's 403 with Retry-After is no longer reported as …
juliusmarminge Nov 10, 2026
9cd7a04
fix(web): sending from an empty citation comment clears the composer …
juliusmarminge Nov 10, 2026
78201b0
fix(server): text generation fallback respects project provider setti…
Muzammil-Bit Nov 10, 2026
44ebb2f
feat(usage): show Muse Code limits, and xAI and Antigravity accounts …
StiensWout Nov 10, 2026
8fc6fd0
fix(web): preserve previews during attachment preparation (#33949)
Yash-Singh1 Nov 10, 2026
3725817
fix(desktop): input during window teardown no longer throws in the ma…
juliusmarminge Nov 10, 2026
d6d1763
fix(web): sent messages keep the numbers written on list items (#33820)
tsapa44 Nov 10, 2026
1a2a4a5
fix(server): quitting stops an agent-device daemon left by an earlier…
juliusmarminge Nov 10, 2026
3cb99ce
fix(mobile): attaching larger images no longer crashes with a BigInt …
juliusmarminge Nov 10, 2026
17a6a01
feat(mobile): pick a voice environment once, then its method (#34073)
juliusmarminge Nov 10, 2026
d91915d
fix(server): a t3 thread send to a finished delegated child notifies …
juliusmarminge Nov 10, 2026
43915a4
fix(web): question panel header text sits centered in its row (#34095)
juliusmarminge Nov 10, 2026
ae14293
feat(scripts): scenarios prove a fix in the real app with e2e, on web…
juliusmarminge Nov 10, 2026
9e1f81c
feat(claude): Fable resets are offered and redeemed apart from weekly…
juliusmarminge Nov 10, 2026
04f6cfc
fix(desktop): desktop IPC only answers the main app window (#34094)
juliusmarminge Nov 10, 2026
79bca43
feat(server): voice models reuse copies already on disk (#34096)
juliusmarminge Nov 11, 2026
1d80047
fix(web): scroll project picker to top on first result (#34113)
Yash-Singh1 Nov 11, 2026
3a8c250
feat(opencode): track native image job outcomes and previews (#34089)
Yash-Singh1 Nov 11, 2026
b883156
fix(scripts): scenarios run where localhost resolves to IPv6 first (#…
juliusmarminge Nov 11, 2026
768f17c
ci: browser secret helper apt step fetches fewer indexes (#33966)
t3dotgg Nov 11, 2026
d152d2c
fix(client-runtime): a search query pasted from github.com lists pull…
juliusmarminge Nov 11, 2026
4ca1039
fix(web): tighter outdated-conversation cards in the PR code panel (#…
Yash-Singh1 Nov 11, 2026
ccc7b2d
fix(web): MCP App cards no longer flash white in dark mode while the …
juliusmarminge Nov 11, 2026
92f1b8e
fix(peer): link requests use the addresses the app already has for a …
t3dotgg Nov 11, 2026
c90b678
fix(server): Find frees searched thread text after one idle minute (#…
t3dotgg Nov 11, 2026
f7b81e1
fix(web): settings search shortcuts follow the physical key on non-US…
juliusmarminge Nov 11, 2026
bbd51f7
fix(server): import Codex chats moved into a project from the scratch…
juliusmarminge Nov 11, 2026
5c97ada
fix(desktop): clear stale GPU caches when the Electron version change…
juliusmarminge Nov 11, 2026
b3fdf2b
fix(web): PR links jump to the comment, diff line, checks or commits …
Yash-Singh1 Nov 11, 2026
fae2d20
fix(cli): installers retry transient GitHub errors (#32913)
juliusmarminge Nov 11, 2026
facd190
fix(web): opening the terminal with Cmd+J no longer re-renders the wh…
juliusmarminge Nov 11, 2026
0f13d2c
refactor(web): remove icon morphing (#33985)
maria-rcks Nov 11, 2026
ed52af3
feat(opencode): track native shell jobs across turns
Yash-Singh1 Nov 11, 2026
631ea1b
fix(server): restart send stops a Claude turn and runs the message ne…
juliusmarminge Nov 11, 2026
ba4d01c
fix(shared): login-shell environment probe ignores DEBUG trap output …
juliusmarminge Nov 11, 2026
0815d98
fix(web): make Q&A option outlines visible across themes (#34178)
Yash-Singh1 Nov 11, 2026
05adc16
fix(web): hide empty replies when renders show the result (#34182)
Yash-Singh1 Nov 11, 2026
4363d0b
fix(web): mouse tilt wheel no longer switches threads on Windows and …
juliusmarminge Nov 11, 2026
32fdad5
fix(web): timeline minimap preview no longer steals hover or jumps ar…
NoomStuff Nov 11, 2026
c192c67
fix(server): auto thread sends queue while a turn is stopping (#34163)
tanav29 Nov 11, 2026
c03f84b
fix(server): stream the usage-scan cache to disk instead of one strin…
juliusmarminge Nov 11, 2026
5b11efe
fix(clients): images the agent opens stay visible in the chat (#30473)
fedeinfe Nov 11, 2026
31bf2f7
fix(client-runtime): pasted repository page URLs clone the repository…
juliusmarminge Nov 11, 2026
1161141
fix(web): trackpad flicks over the right panel tabs no longer navigat…
juliusmarminge Nov 11, 2026
a0efdae
fix: new threads move from draft to Working in one step (#33783)
juliusmarminge Nov 11, 2026
c82e1ba
fix(gitlab): review comments can cover a range of lines (#30535)
TonybynMp4 Nov 11, 2026
42185a6
test(web): right panel tab swipe test runs as macOS on any CI host (#…
juliusmarminge Nov 11, 2026
1c17285
fix(shared): cite assistant messages with IDs over 512 characters (#2…
juliusmarminge Nov 11, 2026
034f3ba
fix(server): updates copy the database while the server still runs wh…
binjamshid Nov 11, 2026
a03d9bc
fix(mobile): file links in question cards open the file viewer (#29151)
juliusmarminge Nov 11, 2026
37452ee
fix(server): cloning into a stranded clone project's empty folder reu…
juliusmarminge Nov 11, 2026
492f711
fix(desktop): stable updates no longer show a nightly's release notes…
juliusmarminge Nov 11, 2026
2163d41
fix(shared): Open in Zed ignores the OpenZFS zed daemon on Linux (#33…
juliusmarminge Nov 11, 2026
7e45dcd
fix(mobile): chat code blocks colour diff, kotlin, sql and other lang…
juliusmarminge Nov 11, 2026
543ee27
fix(server): fork Claude threads after project root changes (#22836)
juliusmarminge Nov 11, 2026
8030067
fix(web): snooze times read naturally in context menus (#24945)
TonybynMp4 Nov 11, 2026
dea8472
feat(web): label chips show the label's description on hover (#28732)
TonybynMp4 Nov 11, 2026
b6d3097
feat(web): composer strip names the worktree folder (#28459)
TonybynMp4 Nov 11, 2026
362ef9a
feat(gitlab): revert a merged merge request (#30556)
TonybynMp4 Nov 11, 2026
399df48
fix(claude): version errors from a custom endpoint no longer say to r…
binjamshid Nov 11, 2026
8cbc959
fix(web): files marked Viewed stay folded when a pull request's Code …
Umais-Adeed Nov 11, 2026
4e1be34
feat(server): watched GitHub pull requests react to host events, not …
juliusmarminge Nov 11, 2026
5badea5
fix(server): hide passive Claude Stop-hook summaries (#22964)
juliusmarminge Nov 11, 2026
75b22bf
fix(web): dismiss image path tooltips after preview and scroll (#30620)
voltcrash Nov 11, 2026
b0f12e1
fix(server): PR sync and run-status checks stop reading whole thread …
juliusmarminge Nov 11, 2026
950c342
fix(server): preview snapshots keep page text beside large accessibil…
juliusmarminge Nov 11, 2026
40c3682
feat(web): screen readers can hear the agent's messages and steps dur…
shivamhwp Nov 11, 2026
a536ff7
fix(server): thread search finds phrases inside quotes and their comm…
only21mil Nov 11, 2026
f697d4d
fix(web): local server cards in the browser empty state take pointer …
juliusmarminge Nov 11, 2026
fc5edd3
fix(server): worktrees cut from a non-default base no longer show the…
t3dotgg Nov 11, 2026
6e21f81
fix(desktop): wait for the local server to exit when quitting (#22996)
juliusmarminge Nov 11, 2026
c50dd8e
fix(server): agent continuations preserve the working timer start (#2…
juliusmarminge Nov 11, 2026
8c9af54
fix(web): disable the git actions menu when nothing in it is usable (…
Serendeep Nov 11, 2026
94f54a5
fix(server): preserve active turns when switching provider instances …
juliusmarminge Nov 11, 2026
46afd69
fix(server): scheduled task updates keep the saved workspace unless t…
juliusmarminge Nov 11, 2026
5bb5d53
fix(web): full-screen HTML pages fit their content and zoom by reflow…
Zeus-Deus Nov 11, 2026
1bdf470
fix(web): project actions auto-open Preview in web clients (#34048)
juliusmarminge Nov 11, 2026
24e7747
fix(server): a follow-up delegated task waits for a run its child que…
juliusmarminge Nov 11, 2026
25631c3
fix(server): new worktrees refresh their index once, so captures and …
josephv123 Nov 11, 2026
e2a7814
fix(usage): Grok and Cursor usage limits show pace and the even-spend…
wookiist Nov 11, 2026
996b43f
fix(web): retain diff selection across navigation (#22347)
aleo113 Nov 11, 2026
0d36f2b
fix(mobile): subscription widget no longer expires on a window that a…
juliusmarminge Nov 11, 2026
b5256ad
fix(opencode): verify CLI updates when loopback server is still runni…
intrepid37 Nov 11, 2026
729f675
fix(usage): Claude subagent output is no longer undercounted (#20276)
rfrost-xyz Nov 11, 2026
d0d0608
fix(server): a remote update points the service unit at the runtime i…
Marve10s Nov 11, 2026
8d23699
fix(server): a limited provider's queue stays held after another prov…
Marve10s Nov 11, 2026
9ef52de
fix(shared): keep spreadsheet shorthand as inline code (#23203)
juliusmarminge Nov 11, 2026
25f4c9d
fix(web): offer retry while an environment reconnects (#23194)
juliusmarminge Nov 11, 2026
c9dfc40
fix(server): custom Codex providers no longer report native quota (#1…
fixfon Nov 11, 2026
e93f6ea
fix(desktop): Cmd+F now searches the page in the integrated browser (…
armanarutiunov Nov 11, 2026
f6433db
fix(desktop): an SSH password prompt that ended leaves the dialog ins…
Umais-Adeed Nov 11, 2026
2c74ea6
fix(web): render Claude insight blocks as a callout (#22239)
macodev00 Nov 11, 2026
ba32aab
fix(scheduler): show short server timezone on fixed-time labels (#23111)
shawk08033 Nov 11, 2026
4382138
fix(web): focus the primary action when confirmation dialogs open (#1…
rgrvlsk Nov 11, 2026
49bab99
fix(web): Changes row matches the diff comparison (#19553)
whoisaldo Nov 11, 2026
75c7fb2
fix(server): imported ACP sessions show their native history (#22155)
only21mil Nov 11, 2026
c266631
fix(preview): always return evaluated results by value (#22948)
juliusmarminge Nov 11, 2026
afb4f91
fix(provider-core): a model reply of "title" no longer replaces the t…
juliusmarminge Nov 11, 2026
52d621a
fix(desktop,web): Open in runs locally for a background service shari…
KinanLak Nov 11, 2026
d835e43
fix(web): question answers submit while normal sends are blocked (#22…
t3dotgg Nov 11, 2026
fd9b2c3
fix(server): cancelling a background-only delegated task reports it i…
only21mil Nov 11, 2026
54a5c51
fix(web): fall back to a readable server for shared repositories (#21…
sanjaibalajee Nov 11, 2026
2828f28
fix(web): composer follows an optionless thread instead of the settin…
f4llenz Nov 11, 2026
fcddd73
fix(web): don't save retention age until committed (#22208)
macodev00 Nov 11, 2026
faa8ad6
fix(server): one dropped probe no longer lists a live linked peer as …
juliusmarminge Nov 11, 2026
ab9df1d
chore(release): prepare v0.1.9
t3-code-bot[bot] Nov 11, 2026
36f4e07
fix(server): preview automation reports ambiguous selectors instead o…
juliusmarminge Nov 11, 2026
1530bec
fix(opencode): a context overflow that OpenCode compacts no longer fa…
juliusmarminge Nov 11, 2026
691b970
fix(web): Ctrl + "+" zooms on keyboard layouts with a dedicated plus …
juliusmarminge Nov 11, 2026
ea5f85e
fix(ci): release version bump push retries when main moves (#34326)
t3dotgg Nov 11, 2026
5da53f8
fix(server): CLI commands no longer migrate the database of a running…
juliusmarminge Nov 11, 2026
d56b82c
fix(web): keep saved default model when changing effort (#22193)
macodev00 Nov 11, 2026
6700cf6
fix(web): reveal expanded work rows hidden behind the composer (#21968)
ln-bodicherla Nov 11, 2026
b3f5d52
fix(composer): steer instead of queueing during automatic compaction …
NikitaMGrimm Nov 11, 2026
f3da8ff
feat(gitlab): resolve overview threads from Summary and Timeline (#30…
TonybynMp4 Nov 11, 2026
2718827
fix(web): pull request search keeps partial-word matches after GitHub…
juliusmarminge Nov 11, 2026
835e726
fix(server): Claude subagents no longer show the parent's effort (#17…
juansuaya17 Nov 11, 2026
d806251
fix(server): runs cancelled by a server restart say why in the thread…
juliusmarminge Nov 11, 2026
a74ee4c
fix(client-runtime): server updates stop waiting 32 minutes when the …
juliusmarminge Nov 11, 2026
cbc68c9
fix(web): Stop shows a pending state and repeat clicks no longer resu…
voida6 Nov 11, 2026
e0379fb
fix(web): collapsed reasoning previews no longer process the whole bl…
juliusmarminge Nov 11, 2026
52e8788
fix(server): storage cleanup skips stale worktree paths under a regul…
juliusmarminge Nov 11, 2026
dab06c0
fix(terminal): use a byte budget for Ghostty scrollback (#8766)
zero-two-rafaeltab Nov 11, 2026
bc8583b
fix(server): storage cleanup keeps worktrees whose file listing excee…
juliusmarminge Nov 11, 2026
a577e94
fix(server): delete temporary ACP health probe sessions (#25397)
juliusmarminge Nov 11, 2026
ad0b2a9
perf(client): streamed text no longer republishes thread queue and ch…
juliusmarminge Nov 11, 2026
8f4166b
fix(web): convert composer list markers completed later (#22997)
juliusmarminge Nov 11, 2026
4901343
test: remove tests that repeat another case or restate the source (#3…
shivamhwp Nov 11, 2026
0af2d21
fix(server): drop stale queued pull-request watch wakes (#21239)
Sinan53x Nov 11, 2026
d50a6fd
fix(web): preview recordings stay decodable after a viewport resize (…
MansTomb Nov 11, 2026
896e64f
fix(server): only offer claude update for native Claude installs (#14…
AI091 Nov 11, 2026
d2c2595
fix(server): tell outside agents which MCP tools need a thread and th…
juliusmarminge Nov 11, 2026
fb7e558
test(web): theme search test no longer flakes on slow runners (#34417)
t3dotgg Nov 11, 2026
afa617b
fix(web): branch picker no longer interrupts a running turn (#15255)
ScottN-PV Nov 11, 2026
a68bd77
fix(grok): apply the selected reasoning effort to ACP sessions (#19573)
StiensWout Nov 11, 2026
429c0ac
fix(server): timed-out git commands that ignore SIGTERM no longer sta…
juliusmarminge Nov 11, 2026
1d152c3
fix(desktop): Group Linux windows under the installed launcher (#10895)
mwolson Nov 11, 2026
479ee74
fix(web): a thread started from a pull request links it (#15848)
lnieuwenhuis Nov 11, 2026
5534467
fix(mobile): browser address bar and Take control no longer hide unde…
eimexdev Nov 11, 2026
0629735
fix(web): thread controls hide while the mobile sidebar is open (#27490)
juliusmarminge Nov 11, 2026
4c68fdc
fix(web): the terminal cursor no longer leaves faint lines when it bl…
tiliakoos Nov 11, 2026
3ed5fb2
fix(shared): Claude plugin skills no longer show their name twice (#2…
juliusmarminge Nov 11, 2026
a625e0b
fix(terminal): identify T3 Code terminal sessions (#9954)
juliusmarminge Nov 11, 2026
7e565c5
fix(git): stop new threads inheriting historical branch PRs (#34218)
juliusmarminge Nov 11, 2026
2dfbad7
fix(server): t3 serve no longer offers --auto-bootstrap-project-from-…
juliusmarminge Nov 11, 2026
31eea88
fix(rewind): allow conversation-only rewind in non-git workspaces (#1…
Revens2 Nov 11, 2026
f5fe079
fix(web): Office previews say "1 page", "1 sheet", "1 slide" and "1 r…
spoukyii Nov 11, 2026
5ee7f6f
fix(chat): show late async answers in their own runs (#23249)
juliusmarminge Nov 11, 2026
bc3eb6d
fix(web): fix japanese text in file viewer not rendering (#29051)
Natur7a Nov 11, 2026
bc9c84e
docs(mcp): t3_thread_update lists only its rename and title actions (…
juliusmarminge Nov 11, 2026
60efd7c
fix(server): t3_thread_launch refuses models the provider does not ad…
juliusmarminge Nov 11, 2026
15695ee
fix(opencode): omit unsupported reasoning options from catalog models…
AbdulSCSkeu Nov 11, 2026
84478e0
fix(web): long merged spreadsheet selections no longer crash (#34331)
voltcrash Nov 11, 2026
d0c7147
fix(pi): rewinding works after the Pi session was released (#26322)
juliusmarminge Nov 11, 2026
787c59c
fix(web): Word previews no longer cut ordinary documents short (#32040)
yaacovcorcos Nov 11, 2026
184bb39
fix(server): MCP tools reject top-level arguments they do not declare…
juliusmarminge Nov 11, 2026
20584ba
fix(server): slow title generations no longer hold every effect worke…
juliusmarminge Nov 11, 2026
1a3fbee
fix(cursor): Cursor no longer adds attribution when cli-config turns …
juliusmarminge Nov 11, 2026
7c12233
fix(server): listing linked environments no longer waits out an aslee…
juliusmarminge Nov 11, 2026
bff276e
fix(server): Git failures no longer record checkpoints as missing (#2…
juliusmarminge Nov 11, 2026
77d17b1
fix(provider-acp-registry): prepared binary agents stay ready when th…
juliusmarminge Nov 11, 2026
4bf4ae7
fix(desktop): annotation tool keys work after clicking a toolbar butt…
juliusmarminge Nov 11, 2026
7f65c9c
fix(server): PR sync stops reading missing pull requests every minute…
abiassi Nov 11, 2026
26ccb93
fix(server): failed provider updates show the updater's error, not it…
juliusmarminge Nov 11, 2026
3c7424e
fix(server): a busy embedded frame no longer holds copy keys back (#3…
juliusmarminge Nov 11, 2026
ddc3cef
fix(clients): collapsed turns show one context-compacted divider (#34…
binjamshid Nov 11, 2026
1fa250e
fix(mobile): un-settle while a settle is pending is no longer ignored…
juliusmarminge Nov 11, 2026
d5dc111
fix(ssh): reconnect and disconnect ignore a remote pid file that no l…
juliusmarminge Nov 11, 2026
1278628
fix(server): device setup names a missing npm instead of a generic fa…
juliusmarminge Nov 11, 2026
e6afd2a
fix(web): render citation chips in the collapsed composer (#22148)
EtanHey Nov 11, 2026
4599e55
fix(server): agents settle this thread when asked (#26765)
juliusmarminge Nov 11, 2026
6f2ce81
fix(web): copying commands with prose no longer adds code fences (#24…
juliusmarminge Nov 11, 2026
a91d6c8
fix(server): Claude effort picker marks levels capped by maxEffortLev…
juliusmarminge Nov 11, 2026
1a1a573
fix(web): start clone when destination is picked in file manager (#22…
macodev00 Nov 11, 2026
bd02e64
fix(web): expanding a diff whose files changed no longer crashes (#28…
juliusmarminge Nov 11, 2026
303903a
fix(server): a steer during a delegate_task wait no longer drops the …
juliusmarminge Nov 11, 2026
20081ef
fix(server): subagent threads settle with their parent instead of swe…
mikeohuo Nov 11, 2026
9d7384d
fix(client-runtime): reopening a folder picker refreshes its listing …
juliusmarminge Nov 11, 2026
1843c93
fix(chat): keep scratch file links usable (#30768)
voltcrash Nov 11, 2026
9cb45ec
fix(server): text generation falls back to an enabled custom instance…
juliusmarminge Nov 11, 2026
c75a58e
fix(server): peer link migrations 71 and 72 rerun safely (#26834)
juliusmarminge Nov 11, 2026
a48d7c6
fix(ssh): explain how to recover from failed host key checks (#23785)
juliusmarminge Nov 11, 2026
a50ebef
fix(server): show when a Claude steer is waiting for acceptance (#24785)
juliusmarminge Nov 11, 2026
0e1f01e
fix(web): keep grouped project icons consistent in settings (#14493)
hpflatorre Nov 11, 2026
0ceaa9a
fix(server): update branch labels after terminal checkouts (#23422)
juliusmarminge Nov 11, 2026
4778457
fix(web): track switch dialog no longer offers a switch that moves no…
juliusmarminge Nov 11, 2026
ee21337
fix(shared): a zero-credit cap no longer marks seat-based Codex out o…
juliusmarminge Nov 11, 2026
940b7a4
fix(web): screen readers can browse and Tab through the settings sect…
juliusmarminge Nov 11, 2026
b125e89
fix(server): Codex forks no longer request full turn history (#24537)
juliusmarminge Nov 11, 2026
cff8bfc
fix(web): keep model favorites usable after disabling a provider (#23…
juliusmarminge Nov 11, 2026
621f0e7
fix(server): workspace search no longer indexes the home directory (#…
juliusmarminge Nov 11, 2026
cdbfae8
fix(claude): a killed Claude process names its signal on the failed t…
juliusmarminge Nov 11, 2026
546036e
fix(server): t3 service install works on Linux hosts without a login …
juliusmarminge Nov 11, 2026
cdd1c6a
fix(server): Copilot threads load optional T3 tools on demand (#34245)
juliusmarminge Nov 11, 2026
cc6c0d2
fix(server): runtime prune no longer keeps a version whose directory …
juliusmarminge Nov 11, 2026
f15fbde
fix(server): branch switch no longer kills a slow git checkout (#23539)
juliusmarminge Nov 11, 2026
362ac8d
fix(server): fail Codex turns stuck in a provider retry (#33130)
maria-rcks Nov 11, 2026
f796df8
fix(server,desktop): browser tools report why a page failed to load (…
robertnisipeanu Nov 11, 2026
7d8f6c9
fix(server): show a context handoff when a provider conversation can'…
juliusmarminge Nov 11, 2026
335d8b5
fix(server): Claude --settings and prompt-file launch args expand ~ (…
juliusmarminge Nov 11, 2026
458a792
fix(server): a Claude thread waiting on a ScheduleWakeup stays in Wor…
juliusmarminge Nov 11, 2026
faed05d
fix(server): usage prices long-context requests at above-tier rates (…
juliusmarminge Nov 11, 2026
f495217
fix(server): Simlock open failures show what agent-device reported (#…
juliusmarminge Nov 11, 2026
3aea655
fix(clients): show the right app name and thread context (#18442)
chasemakes Nov 11, 2026
c4cf585
fix(server): long Claude sessions import instead of being skipped (#2…
juliusmarminge Nov 11, 2026
675d2bd
fix(server): closed PR watches end even when the activity read fails …
juliusmarminge Nov 11, 2026
731c873
fix(desktop): a hidden preview tab no longer keeps the display awake …
juliusmarminge Nov 11, 2026
52c1491
fix(server): successful worktree handoffs complete normally (#24545)
juliusmarminge Nov 11, 2026
81e9368
fix(mobile): swipe action labels stay whole at larger Android text si…
juliusmarminge Nov 11, 2026
173374c
fix(server): opening a pull request loads while its host is rate-limi…
juliusmarminge Nov 11, 2026
8b21cbd
fix(server): Codex turns that auto-compact end instead of looping on …
juliusmarminge Nov 11, 2026
3cfbc36
fix(server): keep queued Claude workflow members pending (#25325)
juliusmarminge Nov 11, 2026
b264e11
fix(server): t3 doctor warns how long reclaiming takes and shows each…
juliusmarminge Nov 11, 2026
686121d
fix(server): recover service PATH after a slow login shell probe (#23…
juliusmarminge Nov 11, 2026
28bbc91
fix(server): say Git isn't installed when a new project can't run git…
juliusmarminge Nov 11, 2026
0318ead
fix(server): agent clones are no longer cut off after 2 minutes (#27588)
juliusmarminge Nov 11, 2026
1a8ecc6
feat(web): a quote in a sent message shows as an inset card (#34181)
maria-rcks Nov 11, 2026
b015ffd
perf(server): very long threads open about 10x faster (#34490)
t3dotgg Nov 11, 2026
c8e8b58
fix(web): improve Excel spreadsheet previews (#34429)
Yash-Singh1 Nov 11, 2026
f31ce3e
fix(server): pass the process runner to the systemd unit directory re…
juliusmarminge Nov 11, 2026
9ef259e
fix(mobile): sidebar empty states and repeated usage notices (#33188)
maria-rcks Nov 11, 2026
34b50df
ci: stop uploading per-shard test cache reports (#34525)
juliusmarminge Nov 11, 2026
11f61a5
refactor(mobile): lists use LegendList, FlatList is a restricted impo…
juliusmarminge Nov 11, 2026
836b86a
fix(chat): keep final replies visible after steering (#34501)
Yash-Singh1 Nov 11, 2026
a9cb6b3
chore(sync): merge 782 upstream commits, keeping the fork's features
pseudoseed Nov 11, 2026
6d491dc
chore(release): bump PseudoCode to 0.0.79
pseudoseed Nov 11, 2026
6c84258
fix(sync): fork features and tests follow upstream's merged changes
pseudoseed Nov 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
  •  
  •  
  •  
5 changes: 3 additions & 2 deletions .agents/skills/test-t3-mobile/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ vp run mobile:install <ios|android> <device-id>

This installs the dev client for the checkout's native fingerprint: from the
device, the local cache, or the shared cache in seconds, building once only
when no machine has that fingerprint yet (5-15 minutes, logged to the file it
names). The device id may be omitted when exactly one device is booted. It
when no machine has that fingerprint yet: in the `Mobile Dev Client` workflow
on Blacksmith when HEAD is pushed and `gh` may dispatch it (the command waits),
otherwise here (5-15 minutes, logged to the file it names). The device id may be omitted when exactly one device is booted. It
prints one JSON line; on failure it names the next command. Mobile verification
includes that step unless the user prohibits it.

Expand Down
2 changes: 1 addition & 1 deletion .github/SECURITY.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Security policy

Report security vulnerabilities affecting T3 Code or T3 Tools-operated infrastructure to
[security@ping.gg](mailto:security@ping.gg). Please do not disclose them publicly until we have had
[security@t3.codes](mailto:security@t3.codes). Please do not disclose them publicly until we have had
a reasonable opportunity to investigate and remediate them.

See the [full security policy](https://t3.codes/security-policy) for reporting details, scope,
Expand Down
2 changes: 2 additions & 0 deletions .github/actions/ci-changes/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ outputs:
value: ${{ steps.detect.outputs.typecheck }}
build:
value: ${{ steps.detect.outputs.build }}
desktop_launch:
value: ${{ steps.detect.outputs.desktop_launch }}
test:
value: ${{ steps.detect.outputs.test }}
test_packages:
Expand Down
12 changes: 10 additions & 2 deletions .github/actions/setup-ci-deps/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ inputs:
description: Arguments for `vp install`, such as filters. Empty installs the whole workspace.
required: false
default: ""
save-pnpm-store:
description: Set to "false" when a concurrent job with the same install args saves the pnpm store
required: false
default: "true"
runs:
using: composite
steps:
Expand Down Expand Up @@ -123,10 +127,14 @@ runs:
key: ${{ steps.pnpm_verified.outputs.cache-primary-key }}

# A filtered install that started from the current full store adds nothing
# worth a second copy of it.
# worth a second copy of it. A stacked PR, based on a branch other than the
# default, saves a ~1 GB store only its own reruns can read, so it only restores.
# Concurrent jobs with the same install args reserve one key, so the losers
# compress the store for nothing; all but one pass save-pnpm-store: false.
- name: Save pnpm store
if: >-
inputs.install == 'true' &&
inputs.install == 'true' && inputs.save-pnpm-store == 'true' &&
(github.event_name != 'pull_request' || github.base_ref == github.event.repository.default_branch) &&
steps.pnpm_cache.outputs.cache-hit != 'true' &&
(steps.pnpm_store.outputs.namespace == 'full' ||
steps.pnpm_cache.outputs.cache-matched-key != format('pnpm-full-v1-{0}-{1}-{2}', runner.os, runner.arch, hashFiles('pnpm-lock.yaml', 'pnpm-workspace.yaml', 'package.json')))
Expand Down
59 changes: 42 additions & 17 deletions .github/scripts/check-nightly-release.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -40,42 +40,67 @@ async function assertReleaseSource({ github, context, releaseChannel }) {

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

async function findLatestNightly({ github, context }) {
const releases = await github.paginate(github.rest.repos.listReleases, {
...context.repo,
per_page: 100,
});
return releases
.filter((release) => !release.draft && release.published_at && isNightlyTag(release.tag_name))
.sort((a, b) => Date.parse(b.published_at) - Date.parse(a.published_at))[0];
// Only the three fields the gate reads. The REST list also returns every asset,
// which made a full scan tens of megabytes.
const RELEASES_QUERY = `
query ($owner: String!, $repo: String!, $cursor: String) {
repository(owner: $owner, name: $repo) {
releases(first: 100, after: $cursor, orderBy: { field: CREATED_AT, direction: DESC }) {
pageInfo { hasNextPage endCursor }
nodes { tagName isDraft publishedAt }
}
}
}
`;

// Returns the nightly with the newest publishedAt. Release order follows the
// tagged commit date, not publication, so every page is read unless `isSettled`
// says the newest nightly seen so far already decides the caller's answer.
async function findLatestNightly({ github, context, isSettled = () => false }) {
let latest;
let cursor = null;
do {
const { repository } = await github.graphql(RELEASES_QUERY, { ...context.repo, cursor });
const { nodes, pageInfo } = repository.releases;
for (const release of nodes) {
if (release.isDraft || !release.publishedAt || !isNightlyTag(release.tagName)) continue;
if (!latest || Date.parse(release.publishedAt) > Date.parse(latest.publishedAt)) {
latest = release;
}
}
if (latest && isSettled(latest)) return latest;
cursor = pageInfo.hasNextPage ? pageInfo.endCursor : null;
} while (cursor);
return latest;
}

async function shouldReleaseNightly({ github, context, core, now = Date.now() }) {
const lastNightly = await findLatestNightly({ github, context });
const isInGap = (release) => now - Date.parse(release.publishedAt) < MINIMUM_RELEASE_GAP_MS;
// Any nightly inside the gap means the newest one is too, so stop reading.
const lastNightly = await findLatestNightly({ github, context, isSettled: isInGap });

if (!lastNightly) {
core.info("No published nightly found. Proceeding with release.");
return true;
}

if (now - Date.parse(lastNightly.published_at) < MINIMUM_RELEASE_GAP_MS) {
core.info(`Nightly ${lastNightly.tag_name} was published less than six hours ago. Skipping.`);
const tag = lastNightly.tagName;
if (isInGap(lastNightly)) {
core.info(`Nightly ${tag} was published less than six hours ago. Skipping.`);
return false;
}

const { data: comparison } = await github.rest.repos.compareCommitsWithBasehead({
...context.repo,
basehead: `${lastNightly.tag_name}...${context.sha}`,
basehead: `${tag}...${context.sha}`,
per_page: 1,
});
if (comparison.status !== "ahead") {
core.info(
`Candidate commit is ${comparison.status} relative to ${lastNightly.tag_name}. Skipping.`,
);
core.info(`Candidate commit is ${comparison.status} relative to ${tag}. Skipping.`);
return false;
}

core.info(`New commits since ${lastNightly.tag_name}, and the six-hour gap has passed.`);
core.info(`New commits since ${tag}, and the six-hour gap has passed.`);
return true;
}

Expand All @@ -85,7 +110,7 @@ async function resolveLatestNightlyCommit({ github, context, core }) {
throw new Error("No published nightly found. Stable releases build the latest nightly commit.");
}

const tag = lastNightly.tag_name;
const tag = lastNightly.tagName;
const { data: commit } = await github.rest.repos.getCommit({ ...context.repo, ref: tag });
const version = /^(?:nightly-)?v(\d+\.\d+\.\d+)-nightly\./.exec(tag)?.[1];
if (!version) {
Expand Down
102 changes: 84 additions & 18 deletions .github/scripts/check-nightly-release.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ const {
const now = Date.parse("2026-09-05T12:00:00Z");
const hour = 60 * 60 * 1000;
const nightly = (hoursAgo, overrides = {}) => ({
tag_name: "v1.0.1-nightly.20260905.123",
draft: false,
published_at: new Date(now - hoursAgo * hour).toISOString(),
tagName: "v1.0.1-nightly.20260905.123",
isDraft: false,
publishedAt: new Date(now - hoursAgo * hour).toISOString(),
...overrides,
});

Expand Down Expand Up @@ -73,26 +73,39 @@ for (const comparisonStatus of ["behind", "diverged"]) {
});
}

function fixture({ releases = [nightly(7)], comparisonStatus = "ahead" } = {}) {
// `pages` holds the GraphQL release pages; `releases` is shorthand for one page.
function fixture({ releases = [nightly(7)], pages = [releases], comparisonStatus = "ahead" } = {}) {
const calls = [];
const cursors = [];
return {
calls,
cursors,
options: {
now,
context: { repo: { owner: "example", repo: "app" }, sha: "new" },
core: { info() {} },
github: {
rest: {
repos: {
listReleases() {},
async compareCommitsWithBasehead(params) {
calls.push(params);
return { data: { status: comparisonStatus } };
},
},
},
async paginate() {
return releases;
async graphql(_query, { owner, repo, cursor }) {
assert.deepEqual({ owner, repo }, { owner: "example", repo: "app" });
cursors.push(cursor);
const index = cursor === null ? 0 : Number(cursor);
const hasNextPage = index + 1 < pages.length;
return {
repository: {
releases: {
nodes: pages[index],
pageInfo: { hasNextPage, endCursor: hasNextPage ? String(index + 1) : null },
},
},
};
},
},
},
Expand All @@ -101,28 +114,65 @@ function fixture({ releases = [nightly(7)], comparisonStatus = "ahead" } = {}) {

test("releases the first nightly when no nightly is published", async () => {
const { options } = fixture({
releases: [nightly(0, { tag_name: "v1.0.0" }), nightly(0, { draft: true })],
releases: [nightly(0, { tagName: "v1.0.0" }), nightly(0, { isDraft: true })],
});
assert.equal(await shouldReleaseNightly(options), true);
});

test("uses publication time, not release order or the tagged commit date", async () => {
const { options } = fixture({
releases: [nightly(10), nightly(1), nightly(20, { tag_name: "nightly-v0.9.0" })],
releases: [nightly(10), nightly(1), nightly(20, { tagName: "nightly-v0.9.0" })],
});
assert.equal(await shouldReleaseNightly(options), false);
});

test("the six-hour gap ends exactly six hours after publication", async () => {
const atBoundary = fixture({ releases: [nightly(6)] });
assert.equal(await shouldReleaseNightly(atBoundary.options), true);
const justInside = fixture({ releases: [nightly(6 - 1 / 3_600_000)] });
assert.equal(await shouldReleaseNightly(justInside.options), false);
assert.equal(justInside.calls.length, 0);
});

test("stops reading releases once a nightly inside the gap is seen", async () => {
const { options, cursors } = fixture({ pages: [[nightly(10), nightly(2)], [nightly(30)]] });
assert.equal(await shouldReleaseNightly(options), false);
assert.deepEqual(cursors, [null]);
});

test("reads every page when no nightly seen so far settles the gap", async () => {
const { options, cursors, calls } = fixture({
pages: [
[nightly(10), nightly(0, { tagName: "v1.0.0" })],
[nightly(1, { tagName: "nightly-v0.9.0" })],
],
});
assert.equal(await shouldReleaseNightly(options), false);
assert.deepEqual(cursors, [null, "1"]);
assert.equal(calls.length, 0);
});

test("compares against the newest nightly across pages once the gap has passed", async () => {
const { options, calls } = fixture({
pages: [[nightly(10, { tagName: "v1.0.1-nightly.20260905.100" })], [nightly(8)]],
});
assert.equal(await shouldReleaseNightly(options), true);
assert.deepEqual(
calls.map((call) => call.basehead),
["v1.0.1-nightly.20260905.123...new"],
);
});

test("ignores stable releases and drafts when checking the gap", async () => {
const { options } = fixture({
releases: [nightly(0, { tag_name: "v1.0.0" }), nightly(0, { draft: true }), nightly(7)],
releases: [nightly(0, { tagName: "v1.0.0" }), nightly(0, { isDraft: true }), nightly(7)],
});
assert.equal(await shouldReleaseNightly(options), true);
});

test("fails instead of releasing when GitHub cannot supply release state", async () => {
const { options } = fixture();
options.github.paginate = async () => {
options.github.graphql = async () => {
throw new Error("GitHub unavailable");
};
await assert.rejects(shouldReleaseNightly(options), /GitHub unavailable/);
Expand All @@ -137,9 +187,9 @@ for (const status of ["behind", "diverged"]) {

const { resolveLatestNightlyCommit } = require("./check-nightly-release.cjs");

function nightlyCommitFixture({ releases, commitSha = "abc123" }) {
function nightlyCommitFixture({ releases, pages, commitSha = "abc123" }) {
const refs = [];
const { options } = fixture({ releases });
const { options } = fixture({ releases, pages });
options.github.rest.repos.getCommit = async ({ ref }) => {
refs.push(ref);
return { data: { sha: commitSha } };
Expand All @@ -150,10 +200,10 @@ function nightlyCommitFixture({ releases, commitSha = "abc123" }) {
test("stable releases resolve the commit of the newest published nightly", async () => {
const { options, refs } = nightlyCommitFixture({
releases: [
nightly(10, { tag_name: "v1.0.1-nightly.20260905.100" }),
nightly(1, { tag_name: "v1.0.1-nightly.20260905.123" }),
nightly(0, { tag_name: "v1.0.0" }),
nightly(0, { draft: true, tag_name: "v1.0.1-nightly.20260905.999" }),
nightly(10, { tagName: "v1.0.1-nightly.20260905.100" }),
nightly(1, { tagName: "v1.0.1-nightly.20260905.123" }),
nightly(0, { tagName: "v1.0.0" }),
nightly(0, { isDraft: true, tagName: "v1.0.1-nightly.20260905.999" }),
],
commitSha: "deadbeef",
});
Expand All @@ -167,7 +217,23 @@ test("stable releases resolve the commit of the newest published nightly", async

test("stable releases derive the version from legacy nightly tags", async () => {
const { options } = nightlyCommitFixture({
releases: [nightly(1, { tag_name: "nightly-v0.9.0-nightly.20260905.5" })],
releases: [nightly(1, { tagName: "nightly-v0.9.0-nightly.20260905.5" })],
});
assert.equal((await resolveLatestNightlyCommit(options)).version, "0.9.0");
});

test("stable releases read every page, even after a recent nightly", async () => {
const { options, refs } = nightlyCommitFixture({
pages: [
[nightly(2, { tagName: "v1.0.1-nightly.20260905.100" })],
[nightly(1, { tagName: "v1.0.1-nightly.20260905.123" })],
],
});
assert.equal((await resolveLatestNightlyCommit(options)).tag, "v1.0.1-nightly.20260905.123");
assert.deepEqual(refs, ["v1.0.1-nightly.20260905.123"]);
});

test("stable releases fail when no nightly is published", async () => {
const { options } = nightlyCommitFixture({ releases: [nightly(1, { tagName: "v1.0.0" })] });
await assert.rejects(resolveLatestNightlyCommit(options), /No published nightly found/);
});
23 changes: 22 additions & 1 deletion .github/scripts/ci-changes.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,21 @@ const BUILD_ONLY_DEPS = { t3: ["@t3tools/web"] };
const MOBILE_NATIVE =
/^apps\/mobile\/.*\.(swift|kt|kts)$|^apps\/mobile\/(\.swiftlint\.yml|detekt\.yml|\.editorconfig|Brewfile)$|^scripts\/mobile-native-static-check\.ts$|^package\.json$|^\.github\/workflows\/ci\.yml$|^\.github\/scripts\/ci-changes\.cjs$|^\.github\/actions\/ci-changes\//;

// Startup, migration, settlement, and sidebar paths that decide whether an upgraded user's
// threads show after launch. Build runs scripts/smoke-desktop-app.ts for them, so they do not
// first fail in the release launch check.
const DESKTOP_LAUNCH = [
/^apps\/desktop\/src\/((main|boot|compileCache|serverCompileCache)\.ts$|(app|backend|window)\/)/,
/^apps\/desktop\/src\/electron\/(ElectronApp|ElectronProtocol|ElectronWindow)\.ts$/,
/^apps\/web\/src\/((main|AppRoot|appInit)\.tsx|(bootstrap|router)\.ts)$/,
/^apps\/web\/src\/.*sidebar/i,
/^apps\/server\/src\/(bin|binMain|server|serverRuntimeStartup)\.ts$/,
/^apps\/server\/src\/persistence\/Migrations/,
/^apps\/server\/src\/orchestration-v2\/((ThreadSettlementService|ProjectionStore)\.ts$|legacy\/)/,
/^packages\/contracts\/src\/settings\.ts$/,
/^scripts\/(smoke-desktop-app\.ts|fixtures\/desktop-launch\/)/,
];

const OWN_TEST_JOB = new Set(["t3", "@t3tools/web", "@t3tools/monorepo"]);

function readWorkspace() {
Expand Down Expand Up @@ -151,12 +166,18 @@ function decide(files, packages, full) {
(pkg) => pkg.hasTest && !OWN_TEST_JOB.has(pkg.name) && affected.has(pkg.name),
);
const has = (name) => affected.has(name);
const desktopLaunch =
everything ||
files.some(
(file) => !/\.test\.tsx?$/.test(file) && DESKTOP_LAUNCH.some((pattern) => pattern.test(file)),
);

return {
affected: [...affected].sort(),
outputs: {
typecheck: affected.size > 0,
build: has("@t3tools/desktop") || has("t3") || has("@t3tools/web"),
build: has("@t3tools/desktop") || has("t3") || has("@t3tools/web") || desktopLaunch,
desktop_launch: desktopLaunch,
test: tested.length > 0,
// Empty means every package the Test job covers.
test_packages: everything ? "" : tested.map((pkg) => pkg.name).join(" "),
Expand Down
1 change: 1 addition & 0 deletions .github/scripts/ci-changes.d.cts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export function decide(
outputs: {
typecheck: boolean;
build: boolean;
desktop_launch: boolean;
test: boolean;
test_packages: string;
test_web: boolean;
Expand Down
Loading
Loading