Repository navigation
Finish views: media in frames, the share indicator, the command bar's catalogue, split, Peek and Mini Window gaps - #26
Conversation
…c PiP, the controller and the page menu's PiP (MD-01, MD-09, MD-02) Each frame of a playing tab that has media elements gets the media script in its own world, found through the frame tree (webFrameMain), not a frame preload (D40). Its reports are checked (parseSnapshot) and combined with the page's (combineSnapshots). A video in a frame floats through each frame on the way: the frame elements lift at the borrowed view's size, the video in its own frame. The player's calls go to the video's frame; controls, the tray's x and call controls reach every frame. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…RE notes the frame media script Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…twork (MD-09) The page script picks the artwork (the smallest image of at least 64 px, web or data: images only); the main process loads it with the tab's own session and keeps a 48 px data: copy, which is all the shell may show. The site icon shows until then, and when there is none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… (MD-08) The site controls panel gets a Picture in Picture switch for the site, on by default: off is "Always turn off for this site", on undoes that and "Turn off for today", which it shows too. The test also turns the global switch off in Settings > Advanced and checks the video plays on in the sidebar. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A tab sharing a screen or window shows a distinct blue indicator on its row while either source says a share is live (D69): - main's watcher: when Orbit's screen chooser grants a share to any frame of a tab, main puts a script in that frame's own world before the page has the stream, and counts grants, stops, clones and ended sources; - the page preload's count of the main frame's live shared tracks, on a new channel, orbit-page:screen-share (main frame only, clamped, for the tab's indicators only). It sees shares macOS 15's system picker grants. Only chooser grants keep a tab awake and unarchived (screenGranted). NV-15 fix: getDisplayMedia no longer asks for camera and microphone before the screen chooser (Electron asks for 'media' with no media types). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n; per-pane recording indicators (SV-21) - Command bar: an open split is one result (every pane's favicon, its name or pane titles, "Switch to split"), found by any pane or its name; choosing it shows the split with the best-matching pane. Its panes' pages aren't listed again from history or the Archive, and the split on screen isn't offered. - Split menu: Change Icon… opens the sidebar's emoji picker; the icon stands in for the panes' favicons on the split row and its Favorites tile (SV-22, SV-23). Split.icon is persisted. - Each pane segment shows its recording indicator next to the audio one (TB-15); a named split shows them after its name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…atalogue (CB-05, CB-13) - Every Settings section and setting the bar finds (ST-02's actions) is a row labelled Settings, not Action. A unit test keeps every section the settings registry has in the bar. - New actions: Archive Tabs Below (TD-05, on the current tab or its split) and Close Split (the whole split, SV-19; Close Split Pane stays SV-17's). - Catalogue names Copy URLs, Change Theme and Zoom Reset find their actions; an exact typed title wins a tie. A unit test checks each catalogue name Orbit has finds its action first, with the key the live keymap gives it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…SV-26) entryRect took its start from the old pane that covered the new pane's place, and returned the full target when that pane was closing in the same change (or none covered it yet), so the new pane appeared at full size. It now looks only at panes that stay, and otherwise starts the pane as a zero-width sliver on the side its neighbour is (PR #19 review F10). The test adds a pane in the same moment its neighbour's other side closes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A split row in Today offers Archive Tabs Below, as a Today tab's row does (TD-05): the items under the split go to the Archive and the split stays. On the last item it is there but greyed out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each pane of a pinned split keeps its own pinned URL. The split's menu has Reset to Pinned URLs, which sends every pane that wandered off back to its own pinned page; a Favorite split's tile shows the away dot and a double-click does the same, as a tab tile's does. Reset Tab on one pane still resets that pane. Tests also cover what was already there: a link to another site in either pane of a Favorite split opens a Peek from that pane, and the split keeps its focused pane across Spaces. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
⌘T with the floating sidebar out opens the bar over it; the sidebar stays while the bar is open, a right-click over it only closes the bar, and a left click on a tab row there selects the tab in one click and closes the bar. It was all there already: the test names it and the row is marked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…its keys first (CB-23, K3) The Mini Window's lookup bar and the field over its page are now the command bar's compact variant: history from its profile, typed URL and search rows, inline completion, site search and suggestions, and nothing that acts on the browser (open tabs, archive, Spaces, folders, actions). A choice loads there. Over a page the list covers a still image of the page while the page's view steps aside. While it is open, Cmd+W and Cmd+L close the bar first, not the window; Enter with nothing to load gives the page the keyboard (K3). The split pane's bar already closed on Cmd+W, Cmd+T and Cmd+L and removed the empty pane; a test now covers it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…a split (SV-07, SV-08) SV-07: on Windows and Linux a split button beside the window controls opens Add Split Right, Left, Above and Below, each with its key. It is the first to give way when the sidebar is narrow; macOS has none. SV-08: a link dragged out of a page that rests on a pane's page (or on Orbit's surface in the frame) shows the drop indicator with SV-04's zones, and the drop opens it in a new pane there. Main installs a watcher in an isolated world and asks it where the drag is; the page never calls out. The page's own drop targets and text fields keep the drag, a drag near the link does nothing, a full split takes none, and only web addresses open. Dropped files are not built (D40, D49, D58). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…keys review F3); check PK-12 With a Peek open, ⌘F, ⌘G and F3 find in the Peek's page: the find bar shows over the card's top-right corner, above the Peek's view, with the Peek's own search; Esc gives the Peek the keyboard back, and the tab under it keeps its own search. A Mini Window's ⌘F opens a find field in its top bar beside the host (finds as you type, n/m count, Enter, ⌘G and F3 go on, Esc keeps the match selected and focuses the page). PK-12's toggles (settings lane) were already built; a Favorite case was added to the link-routing unit test and the row marked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-17's note says what its test checks (K8) The window's UI grows from 92% to full size in 200 ms in its own layer while the window fades in (on Linux, which can't fade a window, the UI fades too). The OS window isn't resized, which would lay the page out every frame: the page's view, loading all along, sits out the grow and joins on the card at full size when it ends. Main waits up to 100 ms for the UI to take its starting size before showing the window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…alogs (MD-06); media notes name their gaps (MD-05, MD-13, MD-14, MD-16) While an Orbit window shows an alert or dialog (the engine disables the window, macOS shows a sheet, and Orbit's own file pickers say so through dialog-watch), the player keeps clear of where it shows: it glides to the nearest clear corner at its size, or goes out of sight while no corner is clear, and comes back when the dialog closes unless it was moved meanwhile. The remembered corner doesn't change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ns (MW-14) A packaged Linux folder build has no desktop entry, so its launcher can't offer actions. Orbit now writes its own to the user's applications folder a moment after start-up, under Electron's desktop name, with both actions; each runs Orbit with its switch, which reaches the running app as a second instance. It keeps the entry pointing at where Orbit runs from, and never touches an entry a package installed or one it didn't write. Flatpak and Snap installs are left alone. The build ships icon.png for the entry. Checked on a packaged build: the entry appears, and launching each action opens a Mini Window, then hides and shows them all. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…oard in find (keys review F3) On a busy machine the window's focus event can arrive after ⌘F has opened the find field, and the handler gave the keyboard back to the page. The page now takes it only when neither the find field nor the command bar is open. The F3 test sends a late focus after find opens; without the guard it fails (the page has the keyboard). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…; MW-12's full screen tested; MD-15 recorded The button is off by default; Settings > General > Mini Window turns it on. macOS gets Orbit's mark as a template glyph in the menu bar (a click opens, a right-click shows the menu); Windows and Linux get the app's icon in the tray (the drawn mark where a build ships no icon file) with the menu as its context menu. A click opens a blank Mini Window with its lookup bar focused; the menu has New Mini Window and Show/Hide All Mini Windows, so MW-14's four ways in are all there on every platform. Without the button the e2e fails at its first check (no button). MW-12: a video's full screen in a Mini Window now has a test: the page fills the screen inside that window and stays a Mini Window page, and the card comes back on exit. It stays partial: no extensions, captures or sharing exist yet. MD-15 is recorded as not started: the screen chooser shares screens and windows, never one tab, and the engine can't change a running capture's source. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The test timed the grow from the first sample it took to the first one at full size. On a busy machine (load 8) that came to 148.8 ms against its "> 150" check: the samples can start late, and the ease-out gets within 0.1% of full size well before it ends. The test now times the grow's own animation, from its start to when it finishes. A grow shortened to 100 ms still fails the check (114.7 ms). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…CB-23) ⌘L over a Mini Window's page focused the window's UI, but main only counted the bar as open once the UI said so. A window focus, or the end of the open grow (MW-04), that came in before then gave the keyboard back to the page, so the bar opened without it. Main now counts the bar as open from ⌘L. The CB-23 page-bar test now fires the window's focus right after ⌘L. Without the fix it fails: the keyboard is no longer in the Mini Window's UI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s for it (CB-23, NV-05) A key can reach a new Mini Window's page before the window's UI has mounted. This happens under the test harness, which readies no spare window, and on a busy machine. Main sent ⌘L's mini:edit-url and ⌘F's mini:find at once, and nobody was listening yet, so the bar and the find field never opened. Main now holds every mini:* message except the open grow's until the UI reports mini.mounted, then sends them in order. The new test gives two new windows ⌘L and ⌘F straight away. With the holding turned off it fails: the address field never shows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 8937099c-f521-48af-af6c-68af4c002f2e) |
A page or a cross-site frame could dispatch a made-up leavepictureinpicture on its playing video; media's script reported "Back to tab", and main selected the tab, raised its window and switched Space. - The script counts leavepictureinpicture and ended only when trusted. - A frame's script runs in the page's own world, so the page can still call its listener with a forged event. Main now treats a frame's "back" as a request: it brings the window forward or switches Space only for a picture-in-picture Orbit opened in that document (the Picture in Picture action, controller or page menu), once per such picture-in-picture. Otherwise it selects the tab only in a window that already has focus, in the Space that window shows. The tab's own page script (isolated world) keeps today's behaviour. - MD-01's note and ARCHITECTURE §10 give D71's known limit: a page's own PiP button inside a frame returns to the tab without raising the window. Tests: the reviewer's repro (a background tab's page and cross-site frame faking the event every 2 s, auto-PiP off), plus a made-up "ended" that must not close Orbit's player; and a frame that forges the call, which gets no Space switch and no raise, a selection only with focus, and one raise for Orbit's own picture-in-picture. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An entry at the user's path that couldn't be read (no read permission, a folder, a link to nothing) counted as absent, so a folder build wrote over it, or through the link. Now it counts as not Orbit's and is skipped, and a link counts as something there even when it points at nothing. MW-14's note and ARCHITECTURE §11 now say that a packaged Linux folder build writes ~/.local/share/applications/<name>.desktop at start-up, with no opt-out for now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- What main sends a Mini Window's UI waits again while the UI reloads: its page starting to load (or its renderer going) clears `mounted` until the next `mini.mounted`. Before, a message sent then was lost. - The Mini UI reloads after a renderer crash, as the shell, sidebar and tools views do (WindowManager.reloadUiOnCrash, now public). - What only the old UI showed goes with it: the bar over the page (whose view had stepped aside, so the page stayed hidden) and the find field (so ⌘G searched with no field to show it). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 8b8aa3c9-8253-4dd1-bc95-e89e23527174) |
Conflicts, resolved as in the dry run (rerere): - CommandBar.tsx: feel's useReducedMotion and BAR_* timing replace the bar's own reduced-motion hook; the Mini Window bar (CB-23) is kept. - SplitFavoriteTile.tsx: feel's live reduced motion, TILE_FADE and ref; the tile's away-from-pinned mark and double-click reset are kept. - miniwindow/index.ts: the shared reducedMotion(ctx) replaces the local one; the UI reload and crash handling is kept. - feature-status.json: SV-26 joins both notes; FEATURES.md regenerated. Also: player.ts's last richMotion() call reads reducedMotion(ctx), and the screen-share comment in media.css sits on its rule again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: d34af5d5-0bd2-4c74-89b5-b0193ee50732) |
…oved one isn't Back to tab (D74) - The page script counts a leave as Back to tab only if no picture-in-picture is left in its document after the 300 ms wait: a page that moves its picture-in-picture between its videos gets no raise. - An unmarked Back to tab from a frame selects its tab at most once per frame document. - Main clears a tab's marks when it closes Orbit's picture-in-picture there (Picture in Picture off, the page menu, the tab coming back) or hands it to the player, and every other document's mark when it opens one: the engine shows one at a time. - MD-01's note and ARCHITECTURE §10 give D74's known limit: a page can end its own picture-in-picture once and bring the window forward. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ommits (D74) A navigation the UI starts and will-navigate cancels left it unmarked as up: what main sent after it waited for a mount that never came. mounted is now cleared on did-navigate, so a cancelled navigation changes nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…wn place in its list (N5) It was role="button" yet counted in its list's aria-setsize, so the tab rows around it skipped its number. It is now a treeitem with its level, place and size, named by the split's name or its panes' titles. ItemList passes it the place it already had. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: d6f97da4-1088-41ee-8a70-cd18efad282c) |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: d6b393e2-c984-40db-8a96-0a0dcf3d71ea) |
… back is drawn, at any load (MD-01) Back in its place, a frame's page learns its new size only when its parent lays it out, after that frame's events: its resize event comes with the next frame, after one is drawn at its own size with the video still lifted. Only main's own drop, when it came first, hid this (gate r1: media.spec.ts:1959). While its video or a frame on the way is lifted, a frame's script now also watches its root element and a hidden element as big as its viewport with a ResizeObserver, which runs after layout and before the frame is drawn, and puts the video back there. The root alone follows the viewport's width, not its height; observed too, it keeps the page's own observers of what moves from being skipped in that frame. Tests: the frame recorder reads each frame after layout (a ResizeObserver), as it will be drawn. The frame tests hold main's drop and return three times; a new one uses a frame that fills its page, where only the height changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ened isn't Back to tab (D75) The engine shows one picture-in-picture at a time. When a page, a frame or Orbit opens one, the one it replaces reports a leave with nothing left in its document, which counted as "Back to tab": main selected the first tab again and raised its window. - Main ignores a "back" from any document while another document's latest report shows the engine's picture-in-picture. - Before Orbit opens one (the action, the controller, the page menu, in a page or a frame), it ends any other with its own exit, so that document reports it as Orbit's. Tests: a split of two pages and a cross-site frame, and two tabs (one in the background, then one in another window); the second opened by Orbit's action, its page menu and the page itself; the window focused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e Mini Window open and the split entry
Each runs under launchOrbit({ reducedMotion: true }) and fails without its check:
- MD-06: the player steps aside for Orbit's alert, and back, with no frame between corners and no
animation (without the check in glide() it springs across).
- MW-04: a Mini Window shows at its full size with its page from its first frame, and its UI never
scales or fades (without growOpen's check the first shown frame has no page).
- SV-26: a new split shows both panes at their end boxes from the first frame (without the check in
the split engine the new pane grows from width 0). The shell page drops Playwright's
prefers-reduced-motion emulation so it sees the forced setting.
The MD-06 alert helpers are hoisted so both alert tests share them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r's curves come from the motion tokens - GROW_MS is DURATION.snappy (200 ms, unchanged) and the UI grow runs on EASE.snappy, the curve its --ease-out resolved to. - Main's Mini Window fade-in (macOS and Windows, where windows fade) runs on the same EASE.snappy curve as the UI's grow, in place of a cubic ease-out, so the window and its UI move as one. - pip.ts's STANDARD_CURVE and EASE_OUT_CURVE are EASE.standard and EASE.instant (same values). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 1287cb9b-c450-426e-b9e2-7c4fbd4efb93) |
Conflicts: - src/main/split/index.ts: both. Main's split.addMenu, and the split row's menu keeps finish-tabs' `at` (TB-14's overlay menu) beside main's Change Icon… item. - src/main/commandbar/search.ts: both. A Mini Window's bar offers no tabs, archive, Spaces, folders or actions (CB-23), and a blank window finds only its own tabs and no Spaces or folders (TB-17). - docs/feature-status.json: TB-14 finish-tabs' (yes), TB-15 main's (screen-share indicator). - FEATURES.md: regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts: docs/feature-status.json (MD-06 keeps the lane's note on Orbit's covers, MD-07 takes main's D75 sentence) and FEATURES.md (regenerated). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The finish-views lane finishes the command bar, split view, Peek, Mini Windows and media, built from
lanes/finish-views.mdonmain(332fb99;592096band then feel's merge3bcb521merged in). Againstmainit changes 77 files (+7734/−548). The builder's report isreviews/lane-finish-views-report.md.What it builds
webFrameMain), with a media script per frame in its own world, not a frame preload (D40). It gets the same automatic picture-in-picture and controller as a top-level video, the page menu's Picture in Picture, and Media Session artwork.Decisions where the spec was unclear
mini.mounted, except the grow's message;Edits in other lanes' files
Each is listed in the report (§3):
windows.ts'sshowTools({top});electron-builder.yml.withDialog(MD-06);Review and fix rounds
reviews/lane-finish-views.md, on5964b7f): approve with one must-fix and three follow-ups.0c6dd9e;reviews/lane-finish-views-fix1-report.md). Each fix fails its test without it.0e5c945):endedandleavepictureinpictureevents.media.spec.ts:2036(the reviewer's repro) and:2091(a forged handler call).83f14d8): an entry Orbit can't read, or a link to nothing, is skipped.0c6dd9e): main holds its messages while its UI reloads, and the UI reloads after a crash.reviews/lane-finish-views-fixcheck.md, on0c6dd9e): approve, no must-fix. Its four follow-ups became D74.404da37,bace4d8):ce76924, from feel's fix check): the split row is atreeitemwith its own place in its list.1fdee1e(12bf737), with conflicts resolved in seven files;main3bcb521(05b7eb9), with no change to the tree.reviews/lane-finish-views-fixcheck2.md, on05b7eb9): approve, no must-fix. Its follow-up 1 became D75.05b7eb9(10:35–11:12): unit 959/959; e2e 684 passed, 1 failed, 2 skipped.media.spec.ts:1959. It recorded one frame drawn at the frame's own size while its video was still lifted. It passed 3 of 3 alone, but the lead counted it as a real race, not a flake.3cfe604):eb16b4f):resizecomes a frame later.ResizeObserver. That runs after layout and before the frame is drawn, and the script puts the video back there.162c44e): a picture-in-picture that the engine closes because another one opened isn't "Back to tab".3c419f0): for the picture-in-picture glide aside, the Mini Window grow and the split entry.a9c610d): the Mini Window grow and fade, andpip.ts's curves, now come from feel's motion tokens.3cfe604): it names the finish-tabs lane for the sidebar's row merge.reviews/lane-finish-views-fixcheck3.md, on3cfe604): approve, no must-fix.Merge gate (D42), run locally on Linux on
3cfe604npm run build,npm run typecheck,npm run lintand./node_modules/.bin/vitest runall exit 0. Unit: 959 passed of 959, in 92 files.xvfb-run -a -s "-screen 0 1440x900x24" ./node_modules/.bin/playwright test --workers 1 --retries 0ran 693 tests in 38.8 min: 690 passed, 2 skipped, 1 failed, and it exited 1.3cfe604itself, withmain(3bcb521) in it. The load average was 4–12, with other lanes' work beside it.feel-rows.spec.ts:317) measured 263.2 ms against its 250 ms budget, at load 11.6.05b7eb9, the merge ofmain3bcb521. It finished with 684 passed, 2 skipped and 1 failed, at load 7–9; unit 959/959.media.spec.ts:1959). That was a real race: the frame's resize came a frame late.eb16b4ffixes it with a ResizeObserver (D78). Fix check 3 found it failing 8 of 8 without the fix and 0 of 12 with it.1899f18, before feel merged, was stopped at 230 of 621 so feel could merge first. It passed build, typecheck, lint and unit (943/943), and had one MW-04 failure, which0c1cfe5fixes.Not run here (unverified):
🤖 Generated with Claude Code
Note
Medium Risk
Touches page preload IPC, screen-share detection, and broad command-bar/Mini Window routing; Linux desktop-entry writes under the user data dir but skips packaged/foreign entries.
Overview
Closes gaps across command bar, split view, Peek, Mini Window, and media per the finish-views lane, with
FEATURES.md/feature-status.jsonbumped to match.Command bar: open splits rank as a single row (name or pane titles, deduped history/archive); Settings registry rows and tighter action matching (e.g. Close Split vs Close Split Pane);
tab.archiveBelowwired; Mini Window search is a compact variant (history/typed URL only—no tabs, Spaces, actions) withsearch.openloading viamini.navigate.Media: PiP from context menu targets the video under the pointer in iframes; screen-share reporting via preload
orbit-page:screen-shareand ascreenSharehook for chooser grants; Media Session artwork fetched/scaled inartwork.ts; floating player avoids Orbit dialogs throughwithDialog/dialog-watch(downloads, import, open file, save page, etc.).Mini Window / Linux: packaged builds ship
icon.pngfor tray/launcher;desktop-entry.tswrites/updates a user.desktopwith New Mini Window / Show-Hide actions;tray-icon.tsdraws the menu-bar glyph when no icon file exists.Docs:
ARCHITECTURE.mddocuments frame media agents, screen-share IPC, and desktop-entry behavior.Reviewed by Cursor Bugbot for commit 3cfe604. Bugbot is set up for automated code reviews on this repo. Configure here.