open-dsh-market
Manifest valida dsh-plugins-market
CCTor 插件市场 · DeepSeek Harness Bundle
cctor-dsh-marketplace 是一个可安装的 DeepSeek Harness(DSH)bundle。它以 https://api.cctor.com 作为动态目录,同时提供原生插件市场界面和面向模型的 Agent 工具。界面与工具共用同一个 Host 服务、同一份持久缓存、同一个已安装状态读取器和同一个安装协调器。
当前版本为 0.1.0。v1 只覆盖发现、详情、已安装状态展示,以及每次都需要用户显式确认的安装;不包含更新、禁用、卸载或跨 profile 安装。
功能概览
- 主从布局:左侧是可搜索的结果列表,右侧是选中插件的详情。窄屏下详情成为独立第二屏,并提供返回控件。
- 搜索与筛选:搜索输入有 300 ms 防抖,会取消被取代的请求;少于 3 个字符的非空搜索不会发出(该 API 对短查询按设计返回空页)。支持分类、排序、刷新、分页、清除缓存。
- 已安装状态:当前 profile 中已安装的条目显示本地版本,不再显示普通安装按钮。
- 双语界面:跟随 DSH 当前 locale 显示中文或英文。日期、数量、空状态、错误和安装进度均本地化;插件名称、描述、README、标签和仓库元数据保持 API 原文。
- 三个 Agent 工具:与 UI 使用完全相同的 Host 规范化结果和缓存。
| 工具 | 作用 | 关键约束 |
|---|---|---|
cctor_search_plugins | 搜索目录,返回插件摘要、分页信息和缓存新鲜度 | 默认 10 条,单次最多 20 条;返回不透明 next_cursor;不返回 README 或 install_command;绝不安装 |
cctor_get_plugin_details | 按稳定 ID 或精确 slug 读取公开详情、验证状态和当前 profile 已安装状态 | slug 解析要求唯一;零匹配返回 not_found,多匹配返回 ambiguous_plugin;稳定 ID 直接走详情端点 |
cctor_request_plugin_install | 为当前 profile 准备一次性安装确认 | 只返回 awaiting_confirmation、确认 ID、过期时间、目标 profile、路由和安全 spec;工具不能自行批准或执行安装 |
这些工具的输出都有字段长度上限和 64 KiB 总预算;内部缓存结构、堆栈、路径和请求头不会进入模型上下文。
架构
Agent 工具 ─┐
├─ CctorMarketplaceService ── CCTor API(list / meta / detail)
Web Client ─┘ │
(同源 HTTP API) ├─ Storage Domain(插件私有持久缓存)
└─ Plugin Manager(只写当前 profile 的安装)
- Host 拥有 HTTP 请求与响应校验、缓存、目录规范化、profile 读取、安装确认与执行。
- Web Client 只负责展示;它不直接访问 CCTor,也不能执行安装。它通过
connection注册的同源/api/cctor-marketplace/rpc路由调用 Host;Agent 工具与保留的 Typert Remote 共用同一个 Host 服务。 - bundle 将官方
storageDomain、pluginManager、profileContext、typert和tools声明为必需注入。如果运行时模块无法导入,或 Host 组合失败,守卫入口会记录一条有界兼容性诊断并保持惰性,而不是破坏整个插件树。
安装
要求:Node.js >= 22;DSH >= 0.2.1-rc.5 < 0.3.0(见 package.json 的 engines,peer 依赖由 DSH 运行时提供)。
从 npm 安装(包发布之后)
dsh plugin --profile <name> add cctor-dsh-marketplace
把 <name> 换成目标 profile。安装完成后按提示重启 DSH。这条 CLI 命令安装的是市场 bundle 本身,与市场 UI 的 v1“只装当前 profile”安装路线是两件事。
本地开发安装
先在检出目录构建,再把本地路径安装到目标 profile:
pnpm install
pnpm build
dsh plugin --profile <name> add /absolute/path/to/cctor-dsh-marketplace
Plugin Manager 会校验 bundle 元数据和兼容性,并把该路径记录为 link: 依赖。请使用绝对路径。本仓库在验证过程中没有向任何真实 profile 安装,也没有发布该包。
配置
bundle 的配置由 Schemastery 定义,通过 DSH 的插件配置传入。字段等价于:
{
"apiBaseUrl": "https://api.cctor.com",
"requestTimeoutMs": 15000
}
| 字段 | 默认值 | 说明 |
|---|---|---|
apiBaseUrl | https://api.cctor.com | 必须是根地址(origin)。生产必须使用 HTTPS;只有字面量 localhost 或 127.0.0.1 允许 HTTP,用于本地开发。拒绝 URL userinfo、路径、查询串和 fragment。 |
requestTimeoutMs | 15000 | 单次目录请求超时,正整数毫秒。 |
工具条上的“清除缓存 / Reset cache”只清除本插件私有的缓存域,不会触碰其他 Storage Domain,也不会改变已安装状态。
缓存与离线行为
- 缓存优先:打开市场时,如果存在匹配的持久缓存记录,Host 立即返回它,同时在后台刷新列表或元数据。成功且通过校验的响应会原子替换对应记录;失败或非法响应不会覆盖最后一次成功记录。详情同样缓存优先。
- 新鲜度:列表和元数据 5 分钟,详情 30 分钟。超过 TTL 的记录会标记为
stale,但仍立即展示,同时触发后台刷新。 - 7 天回退:最后一次成功记录在刷新失败后继续作为回退返回。超过 7 天会标记为
possiblyOutdated,不再被当作实时数据,最终由 LRU 淘汰。 - 有界缓存:最多 50 个列表作用域、50 份元数据和 200 个详情,按 LRU 淘汰;每条记录带缓存 schema 版本。缓存键包含规范化后的 API base URL、查询、分类、排序和 cursor。
- 离线:有缓存时,界面显示缓存内容,并用本地化横幅标明“过期”或“可能已过期”,同时给出重试入口;刷新失败的原因以有界错误码呈现,原始响应不会污染缓存。没有缓存且网络失败时,显示本地化的
offline/timeout错误和重试操作。 - 安装确认不读缓存:准备安装确认时,Host 总是重新从 detail 端点读取插件,确保确认绑定的是网络上的最新身份和安全 spec。
安装确认与安全边界
- 每次安装都需要一次新的显式确认。 确认是单次使用、5 分钟后过期的,并绑定稳定插件 ID、规范化安装 spec、目标 profile、验证状态和源内容摘要。执行前会重新检查源;如果 spec 或相关字段变化,确认失效,用户必须重新审阅。
- 未验证警告:目录中的未验证条目可以浏览和安装,但不会被静默放行。确认框会提示 Host 代码可能访问对话、文件和网络;主按钮为
仍要安装(英文界面为Install anyway)。不额外要求勾选框或第二次确认。 - 安全 spec 只从结构化字段推导:优先使用合法的 npm 包名加 API 给出的精确版本;没有合法 npm 目标时才使用规范化后的 GitHub 仓库,生成
github:owner/repo。github+npm记录优先 npm。空白或缺失的package_name/version按null处理。 - 拒绝不安全目标:非法、歧义、非 GitHub Git、tarball、本地路径或带 shell 元字符的目标会被拒绝。
install_command只用于展示,永不执行。 运行时源码src/不导入child_process,不拼接 shell 命令,也不把 API 返回的命令当作执行输入。- 串行安装:同一时间只允许一个安装;第二个请求会得到
install_busy。 - 目标恒为当前 profile:v1 只通过官方 Plugin Manager 的
pluginManager.installBundle安装到当前 profile。不启动dsh子进程,不写其他 profile,不提供 profile 选择器,也没有defaultProfile设置。路由始终是plugin-manager。 - v1 不做更新/禁用/卸载:这些操作请使用 DSH 自带的插件管理界面。已安装条目会显示本地版本,并隐藏普通安装入口。
为什么 v1 不做跨 profile 安装
见设计文档 §15.1。核心原因是:打包的 Desktop 运行时与 PATH 上的 dsh 可能不是同一代 DSH;ProfileContext.packageManager 存在的原因正是打包应用使用自带运行时,而不是可靠的 PATH 可执行文件;当前 profile 也是 Host 唯一能观测、且 Plugin Manager 能端到端校验其变更的 profile。跨 profile CLI 路线、profile 选择器和 desktop 例外路径都推迟到 v1.1。
目录数据现实与空状态
2026-11-04 对生产目录的观测(7,567 条公开记录,抽样 200 条):
verified在样本中全部为false,featured也全部为false。因此未验证是常态,未验证警告是常规路径,而不是异常。- 200 条列表记录中只有 1 条带非空
readme;详情响应同样经常为空。 package_name和version只出现在github+npm记录中(样本 58/200);github记录两者都没有。- 稳定 ID 有两种命名空间形式:
github:owner/repo和repo:owner/name。两者都被接受,且不会从repository重新推导 ID。
因此界面必须显式呈现空状态:没有 README 时显示本地化的“这个插件没有提供 README。”,而不是空白块;缺失的版本或许可证显示“未知”。这些是目录的预期状态,不是加载失败。API 提供的插件名称、描述、README 和仓库信息保持原样。
API 前置条件
本 bundle 依赖现有的 GET /market/plugins 和 GET /market/plugins/meta,并依赖已部署的精确详情端点:
GET /market/plugins/detail?id=github%3Aowner%2Frepository
该端点于 2026-11-04 在生产环境验证可用(返回 200,包含 readme、verified、featured;空 id 返回 400;未知 id 返回 404;响应带 CORS 和 Cache-Control: public, max-age=60, s-maxage=300)。本次发布门禁没有再次联网调用它。
契约要点:
- 只接受恰好一个非空
id查询参数;稳定 ID 可能包含/,因此必须 URL 编码。 - 按主键精确查找,只返回 active 的公开记录。
- 成功响应包含公开列表项字段,外加完整的
readme、verified和featured;不得返回审核、同步、凭据或内部溯源字段。 - 稳定错误响应:
400 {"error":"invalid_plugin_id"}404 {"error":"plugin_not_found"}(未知或非 active)405 {"error":"method_not_allowed"}502 {"error":"database_error"}(不泄露数据库细节)
- 使用现有市场 CORS 策略和公共缓存头;路由必须先于任何通用的
/market/plugins/<segment>路由匹配。
Host 会把网络、超时、非法响应、找不到、slug 歧义、安装忙、确认过期、源变化、profile 无效、不兼容和安装失败映射为稳定的公开错误码,并为用户提供可用的恢复动作。
验证与已知限制
最近一次完整门禁的真实结果(本仓库,2026-11-05):
| 检查 | 结果 |
|---|---|
pnpm typecheck | 通过(Host 与 Client 两个 tsconfig) |
pnpm build | 通过,产出 lib/index.js、lib/plugin.js、lib/client.js、类型声明和 sourcemap |
pnpm test | 327 个 Node 测试全部通过,0 失败、0 跳过 |
pnpm exec playwright test | 16 个测试通过(15 个 desktop + 1 个 @narrow),覆盖 1440×900、1024×768、390×844 三个视口 |
| 禁止模式扫描 | 无真实违规;匹配项是说明“这些模式不存在”的文档句子、正则 .exec、测试辅助函数 exec() 和 UI 的 placeholder 文案 |
327 个 Node 测试的分布:覆盖 Client HTTP transport/store/locale/UI、Host 路由与服务、缓存/安装/目录/profile、入口与构建,以及真实 DSH Loader 组合。它们覆盖 HTTP 请求校验、错误 envelope、缓存 TTL/LRU/schema 版本/原子替换、slug 解析、安装 spec 白名单、确认过期与源变化、工具输出边界和 Client HTTP route 契约。
这些结果证明什么、不证明什么:
- 安装边界是用一个与 Plugin Manager 兼容的假实现验证的。真实的 DSH Plugin Manager 应用、真实包管理器执行和真实 profile 写入没有被执行(本次任务也禁止这样做)。因此适配器边界的语义已证明,真实安装的应用/重启/构建审批路径未证明。
- 缓存持久性是通过真实 Storage Domain、搭配测试自有的文件后端验证的。已部署后端的 media、per-record、
compatibleVersions、backup 等边界语义不在证明范围内。 - Playwright 证明的是构建后的
lib/client.js产物、工作流和布局,使用假 shell 与假 Host HTTP route。它不证明打包 shell 的真实 seat 实现、真实模块表、真实样式变量或 Connection carrier 的生产往返。 - 集成 fixture 是惰性的 spec 目标:它从未被安装,也没有入口模块,不可启动。请勿把它当作可运行的示例插件。
pnpm build必须先于pnpm test:test/integration/loader.test.ts有基于 mtime 的新鲜度守卫;如果产物缺失或早于最新的src/文件,测试会直接失败。- 实测未验证:打包 Desktop shell 的 Connection route 往返、真实网络下的 API 调用、真实 profile 中的安装、跨 profile 安装,以及发布后的 npm 安装。
- Playwright 截图像素基线是 Chromium/macOS/1×/UTC/light 专用的;不同字体栈或 Chromium 版本可能需要
--update-snapshots,这属于平台基线变化,不是 UI 变化。 - 真机验收发现与修复状态:2026-11-05 的打包 Desktop 检查曾发现
ctx.remote.$mount(...)不结算。Client 现已改用connection提供的同源 HTTP route,不再等待第三方 Typert namespace mount;Host 仍保留 Typert Remote 与 Agent 工具。该修复通过 327 个 Node 测试和 16 个 Playwright 测试,但尚未在打包 Desktop shell 复验。尝试启动隔离cctor-demoprofile 时,dshlauncher 先尝试 unlink/修复共享 profiles symlink 并被 sandbox 拒绝,因此没有修改 profile 或宣称真机验收通过。 - 隔离调试 profile
~/.dsh/profiles/cctor-demo(App 的 0.2.1 runtime + 本 bundle + 参考插件)保留用于后续排查;desktop/webprofile 未被修改。 - 测试与验证步骤没有向
~/.dsh/profiles/*写入任何内容;仓库没有发布,也没有部署 API。
截图
以下 9 张截图来自 Task 9 的 Playwright harness,均已用图像阅读器逐张检查。截图隐藏了 harness 工具条,Date.now 冻结在 2026-11-04T12:05:00Z,数据来自确定性 fixture,不是生产目录;因此截图中的日期、数量和插件名只用于展示布局。
| 列表 | 详情 | 安装确认 |
|---|---|---|
![]() | ![]() | ![]() |
![]() | ![]() | ![]() |
![]() | ![]() | ![]() |
我在这些截图中实际确认到的内容:
- 1440×900 列表:工具栏保持一行,搜索框占据主要宽度,分类、排序、刷新、清除缓存和只读的当前 profile 标签靠右;顶部有目录总数与同步日期,列表标题旁有“更新于 5 分钟前 · 来自网络”。左侧可见多行结果和右对齐的“未验证/已验证/已安装”徽标;长插件名跨多行换行且未被裁切。右侧尚未选择插件,显示“选择一个插件查看详情。”。视口下缘截断后续行,没有横向溢出。
- 1440×900 详情:选中行有高亮;“Alpha 未验证插件”详情展示未验证状态、粉色警告块、仓库、作者、版本、许可证、标签、发布日期、更新时间、星标/周下载和缓存年龄。长 README 超出可视区域,由详情列裁切;蓝色安装按钮在视口下缘只露出一部分,下半部分被视口裁切——详情列内部可滚动,向下约 16 px 即可完整显示并点击安装。
- 1440×900 确认框:对话框居中覆盖在变暗的工作区上;对话框面板本身不覆盖顶部工具栏(背景遮罩会变暗工具栏区域,并在弹窗期间拦截其点击)。内容包含“确认安装”、未验证徽标与警告、插件、仓库、目标 profile
web、安装方式“插件管理器”、安装包@cctor-lab/alpha-tool@1.2.3、命令预览、有效期“2026年11月4日 12:10”,以及“取消”和“仍要安装”按钮;命令预览换行到两行。 - 1024×768 列表/详情:工具栏仍为一行;列表更窄,长名称换行更多,底部行被视口截断。详情列变窄但字段和 README 正常换行;该视口中安装按钮位于首屏折叠之下(详情列内部向下滚动约 148 px 可见,按钮本身可点击)。确认框完整落在 768 px 高度内。
- 390×844 列表:工具栏折成两行(第一行搜索和分类,第二行排序、刷新、清除缓存和 profile 标签),profile 标签仍可见;列表占满宽度,长名称跨多行换行,徽标仍在右侧列内。
- 390×844 详情:列表隐藏,顶部显示“← 返回”,下面是完整的未验证警告、字段和换行后的 README;没有横向滚动。
- 390×844 确认框:窄屏对话框落在视口宽度内,警告、字段和命令预览(三行)换行干净,底部“取消/仍要安装”可见,背景详情被遮罩。
这些截图是像素级基线(maxDiffPixels: 0、threshold: 0),用于防止布局回归;它们不是对真实 DSH 桌面 shell 的验收截图。
开发与验证
pnpm install
pnpm typecheck
pnpm build # 必须先于 pnpm test:Loader 测试的守卫基于 mtime
pnpm test # 327 个 Node 测试
pnpm exec playwright test # 16 个测试,9 张像素基线
修改客户端后重新跑到 Playwright;修改 src/ 后先重新 pnpm build。Playwright 的 webServer 会自行构建 harness 资源并监听 127.0.0.1:4517;它要求 lib/client.js 已存在。
本版本明确不做的事
- 不发布 npm 包、不部署 API、不向真实 DSH profile 安装。
- 不做更新、禁用、卸载、跨 profile 安装、profile 选择器或
defaultProfile。 - 不执行 API 返回的
install_command,不启动 shell 或dsh子进程。 - 不把缓存写入 Session 历史,也不把缓存内部结构暴露给模型。
Versions
| Latest version | Published | Size |
|---|---|---|
| 0.1.0 | — | — |
Comments
Loading…
Similar plugins
by 250shiwo
deepseek harness的简易插件市场
★ 0
TypeScript
Aug 21, 2026
dsh plugin --profile web add dsh-plugin-marketby qiqiangvae
dsh obsidian wiki plugin
★ 0
MIT
TypeScript
Aug 30, 2026
dsh plugin --profile web add @qiqiangvae/dsh-obsidianby Ephemeral-AI-Lab
Make Deepseek Harness Great
★ 54
MIT
TypeScript
Nov 2, 2026
dsh plugin --profile web add dsh-codex-terminalby ZSCDumin
dsh-wellness
★ 0
MIT
TypeScript
Sep 6, 2026
dsh plugin --profile web add dsh-wellnessby peng7peng
dsh-terminal-manager
★ 0
MIT
TypeScript
Nov 2, 2026
dsh plugin --profile web add dsh-terminal-managerby losebird
DeepSeek Harness plugins market|DSH 插件市场
★ 25
↓ 3.5k/wk
NOASSERTION
JavaScript
Nov 5, 2026
dsh plugin --profile web add @ace-zone/dsh-market







