fix(web-shell): isolate slash command plugin pages - #7581
Conversation
E2E verification report
|
|
Thanks for the PR! Template looks good ✓ Problem: observed inconsistency — the unified Plugins page respects Direction: aligned. This is a straightforward consistency fix within the web-shell Shadow DOM boundary — no auth, sandbox, or model-selection surface is touched. Size: not applicable (no core paths). 6 files, +142/−33 — production logic ~72 lines in Approach: the scope feels right. Hoisting the existing Moving on to code review. 🔍 中文说明感谢贡献! 模板完整 ✓ 问题:已观测到的不一致——统一 Plugins 页面遵循 方向:对齐。这是 web-shell Shadow DOM 边界内的一致性修复,未触及 auth、sandbox 或模型选择。 规模:不适用(未触及核心路径)。6 个文件,+142/−33——生产逻辑约 72 行( 方案:范围合理。将现有 进入代码审查 🔍 — Qwen Code · qwen3.8-max-preview Reviewed at |
Code ReviewThe approach is exactly what I'd propose independently: hoist the existing
One minor note: for the No correctness bugs, security issues, or regressions found. No AGENTS.md violations. Test Resultstmux is not available on this CI runner, so browser-level verification was not possible. The unit and integration tests above cover the shadow-isolation behavior for each panel type. 中文说明代码审查方案与我独立提出的一致:将现有
一个小注意点: 未发现正确性 bug、安全问题或回归。无 AGENTS.md 违规。 测试结果shadowDom 单元测试 13 项全部通过;App 集成测试中 4 项 shadow 隔离测试全部通过;完整 web-shell 测试套件 2078 项全部通过。类型检查、构建、lint 均干净。 此 CI 运行环境无 tmux,无法进行浏览器级验证。上述单元和集成测试覆盖了各面板类型的 shadow 隔离行为。 — Qwen Code · qwen3.8-max-preview Reviewed at |
|
Confidence: 5/5 Small, focused fix that does exactly one thing: extends the existing All 2078 web-shell tests pass, typecheck and build are clean, lint is clean. The new tests cover each compatibility page individually. The LGTM, approving. ✅ 中文说明置信度:5/5 小而专注的修复,只做一件事:将现有 全部 2078 项 web-shell 测试通过,类型检查和构建干净,lint 干净。新测试逐一覆盖各兼容页面。 LGTM,批准。 ✅ — Qwen Code · qwen3.8-max-preview Reviewed at |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
🖼️ web-shell visual previewRendered against a mock daemon (no real backend): the PR base vs this PR head Screenshots · before / afterℹ️ No screenshot changed against the PR base — but this PR edits 1 render-shaping file:
Either the change has no visual effect (logic, plumbing, a state the scenarios never reach), or no scenario renders this UI — in which case the preview cannot see it, and an empty result is a coverage gap rather than a clean bill of health. To make it visible, add a scenario to Full-resolution recordings (.webm) are attached to the workflow run. — Qwen Code · web-shell visuals |
| .filter(Boolean) | ||
| .join(' ')} | ||
| styles={shadowDomOptions.styles} | ||
| initialFocusRef={ |
There was a problem hiding this comment.
[Suggestion] initialFocusRef only covers plugins and extensions; mcp/skills/agents fall through to undefined. If these panels manage focus internally, a brief comment (e.g. // mcp/skills/agents manage focus internally) would prevent future maintainers from thinking it's an oversight.
— qwen3.8-max-preview via Qwen Code /review
yiliang114
left a comment
There was a problem hiding this comment.
LGTM. Clean lift of ShadowDomBoundary from per-component to panel-level, conditioned on isPluginShadowPanel(). Tests cover inclusion/exclusion correctly. One inline nit on initialFocusRef coverage.
— qwen3.8-max-preview via Qwen Code /review
What this PR does
Extends the existing
shadowDom.pluginsoption to isolate every plugin-management surface, including the unified Plugins page and the compatibility pages opened by/extensions,/mcp, and/skills. It also recognizes theagentspanel introduced by #7572 so the agents manager and its nested create/edit page use the same boundary once that change is present.Why it's needed
Consumers can opt into Shadow DOM isolation for the unified Plugins page, but opening the equivalent managers through slash commands currently renders them in the host page's Light DOM. That creates inconsistent style isolation depending on how the same management UI was opened.
Reviewer Test Plan
How to verify
Embed Web Shell with
shadowDom={{ plugins: true, portals: false }}. Open the unified Plugins page, then run/extensions manage,/mcp, and/skills details; each manager body should render under the plugins ShadowRoot. Open Settings, Daemon Status, and Session Overview and confirm they remain in the Light DOM. EnablingshadowDom.portalsshould remain the only way to move dialogs, dropdowns, and other portal content into a ShadowRoot.With #7572 present, open
/agentsand its create/edit flow; both the manager and nested form should remain in the same plugins ShadowRoot.Evidence (Before & After)
Before: only the unified Plugins page body was isolated; compatibility pages opened by slash commands rendered in the Light DOM.
After: the unified page and all plugin-management compatibility pages share the same opt-in Shadow DOM behavior, while unrelated panels and portals retain their existing behavior.
Tested on
Environment (optional)
Local standalone Web Shell via
npm run dev:daemon; 183 targeted Vitest tests, Web Shell typecheck, build, lint, and formatting checks passed.Risk & Scope
Linked Issues
Related to #7572.
中文说明
本 PR 做了什么
扩展现有的
shadowDom.plugins选项,使它隔离所有插件管理界面,包括统一 Plugins 页面以及通过/extensions、/mcp、/skills打开的兼容页面。同时预先识别 #7572 引入的agents面板,使该改动合入后 Agents 管理页及其内部的创建/编辑页面使用同一个 Shadow DOM 边界。为什么需要
使用方可以为统一 Plugins 页面启用 Shadow DOM 隔离,但通过斜杠命令打开相同管理功能时,页面目前仍渲染在宿主页的 Light DOM 中。这会导致同一管理界面因打开方式不同而具有不一致的样式隔离行为。
Reviewer 测试计划
验证方式
使用
shadowDom={{ plugins: true, portals: false }}嵌入 Web Shell。打开统一 Plugins 页面,然后分别执行/extensions manage、/mcp和/skills details;每个管理页面主体都应渲染在 plugins ShadowRoot 中。打开 Settings、Daemon Status 和 Session Overview,确认它们仍在 Light DOM 中。只有启用shadowDom.portals时,弹窗、下拉菜单等 portal 内容才应进入 ShadowRoot。在包含 #7572 的代码上打开
/agents及其创建/编辑流程;管理页和内部表单应始终位于同一个 plugins ShadowRoot 中。前后对比证据
修改前:只有统一 Plugins 页面主体被隔离,通过斜杠命令打开的兼容页面渲染在 Light DOM 中。
修改后:统一页面和所有插件管理兼容页面共享相同的可选 Shadow DOM 行为,无关面板和 portal 保持原有行为。
测试环境
环境(可选)
通过
npm run dev:daemon启动本地 standalone Web Shell;183 个定向 Vitest 测试、Web Shell 类型检查、构建、lint 和格式检查均通过。风险与范围
关联 Issue
关联 #7572。