qwen-code Extension Skill 所有者身份模型:extensionName 与 extensionDisplayName 契约详解 qwen-code Extension Skill 所有者身份模型extensionName 与 extensionDisplayName 契约详解【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code导读qwen-code 通过GET /workspace/skills向 ACP 客户端IDE 集成、TypeScript SDK、Web Shell 等暴露工作区中可用的 Skill 列表。对于由 Extension 提供的 Skill该接口需要同时满足两个诉求客户端能够稳定地建立 Skill 与 Extension 的归属关系身份又能拿到适合人类阅读的友好名称展示。本文围绕 extension-skill-owner-identity 设计文档 展开剖析 qwen-code 如何通过extensionName规范身份与extensionDisplayName本地化展示名双字段模型解决身份混淆问题并深入到packages/core的 Skill 管理器、ACP Bridge 与 TypeScript SDK 的类型投影实现帮助你理解该契约的边界与兼容性约束。问题背景display name 为什么不能当身份用在引入本设计之前GET /workspace/skills返回的extensionName字段实际存放的是 Extension 的本地化展示名localized display name而不是 Extension 清单manifest中的规范name。这个做法在两个维度上是有问题的随 locale 漂移同一个 Extension 在不同语言环境下会解析出不同的 display name客户端无法把一个 Skill 稳定地归属到其 Extension不具备唯一性展示名是给人看的两个 Extension 完全可能撞名客户端拿到重名后无法区分。从源码看Extension 的规范身份正是其 manifest 中的name。Skill 管理器的注册与枚举都以extension.name为准并将两个字段显式分离记录见 skill-manager.tsskills.push({ ...skill, name: qualifySkillName(extension.name, skill.name), authoredName: skill.name, extensionName: extension.name, extensionDisplayName: extension.displayName, priority: hasInvalidPriority ? 0 : (skill.priority as number | undefined), });其中qualifySkillName(extension.name, skill.name)生成形如extensionName:authoredName的注册表身份从而保证两个 Extension 即使都发布名为pdf的 Skill也能在/skills列表中产生两个可区分的名字见 types.ts。契约定义双字段的职责划分设计文档将所有权信息收敛为两个可选字段职责严格分离字段含义用途是否可作身份extensionNameExtension manifest 中的规范name身份匹配、非活跃态检查、快照去重✅ 唯一权威extensionDisplayName可选、按 locale 解析出的展示名展示层友好标签❌ 仅展示契约中的关键约束如下身份匹配、非活跃态检查、快照去重一律只使用extensionName展示层统一采用extensionDisplayName ?? extensionName的回退表达式——有展示名用展示名没有就回退到规范名两个字段都保持可选optional原因有二非 Extension 来源的 Skill 没有所有者较老版本的 daemon 不输出extensionDisplayName状态statusschema维持在 version 1因为新字段是纯增量additive的不破坏既有消费者。在核心类型定义中extensionName被注释为 “the canonical name of the providing extension”而extensionDisplayName被明确标注为 “Presentation only; never use this field as an identity”见 types.ts与契约一一对应。数据流从 Extension 枚举到 ACP/TypeScript SDK 状态类型整条链路分三步走Skill 管理器记录SkillManager在枚举活跃activeExtensions 时从每个 extension 的 manifest 同时取出name与displayName写入extensionName/extensionDisplayNameskill-manager.tsACP 工作区快照合成当从非活跃inactiveExtensions合成 Skill 时应用同样的规则——即extensionName取规范名、extensionDisplayName取展示名保证活跃与不活跃两条路径行为一致共享映射器投影共用的 workspace-skills mapper 将这两个值投影进 ACP Bridge 与 TypeScript SDK 的状态类型中保证两个 SDK 面看到的字段语义完全一致。从仓库源码可以确认这一投影确实落地到了客户端侧类型ACP Bridge 状态类型中同时存在extensionName与extensionDisplayName见 packages/acp-bridge/src/status.tsTypeScript SDK 的 daemon 类型同样投影了这两个字段见 packages/sdk-typescript/src/daemon/types.ts。CLI 与 Web Shell 的展示层则读取展示字段并按extensionDisplayName ?? extensionName回退而 MCP 与 Agent 的所有权元数据属于独立契约本次改动不触碰边界划分清晰。兼容性策略旧客户端与新客户端的双赢设计文档明确了三层兼容性保证现有第三方客户端继续收到extensionName但值从展示文本被纠正为manifest 身份——这是行为修正而非破坏性变更字段名不变需要友好标签的客户端可以主动采用extensionDisplayName并在其缺失时回退到extensionName新客户端面向老版本 daemon 时由于extensionDisplayName缺失同样以extensionName兜底天然兼容。测试用例印证了这一行为在 skill-manager.test.ts 中断言同时校验了extensionNamealibabacloud-database-suite与extensionDisplayName的取值确保身份字段承载的是规范名而非展示名。实践建议客户端接入要点对于基于 qwen-code daemon 开发 ACP 客户端或集成方的读者本契约带来的实操结论可以归纳为四点永远不要用 display 类字段做匹配键无论是 Skill 与 Extension 的 join、非活跃状态的判定还是快照去重一律以extensionName为准展示名一律走回退表达式extensionDisplayName ?? extensionName保证老 daemon 与无主 Skill字段缺失场景下 UI 不出现空标签schema 版本无需升级extensionDisplayName是增量字段status schema 保持 version 1消费方无需因该字段做版本协商区分契约边界MCP 工具、Agent 的所有权元数据与 Extension Skill 的所有权是两套独立契约不要混用字段做跨域推断。总结extensionNameextensionDisplayName的双字段模型是 qwen-code 在 机器可用的身份 与 人可读的展示 之间做的一次干净切分规范名承载唯一性与稳定性展示名承载可读性两者通过??回退优雅衔接并以纯增量字段保证 schema 与旧客户端双兼容。对于任何消费GET /workspace/skills的客户端牢记 身份只看extensionName 这一原则即可避免本地化与重名带来的归属错乱。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考