
DSH Community Market Shell 架构解析目录来源、npm 安装与卸载的职责边界【免费下载链接】deepseek-harness-desktop为 DeepSeek Harness (DSH) 插件生态打造的现代化桌面端解决方案。万物皆「插件」桌面本身也是「插件」。项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness-desktop本文聚焦 DSH Desktop 内建开源插件市场dsh-community-market的 Shell 架构它如何把「目录来源 - Host adapter - 标准化目录 - Market Client」这条浏览链路与「Profile 清单 - 已安装视图 - 不透明 bundleId - pnpm remove」这条操作链路组合在一起并在 Renderer 与 package-manager 之间建立不可逾越的信任边界。读完本文你将掌握市场模块的归属边界、来源/安装/卸载的运行时形态、可安装候选的准入规则、一次性 preview token 机制以及故障恢复的边界设计可直接对照 market-shell.zh.md 与同目录的安装卸载指南、目录提供方契约继续深入。一、Shell 的归属边界市场拥有什么、不拥有什么dsh-community-market是一个被内置于 DSH Desktop 的插件市场模块其英文文档自述状态为「已交付并内建于 DSH Desktop」。作为 Shell它严格划定自己的职责范围它拥有Ownership目录来源设置catalog-source settings的保存、选择与排序来源 adapter标准 HTTP adapter 与受审的 provider adapter标准化发现normalized discovery即把不同 provider 的 wire 格式统一为同一套目录模型Market Client 界面发现、可安装、已安装、来源四个视图npmlatestpreview 的解析Profile package 操作编排安装/卸载的 preview 与 execute 编排。它不拥有明确不属于市场模块Profile 存储由 Desktop 的 profile 服务负责pnpm 执行市场只调用desktopPnpm.run(argv)自己并不实现包管理器恢复 checkpoint由 Desktop 统一的健康启动 checkpoint 机制负责终端窗口openTerminal是 Desktop 的 desktopActions 能力重启实现requestRestart同样来自 Desktop 的 desktopActions。从源码入口 dsh-community-market/src/index.ts 可以看到这种「窄依赖注入」的写法模块声明inject [webServer, settings]然后通过ctx.inject([desktopProfiles, desktopPnpm], ...)等注入声明可选的 Desktop 能力——只有当desktopProfiles、desktopPnpm、desktopPlugins、desktopActions这些窄能力存在时package 操作才会被创建浏览能力则保持可移植不依赖它们。二、Runtime 形态两条链路、一个原则文档给出的运行时形态是文章理解整个市场最核心的图景目录来源 - Host adapter - 标准化目录 - Market Client | - npm latest preview Desktop Profile 清单 - 已安装视图 - 不透明 bundleId - pnpm remove这条链路蕴含一个贯穿全文的安全原则ClientRenderer只接收标准化数据和不透明 operation 身份永远不会获得 package-manager 能力。第一条链路负责「发现与安装」目录来源的数据在 Host 侧经 adapter 抓取、校验、标准化后才交给 ClientClient 若要安装只提交{ sourceRecordId, itemId }由 Host 解析自己此前观察到的标准化 npm package 身份再走 npmlatestpreview。第二条链路负责「已安装视图与卸载」Desktop 读取 Profile 的直接依赖与 bundle 清单为每个可移除依赖生成当前 generation 有效的不透明bundleIdRenderer 只提交bundleIdHost 重新解析后调用desktopPnpm.run([remove, packageName])。在 dsh-community-market/src/host/routes.ts 中可以印证这一点操作 preview 请求被严格限定为两种精确形状——{ action: install, sourceRecordId, itemId }或{ action: uninstall, bundleId }并且使用exactKeys拒绝任何多余字段标识符还必须通过boundedIdentifier1~240 字符、不含\0。Client 根本没有提交 package name 或包管理器命令的通道。三、来源行为有界本地索引与 provider 远程分页文档把来源行为分为两类1. 标准 cursor 来源与 dshfind扫描为有界本地索引搜索、分类筛选和可见分页都在这份有界索引上执行。dshfind 的 adapter 以per_page100抓取全部页面并记录一致的data_version遇到409 stale_data、版本不一致或遍历不完整时整次扫描失败绝不发布部分索引详见目录提供方契约的「与 dshfind 的合作」一节。由于匿名配额低每分钟 30 次、突发 10 次adapter 使用固定串行间隔不能通过并发绕过 provider 限制。2. DSH 1024Store直接使用 provider 的分页 v2 API发现页对所有查询包括无筛选目录都使用 provider 当前的/api/v2/plugins分页 API单分类筛选直接转发多分类 OR 筛选合并有界的 provider 排序前缀并隐藏在一个 Host 不透明 cursor 之后「可安装」视图每批请求 200 条远程 registry 记录只保留该 page 里的直接 npm 目标Client 通过下一枚不透明 cursor 继续加载Host 与 Renderer 都不会物化完整目录。在 dsh-community-market/src/host/routes.ts 中可以看到该行为的实现分支当activeSource的adapterId是DSHFIND_ADAPTER_ID或 1024Store 系 adapter 时走service.fetchProvider(query, signal, scope, { force })的远程分页路径否则走service.scanCatalog(...)的本地索引路径。两条路径都只向 Client 返回query results categories manualInstall fetchedAt分页状态由sourceRecordId与cursor限定routes.ts 会校验「一个 cursor 必须对应一个 source record」。关于 provider 命令的硬性规则来源可以提供目录身份但绝不能提供可执行 argv、凭据、adapter 代码、来源选择或安装权限。被审查的 1024Store adapter 只解析一种严格的惰性命令形状dsh plugin --profile … add npm-package来恢复 npm package name随后立即丢弃该命令绝不转发或执行。dshfind 的install.cmd同样在标准化前被丢弃。四、安装行为一次 preview、一次 execute、一个 npm 身份4.1 可安装条目的唯一贡献一个 npm package 身份可安装目录条目只贡献一个npm package 身份。安装 preview 解析 npm 官方 registry 的latestmanifest并要求同时满足npm package name 一致registry 返回的 name 与目录条目标准化的 name 相同版本精确且稳定exact stable version而非 range 或 tagdsh.bundle.patch声明合法安全、相对路径的 DSH bundle patch。4.2 一次性 preview token 机制Preview 把三件事绑定到一个短时一次性 token上上述验证事实name、exact version、合法 bundle patch已经观察到的目录条目{ sourceRecordId, itemId }当前 Profile 绑定。执行阶段只调用desktopPnpm.run(argv)即精确版本的pnpm add保存精确版本并 reconciledsh.profile.bundles。preview token 是一次性的一旦消费即失效如果 preview 之后 Profile 发生了变化Host 会拒绝执行防止「用户确认时的状态」与「执行时的状态」不一致。这一点在 dsh-community-market/src/host/routes.ts 有直接体现execute 请求体只允许{ previewId }一个键exactKeys(request, [previewId])其余字段一律拒绝。整个安装流程中 Renderer 从不发送 package name 或包管理器命令与安装卸载指南中「Renderer 只发送sourceRecordId和itemId」的描述完全对应。4.3 不设安装门槛的字段Market不再使用 receipt 或安装专用保护、恢复路径。以下字段明确不作为安装门槛来源版本provider 列出的版本永远不是安装目标版本权威是 npmlatest仓库匹配repository 是否一致不决定资格lifecycle script、deprecated 元数据、engine 范围provider 验证徽章。pnpm 负责按请求的精确 npm 版本完成解析与安装。安装失败也不会触发自动清理或回滚——这是刻意的设计见第六节故障边界。五、已安装清单与卸载跨市场兼容的不透明 bundleId5.1 清单来源Desktop 的已安装清单读取当前 Profile 的直接依赖和 bundle因此天然包含三类来源安装的插件本市场安装的插件其他市场安装的插件DSH CLI 安装的插件。已安装状态与当前目录来源无关也与最初由哪个市场安装无关——不需要任何特殊集成即可看到外部来源安装的插件。产品自有 bundle如dsh-plugin-desktop、dsh-plugin-desktop-beta、dsh-community-market自身只读其他直接插件依赖获得当前 generation 有效的不透明bundleId并且只提供卸载。5.2 卸载时序Desktop 读取 Profile 的dependencies与dsh.profile.bundles每个直接 bundle 获得当前 generation 有效的不透明bundleIdHost 在 preview 前解析bundleId确认它对应清单中的真实依赖执行前重新检查直接依赖防止确认后被移除或变化用户确认后Host 调用desktopPnpm.run([remove, packageName])并移除 bundle 引用。Host 侧对清单的校验是严格的dsh-community-market/src/host/routes.ts 中validDesktopBundle要求每个 bundle 恰好包含bundleId/packageName/status/mutable/uninstallable五个键bundleId必须唯一重复即拒绝数量上限 4096 条。市场不暴露启用或禁用操作——这进一步缩小了操作面避免出现超出「安装/卸载」之外的半吊子状态机。六、故障边界可浏览、不阻塞、不自动回滚文档对故障行为给出了非常明确的四条规定Desktop package 能力不可用时仍可浏览即使desktopPnpm/desktopProfiles能力缺失发现、搜索、详情等浏览功能照常工作这也是 src/index.ts 中「Browsing remains portable」注释的含义来源故障不会阻止 Desktop 启动目录 I/O 全部是惰性请求启动阶段不执行阻塞式 fetchPackage 操作错误不会触发自动清理或回滚pnpm 失败只保留有上限的 stdout/stderr 尾部、写入 Desktop 日志并展示失败弹窗弹窗提供 Host 推导的精确命令与「打开 DSH 终端」用于手动跟进但不重试已消费的确认Desktop 的三个健康启动 Profile checkpoint 是唯一恢复机制恢复仍然是恢复页面中的显式操作市场自己不做快照、重试或回滚。安装卸载指南用一张表汇总了失败行为故障结果无法解析 npm latest或它不是稳定 DSH 插件不启动 package 操作Preview 后 Profile 发生变化拒绝一次性 previewpnpm 失败报告错误Market 不自动清理或回滚pnpm 后 Profile reconcile 失败报告错误供诊断或显式恢复 checkpoint用户确认后 Renderer 关闭Host 持有的 package 操作继续仅可能丢失响应另外「修改成功后用户可以立即重启或稍后重启重启绝不会静默进行」——重启始终是显式用户操作。七、Headless 要求与发布门槛最后Shell 对自身的工程化边界有硬性约束合同生成、类型检查、单元测试、package build、export 验证和 Loader smoke test 都必须保持 headless-safe测试不得启动 Electron 或图形应用。这意味着市场核心逻辑契约校验、adapter、来源 registry、安装编排全部可以在纯 Node 环境验证也解释了仓库中大量.spec.ts测试文件如 tests/catalog-* 系列、tests/host-routes.spec.ts、tests/market-install.spec.ts、tests/market-runtime.spec.ts能够独立于桌面外壳运行的原因。八、从 Shell 到契约下一步阅读路径market-shell文档是理解市场整体职责的入口要落地实现或接入自己的目录来源建议按以下路径深入当前仓库安装与卸载细节install-and-uninstall.zh.md自动安装四条件、卸载五步骤、失败行为表目录提供方契约catalog-provider-contract.zh.mdmanifest/query/provider-page/snapshot 四份 v1 Schema、网络边界预算表、已验证测试矩阵Adapter 接入指南catalog-adapter-guide.zh.md路径 A 标准来源、路径 B 受审 adapter含完整 TypeScript skeleton 与评审清单Schema 与示例schemas/ 下的catalog-source.schema.json、catalog-query.schema.json、catalog-provider-page.schema.json、catalog-snapshot.schema.json以及 examples/ 下的最小 fixture源码实现src/host/routes.ts来源变更、目录响应、媒体服务与安装交接、src/index.ts模块装配与窄能力注入、src/adapters/standard-http / dsh-1024store / dshfind 三个 adapter。总结dsh-community-market的 Shell 设计用一个词可以概括——窄化。数据窄化远程 wire 数据先标准化、能力窄化Client 只有{sourceRecordId, itemId}与bundleId两类不透明身份、操作窄化只有安装与卸载没有启用/禁用、没有 receipt、没有自动回滚。它把信任边界画在 Host 内部目录只贡献「身份」版本只信 npmlatest恢复只靠 Desktop checkpoint。这套边界使得市场可以在失去 package 能力时仍保持可浏览、在来源故障时不影响 Desktop 启动并在 headless 环境下被完整测试。【免费下载链接】deepseek-harness-desktop为 DeepSeek Harness (DSH) 插件生态打造的现代化桌面端解决方案。万物皆「插件」桌面本身也是「插件」。项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness-desktop创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考