资讯详情

qwen-code Web Shell @ 提及图标芯片(mention icon chips)机制解析与验证指南

📅 2026/9/10 13:41:41 | 华诺云谱 👁 阅读
qwen-code Web Shell @ 提及图标芯片(mention icon chips)机制解析与验证指南
qwen-code Web Shell 提及图标芯片mention icon chips机制解析与验证指南【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code本篇文章围绕 qwen-code 仓库中 .qwen/e2e-tests/webshell-mention-icon-chips.md 这份验证文档展开系统讲解 Web Shell 输入框内提及mention功能如何把插入的引用文本渲染为带内置图标的 inline chip 标签、如何通过composerTagIcons注册自定义图标以及相关的安全回归约束与可复现的验证方法。读完本文你将掌握内置/自定义提及 chip 的渲染链路、图标解析与 CSS 转义的安全边界并能在本地直接运行文档所列的测试与构建命令进行验证。一、验证文档要解决的问题在 Web Shell 的 composer 输入框中输入会唤起提及at-mention菜单用于引用扩展extension、文件file、MCP 资源MCP resources以及 skill 等对象。选择某个候选项后输入框里不应出现一段生硬的纯文本例如ext:...、mcp:...或文件引用路径而应当插入一个内联 composer 标签inline composer tag一个带有图标、标签、值与可删除按钮的视觉芯片。该验证文档围绕三个测试组展开Built-in mention chips内置提及芯片接受扩展、文件或 MCP 的提及后编辑器插入原始序列化文本并附着内联 composer 标签可见结果是一个带内置图标的内联 chip而不是ext:...、mcp:...或文件引用纯文本。Custom mention chips自定义提及芯片注册一个atProvider其候选项提供composerTag.kind table并向WebShell传入composerTagIcons{{ table: icon-url }}接受该候选项后应插入 provider 提供的insertText并使用注册的 table 图标渲染内联 chip。Regression coverage回归覆盖自定义图标查找必须忽略继承的对象属性未注册自定义图标时内置图标仍能正常解析图标 URL 在写入 CSS 自定义属性前必须经过转义。最后一部分还记录了 2026-07-16 的一次内置 SVG data URI 回归基线版本0.18.5-preview.0用于验证四个内置图标extension、file、MCP、skill在内联 composer 标签、顶部 composer 标签和已提交用户消息标签三种表面上的掩码节点渲染是否正常以及任意 SVG data URI 和javascript:自定义图标 URL 是否仍被排除在 DOM 之外。二、从「纯文本」到「图标 chip」内联标签渲染链路2.1提及解析与菜单状态机用户键入后useAtMentionMenuHook 负责解析当前光标处的提及查询并管理菜单状态。其核心入口是parseAtMention正则AT_PATTERN /((?:[\p{L}\p{N}_./:-]|\\.)*)$/u负责匹配光标前最后一个开始的片段并校验前一个字符必须是空白或[\s([{]之一避免误触例如邮箱地址中的。详见 useAtMentionMenu.ts。菜单状态机包含categories与items两级categories层展示所有可用 provider内置的 files / extensions / mcp-resources以及宿主注册的自定义 provideritems层展示当前 provider 的候选项支持 150ms 防抖SEARCH_DEBOUNCE_MS 150、AbortController 取消过期请求以及内置 provider 的结果缓存。内置 provider 通过createFileProvider、createExtensionProvider、createMcpResourcesProvider构造并可用WebShellBuiltinAtProvidersConfig控制启用/禁用支持布尔值、ID 数组或{ enabled, include, exclude }三种形态见 useAtMentionMenu.ts 与 customization.tsx。2.2 候选项到 composer tag 的转换每个候选项的类型是WebShellAtItem其中composerTag?: WebShellComposerTag字段携带了选中后要创建的标签数据。WebShellComposerTag的核心结构为见 customization.tsxexport interface WebShellComposerTag { id: string; label?: string; // chip 中带主题色的标签文本 value?: string; // chip 中的主文本如文件路径 removable?: boolean; // 是否允许删除默认可删除 kind?: WebShellComposerTagKind; // 用于图标解析extension | file | mcp | skill | 自定义字符串 icon?: WebShellIconSource; metadata?: unknown; serialized?: string; // 提交时真正写回文本流的序列化内容 }其中WebShellComposerTagKind为extension | file | mcp | skill | (string {})即内置四类之外还允许任意自定义字符串见 customization.tsx这正是文档中composerTag.kind table自定义场景的类型基础。选中候选项后useAtMentionMenu会调用createComposerTagForItem生成标签并把原始插入文本insertText写入编辑器同时通过createInlineTagEffect效果StateEffect通知 composer 在该文本对应的文档区间上挂载内联标签装饰。相关实现见 useComposerCore.ts 中的addInlineTagEffect/removeInlineTagEffect/clearInlineTagsEffect。2.3 CodeMirror 装饰层与 chip 的 DOM 结构Web Shell 的 composer 基于 CodeMirror 6 构建。内联 chip 是通过StateFieldDecoration.replace实现的inlineComposerTagField维护一个DecorationSetaddInlineTagEffect把ComposerTagWidget作为替换装饰挂到对应区间上并同时注册为EditorView.atomicRanges保证光标移动与编辑不会“穿过” chip 内部见 useComposerCore.ts。ComposerTagWidget.toDOM负责把标签渲染成 chip DOM关键渲染步骤包括解析图标const iconUrl this.tag.iconUrl ?? getComposerTagIconUrl(this.tag.kind)安全校验仅当isBuiltinComposerTagIconUrl(iconUrl) || isSafeImageSrc(iconUrl)时才使用该 URL否则不渲染图标safeIconUrl为undefined构造图标节点一个 12×12 的span使用background: currentColor配合mask: var(--composer-tag-icon-url) center / contain no-repeat含-webkit-mask渲染图标 URL 通过cssUrlValue(safeIconUrl)写入--composer-tag-icon-url自定义属性附加默认内容label value超出max-width:32ch省略、tooltip可选与删除按钮×removable ! false时。上述逻辑见 useComposerCore.ts。也正是“mask 节点icon mask node”一词的来源图标本质上是把 SVG 当作 CSS mask 画在 chip 内部的节点上。2.4 提交时inline chip 如何还原成文本发送消息时buildComposerPromptWithInlineTagPlacements会把文档中的内联标签区间替换回序列化文本replaceInlineTagPlacements按区间排序后逐段重组文本再与顶部标签一起拼装 prompt见 useComposerCore.ts。也就是说chip 只是编辑时的视觉投影提交时仍还原为serialized文本默认回退顺序为serialized - value - label - id见 composerTag.ts。同时createInputAnnotationsFromComposerTags会为每个标签生成DaemonInputAnnotation类型为reference携带id、kind、label、value、metadata、serialized、removable供会话记录层在用户消息中继续渲染 chip见 composerTag.ts。三、自定义图标composerTagIcons与atProvider的配合3.1 定制入口与类型定义宿主host可以在WebShellCustomization中声明composerTagIcons?: WebShellComposerTagIconMap类型为ReadonlyRecordstring, string即「标签 kind → 图标 URL」的映射见 customization.tsx 与 customization.tsx。文档给出的用法是composerTagIcons{{ table: icon-url }}同时注册一个自定义atProvider其候选项的composerTag.kind设为table{ id: my-tables, label: Tables, search: async ({ query, signal }) [ { id: table:orders, label: orders, insertText: table:orders , composerTag: { id: table:orders, kind: table, value: orders }, }, ], }接受该候选项后composer 会插入insertText即table:orders并把标签解析为 inline chip——此时kind table在内置图标表中不存在于是回退到composerTagIcons[table]注册的图标。3.2 图标解析顺序与安全边界图标解析集中在 composerTag.tsgetOwnIconUrl(iconUrls, kind)使用Object.prototype.hasOwnProperty.call(iconUrls, kind)严格检查自身属性这正是文档回归项中「自定义图标查找忽略继承的对象属性」的实现保证——即使某个 kind 名称恰好与Object.prototype上的属性同名如constructor、toString也不会被错误命中getComposerTagIconUrl(kind, customIconUrls)的解析顺序为自定义图标映射优先其次内置图标映射builtinTagIconUrls内部包含 extension/file/mcp/skill 四个 SVG 资源isBuiltinComposerTagIconUrl通过内置图标 URL 的 Set 集合做白名单校验只有「内置图标」或「通过isSafeImageSrc校验的 URL」才会被写入 DOM 的 mask 节点。3.3 图标 URL 的 CSS 转义文档明确要求「icon URLs are escaped before being written into CSS custom properties」。由于图标 URL 最终会被写入 CSS 自定义属性--composer-tag-icon-url并作为url(...)使用URL 中若含引号、反斜杠、换行等字符可能破坏 CSS 语法甚至注入样式。cssUrlVar.ts中的cssUrlValue负责转义export function cssUrlValue(url: string): string { const escaped url.replace(/[\\\n\r\f]/g, (char) { switch (char) { case : case \\: return \\${char}; case \n: return \\A ; case \r: return \\D ; case \f: return \\C ; default: return ; } }); return url(${escaped}); }其测试用例cssUrlVar.test.ts验证了https://x.test/a\\\nb.svg被转义为url(https://x.test/a\\\\A b.svg)以及cssUrlVar(--icon-url, /icons/table.svg)生成{ --icon-url: url(/icons/table.svg) }。正是这一层转义配合isBuiltinComposerTagIconUrl || isSafeImageSrc的双重校验使文档中「任意 SVG data URI 和javascript:自定义图标 URL 不进入 DOM」的回归结论成立。四、内置 SVG data URI 回归验证2026-07-164.1 基线问题全局qwen --version基线为0.18.5-preview.0。修复前的 DOM 矩阵显示虽然四个内置图标都能解析为data:image/svgxmlURL但在内联 composer 标签、顶部 composer 标签和已提交用户消息标签三种表面上渲染出的icon mask 节点数量为零——即图标 URL 已解析但未实际渲染成可见图标。4.2 验证结论修复后的验证结果如下从菜单接受一个扩展项仍能在编辑器中插入kind: extension的内联标签内联 composer 标签、顶部 composer 标签、已提交用户消息标签三种表面均渲染出 extension、file、MCP、skill 四个图标 mask 节点任意 SVG data URI 与javascript:自定义图标 URL 在三种表面上均不出现于 DOM聚焦 WebShell 场景下 5 个文件共 128 个测试通过包含扩展接受路径按现有 lockfile 声明的依赖集安装后全仓库构建通过全仓库 typecheck 通过。这条回归与第一节提到的两个修复效果截图相互印证修复前内联 chip 上「Icon mask node: Missing」修复后变为「Icon mask node: Detected ✓」。五、本地验证方法命令与预期结果5.1 单元测试在packages/web-shell下运行提及菜单、composer 核心、图标解析与 CSS 转义四组测试cd packages/web-shell npx vitest run \ client/hooks/useComposerCore.test.ts \ client/hooks/useAtMentionMenu.test.tsx \ client/components/composerTagIcons.test.ts \ client/utils/cssUrlVar.test.ts预期结果通过涉及 4 个文件、80 个测试。需要说明的是当前仓库源码中图标解析逻辑位于 utils/composerTag.ts对应的测试文件为 composerTag.test.ts验证文档中记录的composerTagIcons.test.ts是编写验证时的既有文件清单useComposerCore.test.ts、useAtMentionMenu.test.tsx、cssUrlVar.test.ts均存在且可直接运行。5.2 ESLint 静态检查npx eslint \ packages/web-shell/client/customization.tsx \ packages/web-shell/client/components/composerTagIcons.ts \ packages/web-shell/client/components/composerTagIcons.test.ts \ packages/web-shell/client/components/ChatEditor.tsx \ packages/web-shell/client/hooks/useAtMentionMenu.ts \ packages/web-shell/client/hooks/useAtMentionMenu.test.tsx \ packages/web-shell/client/hooks/useComposerCore.ts \ packages/web-shell/client/hooks/useComposerCore.test.ts \ packages/web-shell/client/index.ts \ packages/web-shell/client/App.tsx \ packages/web-shell/client/utils/cssUrlVar.ts \ packages/web-shell/client/utils/cssUrlVar.test.ts预期结果全部通过。5.3 构建验证npm run build --workspacepackages/web-shell预期结果构建通过存在已有的 Vite large chunk 警告不影响结果。验证文档同时注明当前环境未进行人工浏览器截图行为覆盖停留在 hook 与渲染辅助函数边界包构建用于校验 web-shell bundle 本身。5.4 聚焦与全量验证回归场景针对 2026-07-16 回归聚焦 WebShell 结果为5 个文件、128 个测试通过包含扩展接受路径随后按现有 lockfile 声明的依赖集完成安装后全仓库构建与全仓库 typecheck 均通过。整个验证链路与文档中「Built-in SVG data URI regression」一节完全对应可作为该功能后续任何图标相关改动的回归基线。六、关键实现文件索引以下是本文引用的核心实现与测试文件便于深入阅读packages/web-shell/client/hooks/useAtMentionMenu.ts提及菜单状态机、provider 注册与候选项加载packages/web-shell/client/hooks/useComposerCore.tsCodeMirror 编辑器装配、内联标签装饰与 chip DOM 渲染、提交时文本还原packages/web-shell/client/utils/composerTag.ts标签序列化/反序列化、图标解析自定义优先、内置兜底、内置图标白名单packages/web-shell/client/utils/composerTag.test.ts标签解析与图标解析的单元测试packages/web-shell/client/utils/cssUrlVar.tsCSSurl(...)转义与自定义属性生成packages/web-shell/client/utils/cssUrlVar.test.tsCSS 转义与cssUrlVar的单元测试packages/web-shell/client/customization.tsxWebShellCustomization、WebShellComposerTag、WebShellComposerTagIconMap、WebShellAtProvider等公共类型定义.qwen/e2e-tests/webshell-mention-icon-chips.md本文依据的验证文档本体。七、小结Web Shell 的提及图标芯片功能本质上是「序列化文本 编辑期视觉投影」这一设计思想在 CodeMirror 装饰层上的落地选中候选项时写入原始文本并挂上替换装饰编辑期呈现为带图标/标签/删除按钮的 chip提交时再无损还原为文本同时以 input annotation 形式把标签语义传给会话记录层。自定义图标通过composerTagIcons按 kind 注册、优先于内置图标解析并受到「自身属性检查 内置白名单/安全图片源校验 CSS 转义」三重防护。验证文档及其背后 80/128 个测试用例为这一交互与安全边界提供了可复现的回归基线。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。