Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
384 commits
Select commit Hold shift + click to select a range
7b307eb
fix(web): background surfaces retain valid workspace focus
maria-rcks Nov 9, 2026
1ee4af0
fix(web): closing background subagents preserves the active tab
maria-rcks Nov 9, 2026
133a3c9
fix(web): stale tab replacements preserve open threads
maria-rcks Nov 9, 2026
c0f5f55
fix(web): written answers cancel question auto-advance
maria-rcks Nov 9, 2026
b3bf605
fix(web): show enabled ultracode on the reasoning chip
maria-rcks Nov 9, 2026
e94eb30
fix(web): pending answers ignore the parked prompt length
maria-rcks Nov 9, 2026
de1b8c1
perf(web): tick thread mention ages inside their menu rows
maria-rcks Nov 9, 2026
41c28f5
fix(web): keep theme import drafts when adding files
maria-rcks Nov 9, 2026
98fd346
refactor(web): use settings primitives for text generators
maria-rcks Nov 9, 2026
383804e
fix(web): retain relay install cancellation before subscription
maria-rcks Nov 9, 2026
5ad73c5
fix(web): disable pulls when the branch has diverged
maria-rcks Nov 9, 2026
fc064e8
fix(web): keep markdown source as the default file view
maria-rcks Nov 9, 2026
1f1b236
fix(web): restore adding review conversations to chat
maria-rcks Nov 9, 2026
ecc75e5
fix(web): restore oldest-first pull request activity
maria-rcks Nov 9, 2026
cac4b0c
refactor(web): share diff header line counts
maria-rcks Nov 9, 2026
7461c02
feat(web): an open wake-ups fold hangs its rows off a rail
maria-rcks Nov 9, 2026
f5fb077
fix(server): keep claude context categories during turns
maria-rcks Nov 9, 2026
015af50
feat(web): add T3 Code Classic theme
maria-rcks Nov 9, 2026
8afcfff
feat(web): subagent rows are one quiet line with the provider's logo
maria-rcks Nov 9, 2026
eab7349
feat(web): subagents sit in the turn as bare rows, without a group card
maria-rcks Nov 9, 2026
e13c156
fix(web): classic theme separates the chrome from the pane and fills …
maria-rcks Nov 9, 2026
cf6e1c5
refactor(web): the subagent elapsed helper is private to its row
maria-rcks Nov 9, 2026
964c9aa
perf(web): build palette thread items only when needed
maria-rcks Nov 10, 2026
81dd25f
fix(web): flat surfaces use solid fills without depth
maria-rcks Nov 9, 2026
e1120c6
fix(web): the background setup chip sits at the right of the working row
maria-rcks Nov 10, 2026
af0739e
fix(web): flat keeps main's hairline on cards, menus and tables
maria-rcks Nov 10, 2026
a2a2a2e
fix(web): remote lineage rows use the same two lines as local ones
maria-rcks Nov 10, 2026
cbe12cf
fix(web): classic chrome matches the sidebar, and flat tables and sel…
maria-rcks Nov 10, 2026
cf0168b
fix: remote lineage rows show the machine icon, model and effort like…
maria-rcks Nov 10, 2026
0d1364e
fix(web): subagent rows keep the tool rows' height and spacing
maria-rcks Nov 10, 2026
161bd9a
fix(web): remote lineage rows carry the machine on the logo and show …
maria-rcks Nov 10, 2026
a6dc427
fix(web): surface recipes reach floating and checked controls
maria-rcks Nov 10, 2026
4bb11c4
fix(web): soft gradient fields and tints share borderless recipes
maria-rcks Nov 10, 2026
b04b686
fix(web): aqua gloss reaches tinted controls and thumbs
maria-rcks Nov 10, 2026
2f59247
fix(web): aqua blue keeps white labels readable across controls
maria-rcks Nov 10, 2026
9fe9a62
fix(web): gradient rims paint once on cards and checked controls
maria-rcks Nov 10, 2026
cd8287b
fix(web): toast dismiss buttons follow the surface recipe
maria-rcks Nov 10, 2026
1631b6a
fix(web): light style warning labels meet contrast requirements
maria-rcks Nov 10, 2026
d24a29f
fix(web): destructive keycaps keep readable labels in every style
maria-rcks Nov 10, 2026
c29a785
fix(web): named light palettes retain action label contrast
maria-rcks Nov 10, 2026
8b4c928
fix(web): preserve default checked control paint
maria-rcks Nov 10, 2026
e7e88d2
fix(web): tool calls opened inside a wake-ups fold sit on its rail too
maria-rcks Nov 10, 2026
40d0015
fix(web): classic keeps the chosen style's rims and gradients
maria-rcks Nov 10, 2026
f0de28f
fix(web): pane headers mask scrolling chat content
maria-rcks Nov 10, 2026
76c3901
fix(web): palette action labels keep their width
maria-rcks Nov 10, 2026
eb5ef1e
fix(web): sidebar hover controls keep a stable slot
maria-rcks Nov 10, 2026
23e42fa
fix(web): settings section headings use foreground text
maria-rcks Nov 10, 2026
4e07af5
fix(web): browser link target shows its full value
maria-rcks Nov 10, 2026
4be05d5
fix(web): archive uses the shared centered empty state
maria-rcks Nov 10, 2026
af3bc42
fix(web): unchecked choices keep a visible resting edge
maria-rcks Nov 10, 2026
9d36068
fix(web): sidebar toggle inherits its header control color
maria-rcks Nov 10, 2026
b5f23ad
fix(web): split composers share the compact label cutoff
maria-rcks Nov 10, 2026
76e4337
fix(web): the PR list's "more" line lines up with the PRs above it (#…
flamboh Nov 10, 2026
7108330
fix(web): column resize no longer shows snap ticks it never snaps to …
flamboh Nov 10, 2026
958220c
fix(web): the workspace pill names and places the workspace you land on
flamboh Nov 10, 2026
1f8dd4a
fix(web): a pane's + menu opens new tabs in that pane (#31425)
flamboh Nov 10, 2026
3334429
fix(web): the sidebar stays in front while the overview zooms
flamboh Nov 10, 2026
6f6b91a
fix(web): closing a tab beside another no longer grays the gap betwee…
flamboh Nov 10, 2026
3063b3d
fix(web): a streaming chat at the end stays at the end in the frame i…
flamboh Nov 10, 2026
7f1e2c3
fix(web): show keyboard focus on composer pill actions (#31547)
flamboh Nov 10, 2026
2d3a4d1
fix(web): one click works anywhere in a pane that isn't focused (#31397)
flamboh Nov 10, 2026
8be1cb1
fix(web): holding the workspace key glides through workspaces without…
flamboh Nov 10, 2026
6fd1a42
fix(web): the overview fades out the sidebar toggle and ignores Cmd+B
flamboh Nov 10, 2026
7850c69
fix(web): switching tabs keeps a chat's scroll position (#31433)
flamboh Nov 10, 2026
c7c2141
fix(web): queued messages leave pending approvals untouched (#31535)
flamboh Nov 10, 2026
36b1cb5
fix(web): the top-left tab no longer jumps when the overview zooms in
flamboh Nov 10, 2026
7bc3879
fix(web): steered turns keep the cut-off attempt and one timer (#31516)
flamboh Nov 10, 2026
8fff6ca
fix(web): keep settings navigation and dismissal consistent (#31573)
flamboh Nov 10, 2026
dbb9b08
fix(web): shrinking a column while scrolled right no longer runs away…
flamboh Nov 10, 2026
bfec165
fix(web): panes moving aside for a new left column slide under it (#3…
flamboh Nov 10, 2026
827a30f
fix(web): the Tasks tray no longer flashes the last turn's plan on se…
flamboh Nov 10, 2026
0076d95
fix(web): moving a tab above the top workspace opens a new workspace
flamboh Nov 10, 2026
581a0da
fix(web): keep composer steady when holding a modifier (#31524)
flamboh Nov 10, 2026
32b402c
fix(web): position opened threads and sent messages before paint (#31…
flamboh Nov 10, 2026
5e3de77
fix(web): keep mention results visible during searches (#31529)
flamboh Nov 10, 2026
06c70ac
fix(web): pane chrome behaves the same however you open it (#31462)
flamboh Nov 10, 2026
eee0cca
fix(web): the workspace pill lands with its pane and shows after the …
flamboh Nov 10, 2026
b8c0e0f
fix(web): apply sidebar design tokens consistently (#31563)
flamboh Nov 10, 2026
e8795ed
fix(web): pane slides no longer crash below 100% zoom
flamboh Nov 10, 2026
6dcedd6
fix(web): dropped panes land where you drop them (#31469)
flamboh Nov 10, 2026
40ed21f
fix(web): sidebar rows no longer slide through each other (#31569)
flamboh Nov 10, 2026
9050345
fix(web): image removal says Remove, one Escape closes file preview (…
flamboh Nov 10, 2026
f9e8327
fix(web): a closed wake-ups fold keeps a turn gap above the next prompt
maria-rcks Nov 10, 2026
32f0b2f
feat(web): mod+l toggles the thread's linked pull requests
maria-rcks Nov 10, 2026
6f70de6
fix(web): leaving a terminal for an empty workspace no longer jumps b…
flamboh Nov 10, 2026
37c0aec
fix(web): a background open no longer closes your empty workspace
flamboh Nov 10, 2026
327cb7e
fix(web): keep stacked toasts inside their surfaces (#31576)
flamboh Nov 10, 2026
ba437f9
fix(web): make composer popups readable and consistently spaced (#31552)
flamboh Nov 10, 2026
4df3281
fix(web): the command palette scrolls instead of the overview behind it
flamboh Nov 10, 2026
c900539
fix(web): sending a workspace's only pane away no longer flashes the …
flamboh Nov 10, 2026
6f0398e
fix(web): add consistent settings controls and utility tooltips (#31581)
flamboh Nov 10, 2026
6a04581
feat(web): switch house colors from one theme card
maria-rcks Nov 10, 2026
04bbf19
fix(web): chats scrolled off screen no longer mark finished work as read
flamboh Nov 10, 2026
fc29e38
fix(web): use consistent timeline fold disclosures (#31558)
flamboh Nov 10, 2026
bfba29e
fix(web): only the focused pane's thread reads as current in the side…
flamboh Nov 10, 2026
4b6e285
fix(web): sidebar keeps the open thread in view when a new thread sen…
flamboh Nov 10, 2026
deb3098
fix(web): the overview shows readable panes live with the sidebar open
flamboh Nov 10, 2026
cd5b170
fix(web): keep the open branch chip highlighted and readable (#31550)
flamboh Nov 10, 2026
246a9df
fix(web): make settings rows and dialogs consistent (#31583)
flamboh Nov 10, 2026
ce64825
fix(web): stop restored focus reopening tooltips and keep nested dial…
flamboh Nov 10, 2026
c5ef5b9
fix(web): align Voice setting fields with standard row controls (#31588)
flamboh Nov 10, 2026
bc3f5ac
fix(web): preserve settings breadcrumb labels and align layout action…
flamboh Nov 10, 2026
f4ba233
fix(web): clarify file approvals and superseded attempt rows (#31624)
flamboh Nov 10, 2026
0d5cdd0
fix(web): right-clicking an inactive pane tab opens that tab's own me…
flamboh Nov 10, 2026
f20e89e
fix(web): keep Working visible while a sent turn starts (#31625)
flamboh Nov 10, 2026
92a6b7f
fix(web): keep settings breadcrumb aligned with loaded content (#31600)
flamboh Nov 10, 2026
273492d
perf(web): the sidebar slides instead of resizing the panes every fra…
flamboh Nov 10, 2026
fa83091
fix(web): side-by-side drops land beside the pane you drop on (#31836)
flamboh Nov 10, 2026
100651f
fix(web): classic theme's pane header strip matches the lifted pane
maria-rcks Nov 10, 2026
7f9ce6e
fix(web): a stack cannot be merged through a pull request that confli…
maria-rcks Nov 10, 2026
e1ac536
fix(web): let surface styles paint the composer pill
maria-rcks Nov 10, 2026
a2eef23
fix(web): carry control surfaces into cards and overlays
maria-rcks Nov 10, 2026
bb325a2
fix(web): keep soft gradient surfaces smooth and edge free
maria-rcks Nov 10, 2026
d89f424
fix(web): retain aqua gloss across controls and larger surfaces
maria-rcks Nov 10, 2026
2df6968
fix(web): keep aqua blue jelly visible with readable labels
maria-rcks Nov 10, 2026
7134521
fix(web): carry fading rims onto every raised surface
maria-rcks Nov 10, 2026
8615c83
fix(web): align flat control fills with the style card
maria-rcks Nov 10, 2026
c730b9a
fix(web): preserve surface styles through theme overrides and pane tabs
maria-rcks Nov 10, 2026
f80e26a
fix(web): keep styled action labels at aa contrast
maria-rcks Nov 10, 2026
a1e7308
fix(web): keep styled labels readable in named palettes
maria-rcks Nov 10, 2026
8a25711
fix(web): swap sidebar status and hover actions together (#31596)
flamboh Nov 10, 2026
795f256
fix(web): suppress sidebar hover cards while scrolling (#31603)
flamboh Nov 10, 2026
0ee76a6
fix(web): pull request header stays on one line in narrow panels (#33…
flamboh Nov 10, 2026
6cbd2b7
fix(web): the layout introduction and tour work from the keyboard
flamboh Nov 10, 2026
397ee60
fix(web): provider updates no longer pop toasts on launch in the rede…
flamboh Nov 10, 2026
846843d
fix(server): simplify the Connect completion page (#32168)
flamboh Nov 10, 2026
6463310
fix(web): match MCP setup to the redesign (#32166)
flamboh Nov 10, 2026
6a76b35
test(web): sidebar terminal-focus test no longer races environment st…
flamboh Nov 10, 2026
239a1b5
refactor(server): archive message counts come from the projection sto…
flamboh Nov 10, 2026
23a57ea
fix(web): aqua styles leave tabs, the sidebar search and the composer…
maria-rcks Nov 10, 2026
f612045
fix(web): keep rapid thread jumps ahead of chat rendering
maria-rcks Nov 9, 2026
ab22829
fix(web): keep the first typed key after a promoted draft switch
maria-rcks Nov 10, 2026
3e7f345
fix(client-runtime): preserve idle history identity on warm returns
maria-rcks Nov 10, 2026
60b55f7
fix(web): render isolated thread switches without deferral
maria-rcks Nov 10, 2026
761d189
fix(web): isolate timelines during deferred thread switches
maria-rcks Nov 10, 2026
932a679
revert(web): nightly chrome keeps its sunrise artwork
maria-rcks Nov 10, 2026
179553d
fix(web): chat content scrolls under the pane header again
maria-rcks Nov 10, 2026
59392b0
fix(web): restore the settle word on sidebar rows
maria-rcks Nov 10, 2026
9696cbd
fix(web): balance lineage row spacing and icon alignment
maria-rcks Nov 10, 2026
91b5e25
revert(web): lineage rows keep their height and gaps
maria-rcks Nov 10, 2026
6ae86b6
fix(web): round and join composer banner surfaces
maria-rcks Nov 10, 2026
30693fe
fix(web): work row icons match the row text and subagent rows keep th…
maria-rcks Nov 10, 2026
b3f9ef7
fix(web): give sidebar header buttons their selected surface style
maria-rcks Nov 10, 2026
cce7e65
fix(web): keep aqua containers quieter than their controls
maria-rcks Nov 10, 2026
9e1a1c3
fix(web): keep aqua context surfaces calm and readable
maria-rcks Nov 10, 2026
4d8750d
fix(web): make flat segmented selections visible
maria-rcks Nov 10, 2026
ec62eee
fix(web): give lineage lists space at their outer edges
maria-rcks Nov 10, 2026
9760377
fix(web): simplify side chat headers
maria-rcks Nov 10, 2026
575e0bf
feat(web): nightly's dark chrome paints the orbital sunrise in color
maria-rcks Nov 10, 2026
8361f2b
fix(web): nightly's sunrise sits in the app's chrome with the horizon…
maria-rcks Nov 10, 2026
901be9b
fix(web): retain main integrations in the workspace panes
maria-rcks Nov 11, 2026
14a896b
fix(web): keep phone headers and drawers on app chrome
maria-rcks Nov 11, 2026
d88cc8f
fix(web): keep phone composer text clear of controls
maria-rcks Nov 11, 2026
de5d7f1
fix(web): give subagent titles more room on phones
maria-rcks Nov 11, 2026
c700cfc
fix(web): show more queued message text on phones
maria-rcks Nov 11, 2026
75c548c
fix(web): keep pull request titles readable on phones
maria-rcks Nov 11, 2026
87426fb
fix(web): wrap project dialog keyboard hints on phones
maria-rcks Nov 11, 2026
41c1ee1
fix(web): keep pull request controls clear in narrow panels
maria-rcks Nov 11, 2026
9c5f33f
fix(web): keep phone settings labels and controls readable
maria-rcks Nov 11, 2026
2b0b9bb
fix(web): keep thread details menus inside phone screens
maria-rcks Nov 11, 2026
6bc049c
fix(web): keep phone surface tabs and close controls visible
maria-rcks Nov 11, 2026
3f48dba
fix(mobile): use darker chrome around native content sheets
maria-rcks Nov 11, 2026
274ea1f
fix(web): keep tab flicks from navigating workspace history
maria-rcks Nov 11, 2026
5da2ff9
test(web): give the turn announcement fixture an attempt start time
maria-rcks Nov 11, 2026
3c1a9db
fix(web): retain main behavior across workspace controls
maria-rcks Nov 11, 2026
bdfb6f7
fix(web): carry environment editor selection into workspace surfaces
maria-rcks Nov 11, 2026
011b7f3
feat(web): rename surface styles and describe each one in the picker
maria-rcks Nov 10, 2026
21875a4
fix(web): accent gloss keeps the theme accent's hue
maria-rcks Nov 10, 2026
01092fc
fix(web): style cards show their name only
maria-rcks Nov 11, 2026
e927a76
fix(web): restore raised dropdowns in the default surface style
maria-rcks Nov 11, 2026
9860dfa
fix(web): keep thread details from scrolling sideways
maria-rcks Nov 11, 2026
ef05d1c
fix(web): keep image reads in the work log
maria-rcks Nov 11, 2026
84223e9
fix(web): retain the settings size for retention ages
maria-rcks Nov 11, 2026
59743c8
fix(web): preserve primary focus when capturing confirmation openers
maria-rcks Nov 11, 2026
9fa1460
fix(web): keep the automations card from scrolling sideways
maria-rcks Nov 11, 2026
749d725
fix(web): match compact toggle to the flat send pill
maria-rcks Nov 11, 2026
08b562a
fix(web): lineage rows sit tight again
maria-rcks Nov 11, 2026
47c5dcb
fix(web): previous agents expand in place in the Lineage card
maria-rcks Nov 11, 2026
cd4a3fd
fix(web): keep details card headers still when toggled
maria-rcks Nov 11, 2026
020b8c2
fix(web): highlight automation rows and open editing directly
maria-rcks Nov 11, 2026
f9d90ff
fix(web): make sidebar updates match ghost footer controls
maria-rcks Nov 11, 2026
76cb74f
fix(web): a dismissed low usage notice stays dismissed
maria-rcks Nov 11, 2026
a85b3f8
fix(web): details card headers share one height with a centered title
maria-rcks Nov 11, 2026
3185206
fix(web): the details panel scrolls with the pointer over the lineage…
maria-rcks Nov 11, 2026
3b79c2a
fix(web): agent hover cards keep the model and effort on one line
maria-rcks Nov 11, 2026
409d60d
fix(web): use pooled model limits for low usage warnings
maria-rcks Nov 11, 2026
31855ff
fix(web): compact context says why it is unavailable and the context …
maria-rcks Nov 11, 2026
c2ae085
fix(web): offer side chat from the surface menus
maria-rcks Nov 11, 2026
5b88450
fix(web): a queued message still saving can be removed
maria-rcks Nov 11, 2026
3da0676
fix(web): the low usage notice's x dismisses it until its window resets
maria-rcks Nov 11, 2026
e1f1445
fix(web): the stopped square joins the send pill instead of adding a …
maria-rcks Nov 11, 2026
2f2abc6
fix(web): keep timeline row heights stable during zoom
maria-rcks Nov 11, 2026
44c107b
fix(web): environment settings show this machine's overview again
maria-rcks Nov 11, 2026
1426ea9
fix(web): pull request readiness rows line up their details with the …
maria-rcks Nov 11, 2026
0ceb730
fix(web): separate dictation finish and cancel controls
maria-rcks Nov 11, 2026
b3e819a
fix(web): restore main's palette groups and recent results
maria-rcks Nov 11, 2026
748dd6b
test(web): drop main's case for the viewed-images row the work log re…
maria-rcks Nov 11, 2026
06e847e
perf(web): switching threads no longer re-renders every open tab's chat
maria-rcks Nov 11, 2026
b049930
perf(web): leaving a thread no longer forces a style recalc per message
maria-rcks Nov 11, 2026
ed83d9a
perf(web): the composer no longer forces a style recalc when its edit…
maria-rcks Nov 11, 2026
7e902f2
fix(web): label the pull request host filter all forges
maria-rcks Nov 11, 2026
6e52fa9
fix(web): keep selected changes visible in thread details
maria-rcks Nov 11, 2026
5cd035c
fix(web): hidden tabs preserve the visible pane corners
maria-rcks Nov 11, 2026
18c64ca
test(server): give main's new Claude query fakes the context-usage stub
maria-rcks Nov 11, 2026
dd42d40
fix(web): keep pull request rows stable after eager sorting
maria-rcks Nov 11, 2026
f89895d
fix(web): fit more stack rows in the pull request popover
maria-rcks Nov 11, 2026
a1514a7
fix(web): keep git action menus compact
maria-rcks Nov 11, 2026
114de65
fix: group pull request project filters across machines
maria-rcks Nov 11, 2026
bdb1ea3
refactor(web): remove the unused composer footer animation
maria-rcks Nov 12, 2026
501051f
refactor(web): remove unused composer control modes
maria-rcks Nov 12, 2026
f1e65f2
refactor(web): remove unused css tokens and duplicate padding utility
maria-rcks Nov 12, 2026
efdb68b
refactor(web): remove the ignored select indicator prop
maria-rcks Nov 12, 2026
8a1c74c
refactor(web): remove duplicate launcher shortcut metadata
maria-rcks Nov 12, 2026
3c69a2b
fix(web): join compact to the composer action pill
maria-rcks Nov 12, 2026
93c78d3
test(web): remove composer tests that restate the markup
maria-rcks Nov 12, 2026
53a702c
test(web): remove redundant timeline tests
maria-rcks Nov 12, 2026
adfd74d
test: remove settings tests that mirror the schema
maria-rcks Nov 12, 2026
b2128b3
test(web): remove duplicate pull request filtering and paging tests
maria-rcks Nov 12, 2026
fcd0524
test(web): remove device mock mirrors and duplicate provider warning …
maria-rcks Nov 12, 2026
3d67f08
fix(web): blend markdown tables into message bubbles
maria-rcks Nov 12, 2026
147c58e
revert(web): restore the previous table look in message bubbles
maria-rcks Nov 12, 2026
627dbcc
fix(client-runtime): label saved pi and acp reasoning effort
maria-rcks Nov 12, 2026
0edd9f5
fix(web): resolve lineage model aliases before showing effort
maria-rcks Nov 12, 2026
65ce3a7
fix(web): match citation comments to main and keep dictation in place
maria-rcks Nov 12, 2026
db7d350
fix(web): citation comment mic sits before the buttons with no gap
maria-rcks Nov 12, 2026
533534a
fix(web): keep started thread branch controls in details
maria-rcks Nov 12, 2026
f8e33f2
fix(web): keep markdown tables on the user bubble surface
maria-rcks Nov 12, 2026
fc2694e
revert(web): restore the boxed table styling in message bubbles
maria-rcks Nov 12, 2026
8ea53c5
fix(web): show hover on composer and work disclosures
maria-rcks Nov 12, 2026
138b3f8
chore(web): remove redundant details press overrides
maria-rcks Nov 12, 2026
bd189f0
fix(web): keep phone chrome on theme colors
maria-rcks Nov 12, 2026
b270949
fix(web): keep locked workspace details passive
maria-rcks Nov 12, 2026
04d3cef
fix(web): align stash with the composer tray chips
maria-rcks Nov 12, 2026
e15b3a1
feat(web): show model switches beneath their messages
maria-rcks Nov 12, 2026
80ce6f8
fix(web): match message table colors to their bubbles
maria-rcks Nov 12, 2026
0bb510e
fix(mobile): keep ios content below the native header
maria-rcks Nov 12, 2026
bf60d4c
fix(mobile): show themed chrome around ios content sheets
maria-rcks Nov 12, 2026
555c6ea
fix(web): keep timeline row spacing current when neighbors change
maria-rcks Nov 12, 2026
819015d
fix(web): show keyboard focus on reachable controls
maria-rcks Nov 12, 2026
40c1b46
fix(web): match hover states on verified rows
maria-rcks Nov 12, 2026
b64c38f
fix(web): give main's language select the settings row controls
maria-rcks Nov 12, 2026
50e98bf
style(web): format the translated settings rows
maria-rcks Nov 12, 2026
9643a97
fix(web): read the worktree-pending check from shared where main move…
maria-rcks Nov 12, 2026
09d6d6a
test(web): drop the removed shortcut context from main's right panel …
maria-rcks Nov 12, 2026
2f8a8ca
test(server): give main's new Claude fakes the context-usage stub
maria-rcks Nov 12, 2026
fa44fc1
fix(web): match queued automation rows to queued messages
maria-rcks Nov 12, 2026
4dda2b8
fix(web): open pull request details without an update loop
maria-rcks Nov 12, 2026
3cce2a1
chore(web): temporary dev-only recorder for blank timeline gaps
maria-rcks Nov 12, 2026
ff331a3
fix(web): the copy link shortcut copies a focused pull request's link
maria-rcks Nov 12, 2026
eadb5f6
fix(mobile): give ios list filters room below the sheet edge and line…
maria-rcks Nov 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
  •  
  •  
  •  
5 changes: 5 additions & 0 deletions apps/desktop/src/electron/ElectronMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ function normalizeContextMenuItems(source: readonly ContextMenuItem[]): ContextM
disabled: sourceItem.disabled === true,
...(sourceItem.separatorBefore === true ? { separatorBefore: true } : {}),
...(typeof sourceItem.checked === "boolean" ? { checked: sourceItem.checked } : {}),
...(typeof sourceItem.accelerator === "string"
? { accelerator: sourceItem.accelerator }
: {}),
};

if (sourceItem.children) {
Expand Down Expand Up @@ -170,6 +173,8 @@ export const make = Effect.gen(function* () {
label: item.label,
enabled: !item.disabled,
...(typeof item.checked === "boolean" ? { type: "checkbox", checked: item.checked } : {}),
// Shown beside the label for learning; the app's own handler runs the key.
...(item.accelerator ? { accelerator: item.accelerator, registerAccelerator: false } : {}),
};
if (item.children && item.children.length > 0) {
itemOption.submenu = buildTemplate(item.children, complete);
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/ipc/channels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ export const PREVIEW_RECORDING_STOP_CHANNEL = "desktop:preview-recording-stop";
export const PREVIEW_RECORDING_SAVE_CHANNEL = "desktop:preview-recording-save";
export const PREVIEW_STATE_CHANGE_CHANNEL = "desktop:preview-state-change";
export const PREVIEW_POINTER_EVENT_CHANNEL = "desktop:preview-pointer-event";
export const PREVIEW_SET_FORWARDED_KEY_CHORDS_CHANNEL = "desktop:preview-set-forwarded-key-chords";
export const PREVIEW_FORWARDED_KEY_CHORD_CHANNEL = "desktop:preview-forwarded-key-chord";
export const PREVIEW_OPEN_LINK_CHANNEL = "desktop:preview-open-link";
export const PREVIEW_FIND_RESULT_CHANNEL = "desktop:preview-find-result";

Expand Down
12 changes: 12 additions & 0 deletions apps/desktop/src/ipc/methods/preview.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
DesktopPreviewAnnotationSendEnabledInputSchema,
DesktopPreviewAnnotationThemeInputSchema,
DesktopPreviewForwardedShortcutsInputSchema,
DesktopPreviewAnnotationVoiceStateSchema,
DesktopPreviewPickElementInputSchema,
DesktopPreviewArtifactInputSchema,
Expand Down Expand Up @@ -387,6 +388,16 @@ const setAnnotationTheme = DesktopIpc.makeIpcMethod({
}),
});

const setForwardedKeyChords = DesktopIpc.makeIpcMethod({
channel: IpcChannels.PREVIEW_SET_FORWARDED_KEY_CHORDS_CHANNEL,
payload: DesktopPreviewForwardedShortcutsInputSchema,
result: Schema.Void,
handler: Effect.fn("desktop.ipc.preview.setForwardedKeyChords")(function* ({ shortcuts }) {
const manager = yield* PreviewManager.PreviewManager;
yield* manager.setForwardedKeyChords(shortcuts);
}),
});

const pickElement = DesktopIpc.makeIpcMethod({
channel: IpcChannels.PREVIEW_PICK_ELEMENT_CHANNEL,
payload: DesktopPreviewPickElementInputSchema,
Expand Down Expand Up @@ -487,6 +498,7 @@ export const methods = [
clearCache,
getPreviewConfig,
setAnnotationTheme,
setForwardedKeyChords,
setAnnotationSendEnabled,
pickElement,
cancelPickElement,
Expand Down
14 changes: 14 additions & 0 deletions apps/desktop/src/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,20 @@ contextBridge.exposeInMainWorld("desktopBridge", {
ipcRenderer.invoke(IpcChannels.PREVIEW_CLEAR_CACHE_CHANNEL, { environmentId, profileId }),
getPreviewConfig: (environmentId, profileId) =>
ipcRenderer.invoke(IpcChannels.PREVIEW_GET_CONFIG_CHANNEL, { environmentId, profileId }),
setForwardedKeyChords: (shortcuts) =>
ipcRenderer.invoke(IpcChannels.PREVIEW_SET_FORWARDED_KEY_CHORDS_CHANNEL, { shortcuts }),
onForwardedKeyChord: (listener) => {
const wrappedListener = (_event: Electron.IpcRendererEvent, input: unknown) => {
if (typeof input !== "object" || input === null) return;
listener(input as Parameters<typeof listener>[0]);
};
ipcRenderer.on(IpcChannels.PREVIEW_FORWARDED_KEY_CHORD_CHANNEL, wrappedListener);
return () =>
ipcRenderer.removeListener(
IpcChannels.PREVIEW_FORWARDED_KEY_CHORD_CHANNEL,
wrappedListener,
);
},
setAnnotationTheme: (theme) =>
ipcRenderer.invoke(IpcChannels.PREVIEW_SET_ANNOTATION_THEME_CHANNEL, { theme }),
setAnnotationSendEnabled: (tabId, enabled) =>
Expand Down
16 changes: 16 additions & 0 deletions apps/desktop/src/preview/Manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,22 @@ describe("PreviewManager", () => {
);
expect(focus).toHaveBeenCalledOnce();
expect(send).toHaveBeenCalledTimes(2);
yield* manager.setForwardedKeyChords([
{ key: "z", metaKey: true, ctrlKey: false, altKey: true, shiftKey: false },
]);
const layoutPreventDefault = vi.fn();
beforeInput(
{ preventDefault: layoutPreventDefault } as never,
{ ...key, key: "z", code: "KeyY", alt: true, shift: false } as never,
);
expect(layoutPreventDefault).toHaveBeenCalledOnce();
layoutPreventDefault.mockClear();
beforeInput(
{ preventDefault: layoutPreventDefault } as never,
{ ...key, key: "y", code: "KeyZ", alt: true, shift: false } as never,
);
expect(layoutPreventDefault).not.toHaveBeenCalled();
yield* manager.setForwardedKeyChords([]);
send.mockClear();
yield* manager.setForwardedShortcuts([{ command: "view.reopenClosed", shortcut }]);

Expand Down
57 changes: 57 additions & 0 deletions apps/desktop/src/preview/Manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
DESKTOP_PREVIEW_RECORDING_CAPTURE_TRIGGER,
} from "@t3tools/contracts";
import type {
DesktopForwardedShortcut,
DesktopPreviewAnnotationTheme,
DesktopPreviewAnnotationVoiceConfig,
DesktopPreviewAnnotationVoiceState,
Expand Down Expand Up @@ -67,6 +68,7 @@ import * as DesktopRendererHistory from "../telemetry/DesktopRendererHistory.ts"
import {
MENU_ACTION_CHANNEL,
PREVIEW_ANNOTATION_VOICE_EVENT_CHANNEL,
PREVIEW_FORWARDED_KEY_CHORD_CHANNEL,
PREVIEW_PICTURE_IN_PICTURE_FRAME_CHANNEL,
} from "../ipc/channels.ts";
import * as DesktopBrowserHost from "./DesktopBrowserHost.ts";
Expand Down Expand Up @@ -501,6 +503,28 @@ export const previewWindowOpenAction = (details: {
: "navigate";
};

const isForwardedShortcut = (
input: Electron.Input,
shortcuts: ReadonlyArray<DesktopForwardedShortcut>,
platform: NodeJS.Platform,
): boolean => {
if (input.type !== "keyDown" || shortcuts.length === 0) return false;
return shortcuts.some((shortcut) =>
matchesKeybindingShortcut(
{
key: input.key,
code: input.code,
metaKey: input.meta,
ctrlKey: input.control,
altKey: input.alt,
shiftKey: input.shift,
},
{ ...shortcut, modKey: false },
platform === "darwin" ? "MacIntel" : platform,
),
);
};

const isPreviewRefreshShortcut = (input: Electron.Input, platform: NodeJS.Platform): boolean =>
input.type === "keyDown" &&
input.key.toLowerCase() === "r" &&
Expand Down Expand Up @@ -582,6 +606,9 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function
new Set(),
);
const pickSessionsRef = yield* Ref.make<ReadonlyMap<string, PickSession>>(new Map());
// Read synchronously in before-input-event, which must decide on the spot
// whether the page sees a key, so a plain variable rather than a Ref.
let forwardedKeyChords: ReadonlyArray<DesktopForwardedShortcut> = [];
const controlSessionsRef = yield* SynchronizedRef.make<
ReadonlyMap<number, BrowserControlSession>
>(new Map());
Expand Down Expand Up @@ -1567,6 +1594,27 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function
}
return;
}
// App chords (the layout map) go to the app window, not the page.
if (isForwardedShortcut(input, forwardedKeyChords, hostPlatform)) {
event.preventDefault();
const forwardedKey = {
key: input.key,
code: input.code,
metaKey: input.meta,
ctrlKey: input.control,
altKey: input.alt,
shiftKey: input.shift,
};
runFork(
Ref.get(mainWindowRef).pipe(
Effect.map((window) => {
if (Option.isNone(window) || window.value.isDestroyed()) return;
window.value.webContents.send(PREVIEW_FORWARDED_KEY_CHORD_CHANNEL, forwardedKey);
}),
),
);
return;
}
if (isPreviewRefreshShortcut(input, hostPlatform)) {
event.preventDefault();
runFork(
Expand Down Expand Up @@ -3533,6 +3581,10 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function
setAudioMuted,
setShown,
setColorScheme,
setForwardedKeyChords: (shortcuts: ReadonlyArray<DesktopForwardedShortcut>) =>
Effect.sync(() => {
forwardedKeyChords = shortcuts;
}),
setMainWindow,
setForwardedShortcuts: (shortcuts: ReadonlyArray<PreviewForwardedShortcut>) =>
Effect.sync(() => {
Expand Down Expand Up @@ -3766,6 +3818,10 @@ export class PreviewManager extends Context.Service<
tabId: string,
enabled: boolean,
) => Effect.Effect<void, PreviewManagerError>;
/** Chords a focused preview webview hands back to the app window. */
readonly setForwardedKeyChords: (
shortcuts: ReadonlyArray<DesktopForwardedShortcut>,
) => Effect.Effect<void>;
readonly pickElement: (
tabId: string,
voice?: DesktopPreviewAnnotationVoiceConfig,
Expand Down Expand Up @@ -3937,6 +3993,7 @@ export const make = Effect.gen(function* PreviewManagerMake() {
},
),
setAnnotationTheme: operations.setAnnotationTheme,
setForwardedKeyChords: operations.setForwardedKeyChords,
setAnnotationSendEnabled: operations.setAnnotationSendEnabled,
pickElement: operations.pickElement,
updateAnnotationVoice: operations.updateAnnotationVoice,
Expand Down
6 changes: 4 additions & 2 deletions apps/desktop/src/window/DesktopApplicationMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ export const make = Effect.gen(function* () {
{ role: "services" },
{ type: "separator" },
{ role: "hide", label: `Hide ${environment.displayName}` },
{ role: "hideOthers" },
// alt+cmd+H focuses the pane on the left; Hide Others keeps its item.
{ role: "hideOthers", accelerator: "" },
{ role: "unhide" },
{ type: "separator" },
{ role: "quit", label: `Quit ${environment.displayName}` },
Expand Down Expand Up @@ -255,9 +256,10 @@ export const make = Effect.gen(function* () {
accelerator: "Shift+CmdOrCtrl+R",
click: mainContentsClick("forceReload"),
},
// alt+cmd+I and J belong to the layout keys on macOS.
{
label: "Toggle Developer Tools",
accelerator: environment.platform === "darwin" ? "Alt+Command+I" : "Ctrl+Shift+I",
accelerator: environment.platform === "darwin" ? "Alt+Shift+Command+I" : "Ctrl+Shift+I",
click: mainContentsClick("toggleDevTools"),
},
{ type: "separator" },
Expand Down
49 changes: 38 additions & 11 deletions apps/desktop/src/window/DesktopWindow.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as NodeServices from "@effect/platform-node/NodeServices";
import { assert, describe, it } from "@effect/vitest";
import * as Deferred from "effect/Deferred";
import { DesktopSnapShotId } from "@t3tools/contracts";
import { DEFAULT_CLIENT_SETTINGS, DesktopSnapShotId } from "@t3tools/contracts";
import * as Effect from "effect/Effect";
import * as Exit from "effect/Exit";
import * as Fiber from "effect/Fiber";
Expand Down Expand Up @@ -46,7 +46,7 @@ import * as ElectronMenu from "../electron/ElectronMenu.ts";
import * as ElectronShell from "../electron/ElectronShell.ts";
import * as ElectronTheme from "../electron/ElectronTheme.ts";
import * as ElectronWindow from "../electron/ElectronWindow.ts";
import { SNAP_SHOT_EVENT_CHANNEL } from "../ipc/channels.ts";
import { MENU_ACTION_CHANNEL, SNAP_SHOT_EVENT_CHANNEL } from "../ipc/channels.ts";
import * as DesktopServerExposure from "../backend/DesktopServerExposure.ts";
import * as DesktopWindow from "./DesktopWindow.ts";
import {
Expand Down Expand Up @@ -163,9 +163,7 @@ function makeFakeBrowserWindow() {
};
}

const layerDesktopClientSettings = Layer.mock(DesktopClientSettings.DesktopClientSettings)({
get: Effect.succeedNone,
});
const layerDesktopClientSettings = DesktopClientSettings.layerTest();

const layerElectronApp = Layer.mock(ElectronApp.ElectronApp)({
quit: Effect.void,
Expand Down Expand Up @@ -360,6 +358,7 @@ function layerTest(input: {
),
),
Layer.merge(DesktopState.layer),
Layer.merge(layerDesktopClientSettings),
);
}

Expand Down Expand Up @@ -1254,20 +1253,48 @@ describe("DesktopWindow", () => {
if (!swipe) return;
const history = fakeWindow.navigationHistory;

swipe({}, "left");
yield* Effect.promise(() => Promise.resolve(swipe({}, "left")));
assert.equal(history.goBack.mock.calls.length, 1);
assert.equal(history.goForward.mock.calls.length, 0);
swipe({}, "right");
yield* Effect.promise(() => Promise.resolve(swipe({}, "right")));
assert.equal(history.goForward.mock.calls.length, 1);

swipe({}, "up");
swipe({}, "down");
yield* Effect.promise(() => Promise.resolve(swipe({}, "up")));
yield* Effect.promise(() => Promise.resolve(swipe({}, "down")));
history.canGoBack.mockReturnValue(false);
history.canGoForward.mockReturnValue(false);
swipe({}, "left");
swipe({}, "right");
yield* Effect.promise(() => Promise.resolve(swipe({}, "left")));
yield* Effect.promise(() => Promise.resolve(swipe({}, "right")));
assert.equal(history.goBack.mock.calls.length, 1);
assert.equal(history.goForward.mock.calls.length, 1);
assert.equal(
fakeWindow.send.mock.calls.filter(([channel]) => channel === MENU_ACTION_CHANNEL).length,
0,
);
const settings = yield* DesktopClientSettings.DesktopClientSettings;
yield* settings.set({
...DEFAULT_CLIENT_SETTINGS,
layoutThreeFingerSwipe: true,
scrollingWorkspacesEnabled: true,
});
history.canGoBack.mockReturnValue(true);
history.canGoForward.mockReturnValue(true);
for (const direction of ["left", "right", "up", "down"]) {
yield* Effect.promise(() => Promise.resolve(swipe({}, direction)));
assert.deepEqual(fakeWindow.send.mock.lastCall, [
MENU_ACTION_CHANNEL,
`layout-swipe-${direction}`,
]);
}
assert.equal(history.goBack.mock.calls.length, 1);
assert.equal(history.goForward.mock.calls.length, 1);
yield* settings.set({ ...DEFAULT_CLIENT_SETTINGS, layoutThreeFingerSwipe: true });
fakeWindow.send.mockClear();
yield* Effect.promise(() => Promise.resolve(swipe({}, "left")));
yield* Effect.promise(() => Promise.resolve(swipe({}, "right")));
assert.equal(history.goBack.mock.calls.length, 2);
assert.equal(history.goForward.mock.calls.length, 2);
assert.equal(fakeWindow.send.mock.calls.length, 0);
}).pipe(Effect.provide(layer));
}),
);
Expand Down
25 changes: 20 additions & 5 deletions apps/desktop/src/window/DesktopWindow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -834,11 +834,26 @@ export const make = Effect.gen(function* () {

if (environment.platform === "darwin") {
// Mouse drivers can deliver Back/Forward as macOS swipe gestures instead of buttons.
window.on("swipe", (_event, direction) => {
const history = window.webContents.navigationHistory;
if (direction === "left" && history.canGoBack()) history.goBack();
else if (direction === "right" && history.canGoForward()) history.goForward();
});
window.on("swipe", (_event, direction) =>
runPromise(
Effect.gen(function* () {
const settings = yield* clientSettings.get.pipe(
Effect.orElseSucceed(() => Option.none()),
);
if (
Option.isSome(settings) &&
settings.value.layoutThreeFingerSwipe &&
settings.value.scrollingWorkspacesEnabled
) {
window.webContents.send(MENU_ACTION_CHANNEL, `layout-swipe-${direction}`);
return;
}
const history = window.webContents.navigationHistory;
if (direction === "left" && history.canGoBack()) history.goBack();
else if (direction === "right" && history.canGoForward()) history.goForward();
}),
),
);
window.on("enter-full-screen", () => {
window.webContents.send(WINDOW_FULLSCREEN_STATE_CHANNEL, true);
});
Expand Down
Loading
Loading