d16413ef43
Layout (overlap bug): the EmbeddedHubPicker section had no flex
containment — its fixed-height iframe viewport made the section's
min-content height rigid, so at a tall persisted drag height or a short
window the flex column starved the installed-skills area to 0px and the
hub header row painted straight over the list's sort strip and "changes
apply to new sessions" footer. The picker section now clips its own
content (overflow-hidden, shrinkable, min-h for the header row), the hub
viewport uses flex-basis instead of a hard height so it gives pixels
back first, the list region keeps a min-h-40 floor, and the sash drag is
clamped against the actual column height (list reserve) rather than just
the window.
Perf (Capabilities lag):
- The hub iframe (a full Docusaurus site) mounted eagerly with the view
and re-mounted on every scope change (key={`picker-${scopeKey}`}).
It now lazy-mounts the first time the Skills tab is shown, then stays
mounted but display:none across Tools/MCP so a tab bounce never
reloads the site. The scope key is gone — the picker fetches nothing;
the profile rides into each install call as a prop.
- EmbeddedHubPicker is memo()ed and subscribes to the single
UPDATE_ALL_KEY running flag via useStoreSelector instead of the whole
$hubActions map, which churns on every tailed log line during installs.
- Collapse state now persists through the pane store (0 = collapsed),
matching DetailPane, instead of resetting open on every mount.
- CapRow gets content-visibility:auto so 80+ row lists skip offscreen
layout/paint (fixed row heights keep scroll geometry stable).
Validation: npm run check:lint (tsc x3 + eslint) clean; vitest
src/app/skills 9/9 passing, including a new test asserting the iframe
is absent on non-Skills tabs, mounts with the Skills tab, and survives
a tab switch hidden.