- inventory: 607MB asar was ~605MB duplication (python-env 408MB + build-staging 197MB)
- both already ship unpacked in resources/; runtime reads resources/, never the asar
- add build.files exclusion -> asar ~607MB -> ~2MB; kills the 639MB cold-read on first launch
- add inspect_asar.js inventory tool; validate asar size + boot on a packaged exe
* dashboard: pan canvas via middle-drag and horizontal scroll over browser/chat
- Middle-mouse drag inside a browser webview is forwarded as canvas pan
(previously eaten silently by the guest compositor).
- Horizontal-dominant wheel inside a browser webview pans the canvas
when no ancestor in the guest page can absorb horizontal scroll;
otherwise the page handles it.
- Horizontal-dominant wheel over a chat panel pans the canvas (chat has
no horizontal scroller). Vertical scroll is unchanged.
Plain vertical scroll and ctrl/meta+wheel zoom over a browser stay with
chromium's defaults.
* browser: drop in-guest zoom locks so pinch and cmd+wheel zoom the page
setVisualZoomLevelLimits(1, 1) blocked pinch-to-zoom inside the webview, and
setZoomFactor(1) on every dom-ready reset any user page zoom. Both were added
back when canvas zoom was supposed to take over for ctrl+wheel; with that
reverted, chromium's native zoom handlers should run unimpeded.
* [aidan] fix: prev. commit fix. restore ctrl+wheel canvas zoom over webview cards
* [aidan] ui/ux: app navigation
* [aidan] ui/ux: gate webview preload forwarding on app interactive mode
When a view card is "interactive" (user clicked into the app), the preload stops forwarding ctrl+wheel, middle-mouse-drag, and horizontal-scroll-pan gestures so the embedded app gets every event. A mousedown notifier reports in-guest clicks to the host so it can flip the card into interactive mode without intercepting the click itself.
The backend already broadcasts the originating dashboard_id with every browser_card_added, but the frontend was throwing it away. Browser cards live in a single global Redux dict and the canvas rendered all of them unfiltered, so a browser spawned by an agent on dashboard A would appear in whatever dashboard the user was currently viewing.
Tag every card with its dashboard_id (at WS arrival and at fetchLayout hydration) and filter by it in useDashboardSelectors so render, bounds, layout save, and keyboard nav all see only the local dashboard's cards.