diff --git a/README.md b/README.md index 6a20a532..d3571cc8 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,7 @@ - [架构深度对比](./docs/comparison/architecture-deep-dive.md) — 10 Agent 代理循环 + Mermaid 图 - [功能性内部机制](./docs/comparison/functional-internals.md) — API 参数、编辑格式 - [/review](./docs/comparison/review-command.md) | [/security-review](./docs/comparison/security-review-command-deep-dive.md) | [/compact /plan /init](./docs/comparison/key-commands-deep-dive.md) | [/loop /schedule](./docs/comparison/loop-schedule.md) | [/simplify](./docs/comparison/simplify-command.md) -- [/hooks /model /mcp](./docs/comparison/infra-commands.md) | [/btw /rewind](./docs/comparison/btw-rewind.md) | [/context 自动化诊断](./docs/comparison/context-usage-noninteractive-deep-dive.md) | [内置命令总览](./docs/comparison/slash-commands-deep-dive.md) +- [/hooks /model /mcp](./docs/comparison/infra-commands.md) | [/btw /rewind](./docs/comparison/btw-rewind.md) | [插件 Marketplace 生命周期](./docs/comparison/plugin-marketplace-lifecycle-deep-dive.md) | [/context 自动化诊断](./docs/comparison/context-usage-noninteractive-deep-dive.md) | [内置命令总览](./docs/comparison/slash-commands-deep-dive.md) diff --git a/docs/comparison/plugin-marketplace-lifecycle-deep-dive.md b/docs/comparison/plugin-marketplace-lifecycle-deep-dive.md new file mode 100644 index 00000000..3c8ace8a --- /dev/null +++ b/docs/comparison/plugin-marketplace-lifecycle-deep-dive.md @@ -0,0 +1,366 @@ +# Qwen Code 改进建议 — 插件 Marketplace 生命周期管理 (Plugin Marketplace Lifecycle) + +> 核心洞察:Qwen Code 已经具备扩展安装与 marketplace 解析基础,能够兼容 Claude/Gemini 扩展格式,也能从 GitHub、本地路径、npm 等来源安装扩展;但 Claude Code 在此之上又构建了一整套“Marketplace 生命周期管理”系统:声明层与状态层分离、启动期后台 reconcile、自动更新、企业策略阻断、缓存与刷新、UI 管理闭环。两者的差距不在“能不能装插件”,而在“是否已经把插件生态做成一个可运维、可治理、可灰度演进的平台子系统”。 +> +> 返回 [改进建议总览](./qwen-code-improvement-report.md) + +## 一、问题定义:插件系统不只是在本地加载目录 + +当 Agent 从“可扩展工具”演进为“可分发平台”时,核心问题很快不再是: +- 能不能加载一个本地插件目录? +- 能不能识别一个 manifest? + +而变成: + +| 生命周期阶段 | 真实问题 | +|-------------|----------| +| 声明 | 哪些 marketplace 来源是被允许和启用的? | +| 安装 | 插件和 marketplace 如何在启动时自动补齐,而不是要求用户手动操作? | +| 更新 | marketplace 变了以后,插件何时跟着更新?是否需要重启? | +| 治理 | 企业策略如何阻止某些插件或来源? | +| 缓存 | 离线时怎么工作?更新失败后如何回退? | +| UI/CLI | 用户如何浏览、管理、移除、刷新、确认状态? | + +也就是说,真正成熟的 marketplace 系统不是“扩展安装器”,而是: + +> **插件分发 + 同步 + 更新 + 策略治理 + 用户界面的一体化生命周期系统。** + +这正是 Claude Code 相对于 Qwen Code 的一个明显平台化差距。 + +--- + +## 二、Claude Code 的做法:把 marketplace 当作一个长期运行的状态系统 + +Claude Code 在插件生态上最值得注意的,不是“有 marketplace”,而是它把 marketplace 分成了多层次状态,并围绕这套状态构建后台运维逻辑。 + +### 1. `marketplaceManager.ts`:声明层(intent)与状态层(materialized state)分离 + +`utils/plugins/marketplaceManager.ts` 的开头注释已经把它的职责写得非常清楚: +- 管理已知 marketplace sources +- 本地缓存 marketplace manifests +- 从 marketplace entry 安装插件 +- 跟踪并更新 marketplace 配置 + +更关键的是,它明确管理两层不同语义的数据: + +1. **Declared marketplaces**:用户/项目/隐式默认源“声明了哪些 marketplace 应该存在” +2. **Known marketplaces config**:当前磁盘上实际 materialized 的 marketplace 状态 + +源码里甚至直接出现了 `DeclaredMarketplace` 类型与 `getDeclaredMarketplaces()`: +- 支持 implicit official marketplace +- 支持 `sourceIsFallback` +- 支持从 merged settings 和 `--add-dir` 推导 marketplace intent + +这意味着 Claude 的设计不是“读一个配置文件然后直接装插件”,而是: + +> **先确定系统“应该拥有”的 marketplace 集合,再拿它和磁盘真实状态做 diff 与 reconcile。** + +这是平台化系统常见的控制面设计。 + +### 2. 启动期后台 reconcile:`PluginInstallationManager.ts` + +Claude 在 `services/plugins/PluginInstallationManager.ts` 中又向前走了一步: + +- 启动时计算 declared vs materialized 的差异 +- 对缺失或 source changed 的 marketplace 做后台安装 +- 安装过程通过 `onProgress` 映射到 AppState +- 安装成功后自动 refresh active plugins +- 若只是更新则标记 `needsRefresh` + +这个流程有几个很重要的产品含义: + +1. **用户无需手动补齐 marketplace** + 只要 settings / seed dir / implicit declaration 指向了一个 marketplace,系统会尝试在后台使真实状态收敛。 + +2. **UI 能展示 marketplace 安装状态** + `pending / installing / installed / failed` 这种状态流,不是 loader 层能天然提供的,而是系统专门设计出来的。 + +3. **更新与首次安装被区别对待** + 新 marketplace 可能触发自动 refresh;已存在 marketplace 更新则可能只提示 needsRefresh。 + +这已经非常接近“包管理器 + 控制平面”的感觉,而不是简单的插件扫描器。 + +### 3. 自动更新:`pluginAutoupdate.ts` + +Claude 还有一层非常平台化的机制:后台自动更新。 + +`utils/plugins/pluginAutoupdate.ts` 明确实现了: +- 先更新 marketplace +- 再更新这些 marketplace 上已安装的 plugins +- 按 marketplace 的 `autoUpdate` 配置控制行为 +- 记录 pending notification +- 启动时静默执行,不阻塞用户交互 + +这里的设计非常成熟: + +- marketplace 的更新不是孤立动作,而会传导到其上的插件版本 +- autoUpdate 可按 marketplace 配置,而不是全局粗暴开关 +- 更新结果会转化成用户可见通知 / restart-needed 状态 + +换句话说,Claude 的 marketplace 不是“静态目录索引”,而是一个会持续维护自身一致性的动态系统。 + +### 4. 企业策略治理:`pluginPolicy.ts` + +`utils/plugins/pluginPolicy.ts` 的实现虽然短,但战略价值很高: + +```ts +export function isPluginBlockedByPolicy(pluginId: string): boolean { + const policyEnabled = getSettingsForSource('policySettings')?.enabledPlugins + return policyEnabled?.[pluginId] === false +} +``` + +这说明 Claude 把插件治理纳入了 managed settings / policy settings 体系: +- 某些插件可被组织策略强制禁用 +- 阻断不仅影响 UI,还会作用到安装和启用 chokepoint + +这类能力对个人用户未必立刻可见,但对企业环境非常关键: +- 允许哪些插件来源 +- 哪些插件能装、能启用 +- 哪些 marketplace 可 auto-update +- 如何在组织层做统一控制 + +### 5. UI 管理闭环:`ManageMarketplaces.tsx` + +`commands/plugin/ManageMarketplaces.tsx` 表明 Claude 不是只有后端状态系统,还有完整的管理界面: +- 加载 marketplace 及其已安装 plugins +- pending update / pending remove +- applyChanges +- refresh/remove/autoupdate 管理 +- graceful degradation 加载 marketplace 数据 + +这让 marketplace 成为真正可操作的产品功能,而不是隐藏在配置和磁盘里的实现细节。 + +**Claude Code 关键源码**: +- `utils/plugins/marketplaceManager.ts` +- `services/plugins/PluginInstallationManager.ts` +- `utils/plugins/pluginAutoupdate.ts` +- `utils/plugins/pluginPolicy.ts` +- `commands/plugin/ManageMarketplaces.tsx` + +--- + +## 三、Qwen Code 现状:已具备安装与转换能力,但生命周期管理仍偏“安装器” + +Qwen Code 并不是没有 marketplace 相关能力。事实上,它已经有一套相当不错的扩展系统基础。 + +### 1. `marketplace.ts`:安装源解析能力已经存在 + +`packages/core/src/extension/marketplace.ts` 显示,Qwen 已经支持相当丰富的安装来源处理: +- `:` 解析 +- Git URL +- owner/repo 自动转 GitHub URL +- scoped npm package +- 本地路径 +- GitHub `.claude-plugin/marketplace.json` 获取 + +这说明 Qwen 并不是“只能本地 link 扩展”,而是已经在做 marketplace source parsing。 + +从能力层面说,这一步已经超过了很多只支持本地扩展目录的工具。 + +### 2. `extensionManager.ts`:扩展容器能力很强 + +`packages/core/src/extension/extensionManager.ts` 进一步说明,Qwen 的 extension runtime 其实很完整: +- MCP servers +- context files +- settings +- commands +- skills +- agents +- hooks +- channels +- Claude/Gemini 格式转换 + +这意味着 Qwen 的“扩展内容模型”并不弱,甚至相当丰富。它并非只是装一个工具,而是可以装进一整套扩展能力包。 + +### 3. `extensionSettings.ts`:敏感配置处理已经具备基础 + +Qwen 在 `extensionSettings.ts` 中还支持: +- user / workspace scope +- `.env` 文件存储 +- sensitive setting 使用 keychain 存储 +- 安装/更新过程中提示用户填写设置 + +这说明 Qwen 在“扩展配置落地”上也已经考虑到了安全性与多 scope 管理。 + +### 4. 但缺的不是“安装”,而是“持续管理” + +问题在于,和 Claude 相比,Qwen 当前更像是: +- 有一个强大的 extension manager +- 有 marketplace source parsing +- 有设置与转换 + +但还没有明显形成 Claude 那种: +- declared vs materialized marketplace diff +- 启动期后台 reconcile +- marketplace → plugin 自动更新传导 +- policy-backed plugin blocking +- `needsRefresh` / pending status 的完整生命周期状态模型 +- 面向 marketplace 本体的长期管理 UI/后台作业 + +所以更准确地说,Qwen 当前处于: + +> **扩展安装器/运行时成熟,但 marketplace 生命周期控制平面尚未完整产品化。** + +--- + +## 四、差距本质:从“可安装扩展”到“可运维平台”的最后一段路 + +| 维度 | Claude Code | Qwen Code | +|------|-------------|-----------| +| 多来源 marketplace/source 解析 | 有 | 有 | +| 扩展容器能力 | 有 | 有 | +| Marketplace 声明层 vs 状态层分离 | 明确存在 | 未见同等级设计证据 | +| 启动期后台 reconcile | 有 | 未见同等级证据 | +| Marketplace auto-update → plugin update 联动 | 有 | 未见同等级证据 | +| 企业策略阻断 | 有 `pluginPolicy.ts` | 未见同等级 chokepoint | +| 管理界面中的 pending/update/remove 生命周期 | 有 | `/extensions` 为主,生命周期治理较弱 | + +因此这里的差距,不能简单说成“Qwen 没有 marketplace”。更准确的表述应是: + +> **Qwen 已经有 marketplace/source parsing 与 extension runtime,但尚未像 Claude 那样把 marketplace 做成一个可持续收敛、自动更新、带策略治理的生命周期系统。** + +这类差距特别值得写成单独 deep-dive,因为它能解释一个现实现象: + +- 同样叫“插件/扩展系统” +- 有的工具只是能安装扩展 +- 有的工具已经在做插件平台运营基础设施 + +Claude 明显更接近后者。 + +--- + +## 五、Qwen Code 的改进路径 + +### 阶段 1:引入 marketplace 声明层与 materialized state + +Qwen 目前已有 install metadata 和 source parsing,下一步可以补一层: + +- `declaredMarketplaces`:用户/项目/内置源声明希望存在的 marketplace +- `knownMarketplaces`:磁盘已 materialize 的 marketplace 状态 + +然后用 diff/reconcile 的方式管理,而不是把“安装 marketplace”仅当作一次性命令动作。 + +### 阶段 2:启动期后台 reconcile + +启动时执行: +1. 读取声明层 +2. 读取本地 materialized 状态 +3. 对缺失项后台安装/同步 +4. 对 source changed 项执行刷新 +5. 将结果映射到 UI 状态(pending/installing/failed/needsRefresh) + +这样用户就不必手工追踪: +- 哪个 marketplace 缺了 +- 哪个 source 改了 +- 哪些扩展还没 refresh + +### 阶段 3:把 auto-update 提升到 marketplace 级 + +当前 Qwen 若继续强化生态,最自然的路径是: +- 允许按 marketplace 配置 `autoUpdate` +- marketplace 更新后,追踪受影响的 installed extensions +- 标记 restart-needed 或 needsRefresh + +这样才能把“来源变化”真正转化为“插件状态变化”。 + +### 阶段 4:补企业治理 chokepoint + +若 Qwen 未来继续面向团队/企业扩展生态,就需要类似的治理能力: +- 允许来源白名单 +- 插件 ID 阻断 +- managed settings 控制哪些插件可以启用/自动更新 +- 审计 marketplace 变更来源 + +否则扩展生态会越来越难控。 + +### 阶段 5:把 `/extensions` 从管理器提升为生命周期面板 + +当前 Qwen 的 `/extensions` 更偏安装/启停/查看。下一步可以演进为: +- marketplace 列表与状态 +- 更新可用性 +- source 变化 +- pending action +- needsRefresh +- auto-update policy + +也就是从“扩展管理命令”升级为“扩展运维面板”。 + +--- + +## 六、为什么这个改进点值得优先补齐 + +这个题目看起来不像 `/security-review`、`/voice` 那样直观,但它有几个很强的优先级理由: + +### 1. 它影响的是整个生态速度 + +一旦插件/扩展生态起来,最大瓶颈往往不是写一个插件,而是: +- 怎么分发 +- 怎么升级 +- 怎么阻断风险插件 +- 怎么管理来源 + +生命周期能力补齐后,Qwen 扩展生态的可持续性会明显提升。 + +### 2. Qwen 已经有了很好的地基 + +这不是从 0 开始: +- `marketplace.ts` 已有来源解析 +- `extensionManager.ts` 已有完整扩展容器 +- `extensionSettings.ts` 已有配置/敏感信息管理 + +所以这类改进更像“从 0.6 到 0.9 的平台化补强”,而不是纯新功能开发。 + +### 3. 对企业用户特别重要 + +个人用户可以接受“手工装扩展”;但一旦进入团队场景,必然会问: +- 谁批准了这个插件? +- 为什么它自动更新了? +- 能否组织级禁用? +- marketplace 改了后客户端如何收敛? + +Claude 已经开始回答这些问题,Qwen 目前还主要停留在运行时与安装层。 + +--- + +## 七、结论 + +Qwen Code 与 Claude Code 在插件生态上的差距,已经不只是“有没有 marketplace”或“能不能安装扩展”。 + +Qwen 已经拥有: +- 多来源解析 +- 扩展容器 +- 设置与敏感配置处理 +- Claude/Gemini 格式兼容 + +但 Claude 又多走了一步,把 marketplace 做成了: +- 有声明层与状态层 +- 启动期自动 reconcile +- marketplace 与 plugin 更新联动 +- 带 policy blocking 的治理体系 +- 可在 UI 中完整管理的生命周期系统 + +因此这个改进点最值得强调的不是“补一个 marketplace”,而是: + +> **把 Qwen 的扩展能力从“安装器 + 运行时”升级为“可治理、可更新、可收敛的平台生命周期系统”。** + +这会比单纯再加几个官方插件,更深刻地提升 Qwen Code 的生态成熟度。 + +--- + +## 关键源码索引 + +### Claude Code +- `utils/plugins/marketplaceManager.ts` +- `services/plugins/PluginInstallationManager.ts` +- `utils/plugins/pluginAutoupdate.ts` +- `utils/plugins/pluginPolicy.ts` +- `commands/plugin/ManageMarketplaces.tsx` + +### Qwen Code +- `packages/core/src/extension/marketplace.ts` +- `packages/core/src/extension/extensionManager.ts` +- `packages/core/src/extension/extensionSettings.ts` +- `docs/users/extension/getting-started-extensions.md` + +> **免责声明**:以上结论基于 2026-04 本地源码与当前仓库文档对比,后续版本可能已变更。 \ No newline at end of file diff --git a/docs/comparison/qwen-code-improvement-report.md b/docs/comparison/qwen-code-improvement-report.md index d4ad8a48..ed4c6f04 100644 --- a/docs/comparison/qwen-code-improvement-report.md +++ b/docs/comparison/qwen-code-improvement-report.md @@ -224,6 +224,7 @@ | **P3** | [上下文折叠](./context-compression-deep-dive.md) — History Snip(Claude Code 自身仅 scaffolding,未完整实现) [↓](./qwen-code-improvement-report-p3.md#item-2) | 缺失 | 大 | — | | **P3** | [内存诊断](./memory-diagnostics-deep-dive.md) — V8 heap dump + 1.5GB 阈值触发 + leak 建议 + smaps 分析 [↓](./qwen-code-improvement-report-p3.md#item-3) | 缺失 | 中 | — | | **P3** | [Feature Gates](./feature-gates-deep-dive.md) — GrowthBook 远程特性开关 + A/B 测试 + 按事件动态采样 [↓](./qwen-code-improvement-report-p3.md#item-4) | 缺失 | 中 | — | +| **P3** | [插件 Marketplace 生命周期](./plugin-marketplace-lifecycle-deep-dive.md) — 声明层/状态层、后台 reconcile、自动更新与策略治理 | lifecycle 管理较弱 | 中 | — | | **P3** | DXT/MCPB 插件包 — zip bomb 防护(512MB/文件,1GB 总量,50:1 压缩比限制) [↓](./qwen-code-improvement-report-p3.md#item-5) | 缺失 | 中 | — | | **P3** | [/security-review](./security-review-command-deep-dive.md) — 基于 git diff 的安全审查命令,聚焦漏洞检测 [↓](./qwen-code-improvement-report-p3.md#item-6) | 缺失 | 小 | — | | **P3** | Ultraplan — 启动远程 CCR 会话,用更强模型深度规划后回传结果 [↓](./qwen-code-improvement-report-p3.md#item-7) | 缺失 | 大 | — |