# 实现注记 README 里放不下的取舍、槽位选择、以及踩过的坑。 ## 为什么是这三个 slot 插件的全部界面都通过 DSH 的官方 slot 挂载,**没有 DOM 扒取**(对比:社区里一些同类插件靠 `querySelector('[class*="sidebarCol"]')` 猜位置,上游一改标记就挂)。 | slot | 基数 / 作用域 | 用途 | |---|---|---| | `sidebar.panellist` | list / root | 侧边栏顶部的入口行。shell 自己拥有按钮、tooltip 和无障碍名 | | `main` | keyed / root | **必须存在**,key 与 list 的 `id` 相同 —— 否则 ui-layout 直接拒绝选中("selecting a missing main entry throws")。它不渲染任何东西 | | `shell.overlay` | list / root | 整页接管。它的层在 app frame 内是 `position:absolute; inset:0`,所以放一个元素就能盖住**整个页面(含侧边栏)** | **为什么需要 Node 半面**:浏览器无法自己探测 `http://127.0.0.1:3081/` —— 它与页面同 site 但跨 origin,而远程不发 CORS 头,页面内 fetch 最多拿到 opaque 响应。从 Node 探测还能区分「隧道没通」(`ECONNREFUSED`)和「DSH 活着但浏览器还没配对」(带指纹的 401),这是顶栏最有价值的状态信号。 ## 「远程」为什么在「新会话」上面 侧边栏 shell 按固定顺序画自己的块:**品牌行 → 新会话 → `sidebar.panellist`(本插件的位置)→ 工作区 → 底部**。也就是说 panellist 这个座位**天生在新会话下面**。 而品牌行里**没有座位**:`sidebar.brand.mark` / `sidebar.brand.name` 两个插槽都渲染在一个 `aria-hidden` 的 `