插件工坊 · dsh-plugin-studio
一个页面管好 DeepSeek Harness 的插件和技能:三级自动分类、批量删除、AI 大白话讲解、最后使用时间、最近运行档位、一键打包。
它是 dsh-modpack(插件整合包)的下一代:原来的整合包只负责"打包带走",工坊负责"平时怎么管"。
插件工坊界面
上面这张是真实运行截图,不是设计稿。31 个插件按三级树排列,每行前面有复选框,右侧是最后使用时间和操作按钮。
目录
一句话介绍
装了十几个插件之后,Harness 的设置页会变成一长串平铺的列表。你想删掉几个不用的,但看不出哪个是干什么的、不敢删、也不知道哪个真的没用。插件工坊把这四件事合到一个页面里:分类 → 看懂 → 看使用记录 → 批量删,插件和技能一起管。
English
Plugin Studio for DeepSeek Harness — a single browser page to manage your DeepSeek Harness plugins and skills: three-tier auto classification, bulk delete, plain-language AI explanations, last-used time, a "recently ran" tier, and one-click packaging.
It is the next generation of dsh-modpack: where the modpack only "packs things up", the Studio handles "how you manage them day to day".
What it does
- Three-tier auto classification (essential / common / decoration) — rules are explainable, not a black box.
- Bulk delete & bulk package — destructive actions ship with confirm / dryRun.
- Plain-language AI explanations — describes any plugin's purpose in plain Chinese.
- Last-used time + recently-ran tier — see at a glance which plugins are still alive.
- Skills management view.
- One-click packaging into a
.tgz, ready to share or upload.
Install
- Update the DeepSeek Harness desktop client to a version that supports the plugin marketplace.
- Open Settings → Plugin Studio and install / enable with one click.
Or download
dsh-plugin-studio-1.0.8.tgz from Releases and install from file.
Requires: Node ≥ 20, DeepSeek Harness ≥ 0.2.0-rc.1.
v1.0.8 highlights
Adds a "recently ran" tier: some plugins run constantly in the background (e.g. dsh-media-lens, dsh-builtin-browser) yet never show up in tool calls. The Studio now reads the host's desktop-next-*.jsonl logs to surface their latest activity, with a startup-window filter (drops the first 120s of each run) and a ledger (usage-ledger.json) so activity times never regress when logs rotate. Scanning 3 log files takes ~77ms.
Tests
CI runs 9 test suites across Windows / macOS / Linux × Node 20 / 22 / 24:
smoke · analyse · routes · actions · ai · style · compat · render · measure.
中文文档 · Issues
本次更新(v1.0.8)
发布时间:2026-11-02。这是截至发布时的最新版本,本文档与仓库代码、GitHub Release 版本号三者保持一致。
新增「最近运行」档位。 有些插件一直在跑,却永远不会出现在工具调用里(比如壁纸引擎、看图工具、内建浏览器),它们的会话记录还可能被清理掉,于是列里只剩"从没用过"——这既冤枉也不稳定。
本次具体改了什么
| 改动 | 说明 |
|---|
新增 lib/activity.js | 读宿主运行日志(<DSH_HOME>/logs/desktop-next-*.jsonl 最近 3 个文件),按 fields.pluginId 取每个插件最近一次活动时间 |
| 启动窗口过滤 | 每次客户端启动时插件都会打"registered xxx""config loaded"之类的日志。若不过滤,每次重启后所有行都会变成"刚刚"。因此丢弃同一 runId 起始 120 秒内的活动,只保留运行期真实操作 |
| 归属映射 | 日志里的 pluginId(include: 前缀已剥离)先按 entryId、再按 rowId、再按 moduleName 匹配到 bundle 行 |
| 展示优先级 | 最后使用 > 最近运行 > 常驻运行 > 从没用过。"最近运行"有独立措辞与悬停说明,明确写着"只说明它跑过,不代表你调用了它" |
台账增加 runs 段 | 宿主日志会轮转(只留 3 天),观测到的最晚活动时间写入 usage-ledger.json,不会因为日志滚动而倒退;与真实使用分开存,真实使用永远优先 |
| 性能 | 扫 3 个日志文件约 77 ms |
结果
34 行里 10 行有真实使用时间,另有 4 行显示"最近运行":dsh-plugin-wallpaper-engine、dsh-media-lens、@agents-anywhere/dsh-bridge-next、dsh-builtin-browser。
设计细节(为什么这么较真)
- 区分"用过"和"提过":会话日志里出现过
tool/call 才算"最后使用";名字只是被提到过,单独用次要样式显示,不混入使用时间。
- 启动窗口过滤:没有这层过滤,每次重启所有行都会变成"刚刚",这一列直接失去意义。
- 台账防倒退:会话日志会被
dsh-session-clean 删除或宿主轮转,直接重算会让行一夜之间变回"从没用过"。台账只记"见过的最新时间",永远只向前走。
- "最近运行"≠"用过":悬停特意写明"来自宿主运行日志,只说明它跑过,不代表你调用了它",避免误导。
六个功能
1. 三级自动分类,不留"无法判断"
每个插件和技能都会被归到 一级(大类)→ 二级(能力域)→ 三级(它自己) 的三层树里。
一级分类共 8 个(lib/classify.js 的 FAMILIES):
| 一级 | 管什么 | 举例 |
|---|
界面与交互 ui | 给用户看和点的 | 壁纸、主题、侧栏、浮层 |
工具与执行 tools | 给模型加能力的 | 新工具、斜杠命令、MCP 服务 |
网络与数据 net | 联网或读写外部数据 | 抓取、同步、接口、账号 |
模型与推理 model | 接模型或改推理过程 | 模型接入、提示词、上下文压缩 |
会话与工作区 session | 管会话和文件 | 会话增删、工作区、终端 |
运维与诊断 ops | 管插件本身 | 插件管理、技能管理、诊断、备份 |
系统与内核 core | Harness 自带底座 | 通常不该删 |
其它与待确认 other | 证据不足但已归档 | 附原因,可人工改判 |
关于"不再出现无法判断":other 在分类法里保留着,但它是一个有归属的归档,不是"判断失败"——每一行无论证据多弱,都会拿到一个 family、一个 domain 和一条 evidence 说明理由,confidence 会诚实地标 low。实际在本机 28 行真实数据上,other 的命中数是 0。
分类不是"第一条规则命中就定案",而是加权评分:
- PURPOSE(10 分):作者自己写的标题和描述,只投一票,按"最窄的声明优先"排序;
- CAPABILITY(3–10 分):代码里真正调用的服务。调
pluginManager 得 10 分、llm 8 分、tools 7 分、sessionQuery 6 分……这是最有辨识度的证据;
- AMBIENT(1–2 分):几乎所有插件都有的东西。注册一个 UI 插槽、
dsh.client 字段、fetch、fs——这些只用来打平手。
为什么不用"注册了 UI 插槽就是 UI 插件"? 因为那回答的是"它画不画东西",不是"它是干什么的"。优惠券插件、会话清理插件、插件管理器都画东西,但它们分属网络、会话、运维三个大类。早期版本正是踩了这个坑:9 个插件里 7 个被塞进"界面",一级分类直接塌成一支,三级树失去意义。
同分时按 TIE_ORDER = ['tools','net','model','session','ops','core','ui','other'] 裁决——更具体的赢,ui 永远最后。
2. 复选框批量删除 + 重启提示
每个插件/技能前面有复选框,可以单选也可以多选,选中后底部出现操作条。点删除会先弹确认框,列出具体哪几个会被删。
删除走的是 Harness 自己的 pluginManager.removeBundle(),不是手删文件。返回结果里的 application 字段决定要不要提示重启:
applied → 已生效,不用重启;
restart-required → 弹提示,并说明为什么要重启(lib/remove.js 的 RESTART_TEXT 把 restartReason 翻译成人话):
no-hmr —— 这个包没有热重载,改完得重启才能换掉正在跑的代码
package-moved —— 包被移走了,进程还拿着旧路径
host-module —— 改的是宿主侧模块,只有重启才重新加载
unmanaged-plugin —— 这个插件不是包管理器装的,得重启
module-comparison —— 模块版本对不上,重启才能统一
有些行是不可删的(官方底座、只读、来源不明),它们会显示锁图标,复选框直接禁用,并在 removable=false 时给出原因。
删除是串行的:每删一个都会重写 profile 的依赖清单和 patch 文件,并发会丢改动。
3. AI 大白话分析
点每一行的「讲解」按钮,它会结合三样东西推理:
- 代码实际做了什么 —— 读
package.json 的入口、dsh.bundle.patch、dsh.client,读源码里的 slots.register(...)、tools.register(...)、llm.prepareCall 等调用,提取注册了哪些插槽、提供了哪些工具名、碰了哪些子系统;
- 作者自己怎么说的 —— 包的
description、README 开头、locale 里的 meta.description;
- GitHub 上能找到什么 —— 按包名搜 GitHub,校验仓库名或描述里真的出现了这个包名才算命中(防止同名项目误认),再取 README 开头作为佐证。结果缓存 7 天。
输出是三个字段,全部说人话:
what —— 它帮你做什么("会在设置里加一个页面,让你给对话窗口换动态壁纸");
remove —— 删了会怎样("删掉之后壁纸变回纯色,不影响聊天");
why —— 依据是什么("代码里注册了 settings.section,并且调用了 theme.overrideTokens")。
提示词里写死了一条规矩:先说帮你做什么,再说删了会怎样。不给术语,不说"该插件实现了 X 接口"。
4. 最后使用时间
这一列回答"我多久没碰它了"。数据来自 Harness 自己的会话日志(sessionQuery.listSessions() + readSession(),没有这个服务时回落到直接读 ~/.dsh/sessions/**/session.v4.jsonl.zstd)。
关键设计:区分"用过"和"提过"。
- 真的用过(
usedAt / usedVia):会话日志里出现过 tool/call,工具名匹配这个插件注册的工具。这才显示成"最后使用"。
- 只是被提到(
mentionedAt):名字在对话里被说起过。这不算使用,单独用次要样式显示。
为什么较真? 早期版本把"被提到"也算成使用,结果我们一边讨论插件、一边所有插件都被标成"刚刚使用"——28 行里 19 行都有时间,这一列直接失去意义。一条错误的信息比没有信息更糟。
日志读取有个坑:session.v4.jsonl.zstd 是多帧 zstd 拼接,zstdDecompressSync(整个文件) 只解第一帧。lib/usage.js 的 decompressFrames() 按 zstd magic 28 B5 2F FD 扫描全部帧偏移,逐帧解压再拼接。
5. 技能管理页(和插件页功能对等)
第二个 tab 管技能,功能和插件页一致:三级分类、搜索筛选、复选框批量删除、一键打包。
技能从四个根目录扫描(lib/skills.js 的 skillRoots()):
| 根目录 | scope |
|---|
<DSH_HOME>/skills | user-dsh |
<DSH_HOME>/agents/skills | user-agents |
<cwd>/.dsh/skills | project-dsh |
<cwd>/.agents/skills | project-agents |
优先用 skills.list() 服务拿清单,拿不到就自己扫目录(读 SKILL.md 的 frontmatter 取 name / description / when_to_use)。
删除技能有两道守卫:必须是目录、目录里必须有 SKILL.md——防止路径算错时删掉无关目录。
6. 重命名 + 重新设计的界面
名字从「插件整合包」改成「插件工坊」,包名从 dsh-modpack 改成 dsh-plugin-studio,接口前缀改成 /api/dsh-plugin-studio。
界面设计上遵守了 Harness 客户端的三条硬规矩:
- 只用主题 token —— 13 个
--dsw-alias-* / --dsw-specific-* 变量,零硬编码色值,深浅色自动跟随;
- 不碰别人的 DOM —— 不 append 到
document.body、不查询别人的元素、不用 innerHTML;
- 样式可清理 —— 一个
<style> 标签,用 ctx.effect() 注册,卸载时自动移除。
三个 tab:插件 / 技能 / 整合包。视图可以在「三级树」和「平铺列表」之间切换,树可以逐级折叠,每个分组都有「全选本组」。
功能特点
- 零依赖、零构建:插件本身没有任何运行时依赖,测试也只用 Node 内置模块。装上即用,不拖慢客户端。
- 不碰你的其它插件:只读清单、只读日志,删除走 Host 官方
removeBundle,绝不手删文件。
- 破坏性操作全部有确认 / dryRun:批量删除先列清单弹确认;Agent 工具
studio_remove 支持 dryRun。
- 跨版本稳健:按"方法存在性"探测能力,而不是看版本号。老版本缺服务就优雅降级(删除按钮禁用、清单回落文件读取),不会白屏。
- 深浅色自动跟随:全部走主题 token,客户端切深色模式它跟着切。
- 给模型用的三个工具:
studio_list / studio_explain / studio_remove,让 AI 也能帮你清插件。
- 给开发者用的调试脚本:
scripts/scores.mjs 看每行评分明细,scripts/why.mjs <包名> 看为什么被分到那里,scripts/measure.mjs 用无头 Edge 量布局。
界面展示截图
以下是真实运行截图(已上传到仓库 docs/screenshots/,克隆后可见)。
主界面(插件页,三级树 + 复选框 + 最后使用时间)
插件工坊主界面
三级分类树(按 8 个大类分组,可逐级折叠)
三级分类树
完整界面一览(含顶部 tab、工具栏筛选、底部操作栏)
插件工坊完整界面
安装
方式一:从 GitHub 安装(推荐)
plugin_manager action: install_bundle
target: github:KERBALMans/dsh-plugin-studio
装特定版本:
plugin_manager action: install_bundle
target: github:KERBALMans/dsh-plugin-studio#v1.0.8
方式二:从 tgz 安装(离线/内网)
从 Releases 下载 dsh-plugin-studio-1.0.8.tgz,然后:
plugin_manager action: install_bundle
target: E:\下载路径\dsh-plugin-studio-1.0.8.tgz
方式三:从本地目录安装(改代码时用)
plugin_manager action: install_bundle
target: E:\你的路径\dsh-plugin-studio
安装后 profile 里会出现一个指向源目录的 Junction,改源码即刻同步到 profile 磁盘。
安装完成后
打开 设置 → 插件工坊(在侧栏设置里,位于「插件」下面、「智能体预设」上面)。
装完看不到? 如果页面没出现,重启一次客户端。运行中的 Host 会缓存已加载的 ES 模块,plugin_manager 报告 application: "applied" 只说明依赖装好了,不说明新代码已经在跑。
改完代码不生效? 不用重启,禁用再启用一次即可:
plugin_manager action: set_plugin target: "include:dsh-plugin-studio" enabled: false
plugin_manager action: set_plugin target: "include:dsh-plugin-studio" enabled: true
使用前必读 / 注意事项
- 它需要 DeepSeek Harness 桌面客户端(>= 0.2.0-rc.1)。它本身不是独立 App,是客户端里的一个插件。直接打开网页是看不到它的。
- 删除是真实删除。批量删除会真的从 profile 移除插件/技能并重写依赖清单;删之前确认框会列出具体哪几个,请看清再确认。
- "最后使用"不等于"最近运行"。v1.0.8 起新增"最近运行"档位只说明插件在客户端里活动过,不代表你调用了它。真正的调用会单独显示为"最后使用(工具调用)"。
- AI 讲解需要可用的模型。没有配置模型时讲解按钮会提示"当前没有可用的模型",不会卡住;GitHub 检索需要联网。
- 会话日志会被清理。装了
dsh-session-clean 之类的清理插件时,被删会话里的使用记录会一起消失——这是为什么本插件加了"使用台账",让时间不会一夜倒退。
- 不可删的行别硬删。官方底座、只读、来源不明的行复选框是禁用的;强行绕过会失败且不留记录。
- 重启不是 bug。删除某些包后提示重启,是因为它们没有热重载或被宿主侧引用,这是 Harness 的正常行为。
- 版本号三处必须一致:
package.json 的 version、GitHub Release 的 tag(v1.0.8)、CHANGELOG 的版本段。CI 会在打 tag 时自动校验。
界面说明
三级分类树
顶部:三个 tab
| tab | 管什么 |
|---|
| 插件 | 已安装的插件包(bundle) |
| 技能 | 技能工具(skill),功能与插件页对等 |
| 整合包 | 已保存的整合包,可一键装回 |
每个 tab 右边有计数,比如「插件 31」。右上角是刷新按钮(v1.0.8 起刷新会重新读取使用时间,并加了缓存避免切换 tab 重复读日志)。
工具栏
从左到右:
- 搜索框 —— 按名字、包名、描述搜,实时过滤;
- 筛选 chips ——
全部 / 已启用 / 90 天未用 / 可删除 / 低置信度,可以同时选多个(是"与"关系);
- 视图切换 ——
三级树 ↔ 列表视图;
- 展开全部 / 收起全部 —— 只在树视图下出现。
三级树
界面与交互 2 个插件 [全选本组]
├─ 主题与外观 1
│ └─ ☐ dsh-plugin-wallpaper-engine
│ Wallpaper Engine backgrounds for the DSH web GUI...
│ 最后使用:3 天前 [讲解] [展开]
└─ 界面插件 1
└─ ☐ ...
- 一级(粗体):8 个大类之一;
- 二级:能力域,每个大类下 1–5 个;
- 三级:插件本身。
每一级都能点击折叠。二级标题右边有「全选本组」,勾上就选中这一组的所有插件。
每一行长什么样
☐ dsh-plugin-rea 官方 已启用 高置信度
MCP server for reverse engineering tools...
最后使用:2 小时前(工具调用)
▸ 依据:代码里注册了 tools.register,并且调用了 ...
[讲解] [展开]
- 复选框 —— 最左边,点它选中;
- 名称 + 徽章 ——
官方(Harness 自带)、已启用/已停用、高置信度/中置信度/低置信度、只读(不可删);
- 描述 —— 作者写的一句话;
- 最后使用 / 最近运行 / 常驻运行 —— 见下方说明;
- 依据 —— 折叠的判定理由,展开能看到具体证据;
- 讲解 —— 点它调 AI 生成大白话说明;
- 展开 —— 显示完整描述、包名、版本、来源、注册了哪些插槽/工具。
关于「最后使用」这一列
有三种显示,含义不同:
| 显示 | 含义 |
|---|
最后使用:2 小时前(工具调用) | 真的用过 —— 会话日志里有工具调用命中它注册的工具 |
最近运行:3 天前 | 只是跑过 —— 来自宿主运行日志,悬停说明"只说明它跑过,不代表你调用了它"(v1.0.8 新增) |
最后使用:— + 灰字 5 天前提到过 | 只是被提到 —— 名字在对话里出现过,但没有实际调用 |
为什么要区分? 因为"提到"不等于"使用"。你在对话里说"这个插件不错",不代表它工作了。如果混在一起,讨论插件的时候所有插件都会显示"刚刚使用",这一列就失去意义了。
底部操作栏
勾选任意插件后,底部浮出操作栏:
已选 3 个 [打包] [删除] [取消选择]
- 打包 —— 把这 3 个打包成整合包,可以保存或分享;
- 删除 —— 弹确认框,列出具体哪几个会被删,确认后执行。
删除确认框
删除 3 个插件?
dsh-plugin-wallpaper-engine
dsh-aliyun-coupon
dsh-session-clean
这个操作会从 profile 里移除它们,并重写依赖清单。
[取消] [确认删除]
删除后,如果某个包需要重启才能完全卸载,会再弹一个提示说明原因:
- 「这个包没有热重载,改完得重启才能换掉正在跑的代码」
- 「改的是宿主侧模块,只有重启才重新加载」
整合包 tab
显示已保存的整合包列表,每个显示名称、条目数、创建时间。可以删除。
使用场景
场景一:清理长期不用的插件
- 打开插件工坊
- 点筛选 chip
90 天未用
- 列表只剩很久没碰过的插件
- 逐个看描述和最后使用时间,勾选要删的
- 点删除,确认
场景二:搞不清某个插件是干什么的
- 找到那个插件
- 点
讲解
- 等几秒,AI 会给出三段说明:
- 它帮你做什么 —— "会在设置里加一个页面,让你给对话窗口换动态壁纸"
- 删了会怎样 —— "删掉之后壁纸变回纯色,不影响聊天"
- 依据是什么 —— "代码里注册了 settings.section,并且调用了 theme.overrideTokens"
场景三:换电脑,把插件配置带走
- 在插件页勾选想带走的插件
- 点
打包
- 起个名字,保存
- 把
整合包 tab 里的文件拷到新电脑
- 在新电脑上用
plugin_manager 应用,或者用 studio_list 工具
场景四:管理技能
技能页和插件页功能一样:三级分类、搜索、筛选、批量删除、打包。8 个内置技能会被分成「文档处理技能」(office 系列 7 个)和「开发与诊断技能」(1 个)。
常见问题
装完之后设置里没有「插件工坊」
- 确认安装成功:
plugin_manager action: list_bundles,找 dsh-plugin-studio
- 如果列表里有,但页面没有,重启客户端
- 如果列表里没有,重新安装
页面打开是空白的
页面顶部如果有红条提示「客户端与宿主版本不一致」,重启客户端即可。这是防止新旧代码混跑的保护。
AI 讲解一直转圈或报错
AI 功能需要可用的模型。检查:
设置 → 模型 里有没有配置好的模型
- 网络是否可达(GitHub 检索需要联网)
没有模型时,讲解按钮会显示"当前没有可用的模型",不会卡住。
最后使用时间一直是空的
说明这个插件注册的工具从来没被调用过。这是正常的——很多插件是纯 UI 的,不注册工具,所以永远不会有"工具调用"记录。这种情况下会显示"未使用过"或"常驻运行"。
删除按钮是灰的
那一行不可删。原因可能是:
- 它是 Harness 官方底座(
removable: false)
- 它是只读的
- 它的来源不明(不是通过包管理器装的)
鼠标悬停能看到具体原因。
删除后插件还在
- 看删除时有没有弹重启提示。弹了就重启客户端
- 重启后还在的话,检查
plugin_manager action: list_bundles 确认
- 如果确实还在,可能是删除失败,重新删一次看错误信息
技能删除后还在
技能的启用/禁用是通过写 .disabled 标记文件实现的。删除会真的删目录,但需要重启才能让 Harness 重新扫描。
开发
目录
dsh-plugin-studio/
├── index.js Host 半:apply()、HTTP 路由、Agent 工具
├── client.js Client 半:设置页 UI
├── cordis.patch.yml bundle 插入声明
├── package.json
├── icon.svg
├── locale/{zh,en}.json
├── lib/
│ ├── env.js 路径、请求体、JSON 响应、服务查找
│ ├── caps.js 能力探测(按方法存在性,不看版本号)
│ ├── inventory.js 插件清单(pluginManager 优先,文件回落)
│ ├── classify.js 三级分类:FAMILIES / DOMAINS / 加权评分
│ ├── usage.js 最后使用时间(会话日志扫描)+ 使用台账
│ ├── activity.js v1.0.8 新增:宿主运行日志读"最近运行"
│ ├── attribution.js 工具名 → 包 → 行的归属映射
│ ├── ledger.js v1.0.8 新增:持久使用台账(防倒退)
│ ├── skills.js 技能清单、删除、启停、打包
│ ├── ai.js AI 讲解与 AI 分类
│ ├── remote.js GitHub 检索与缓存
│ └── remove.js 删除与重启提示
└── scripts/ 测试套件(见下)
测试
九个测试套件,全部不需要跑起 GUI(用 fixtures/ 里的真实数据):
node scripts/smoke.mjs # 能力探测、清单回落、分类法自检
node scripts/analyse.mjs # 真实数据跑完整管线
node scripts/routes.mjs # 每个 HTTP 路由
node scripts/actions.mjs # 打包、保存、删除、分类的读写
node scripts/ai.mjs # AI 路由在无模型时的降级
node scripts/style.mjs # 样式与模块契约审计
node scripts/render.mjs # 用 React 替身渲染出真实 HTML
node scripts/compat.mjs # 跨版本契约
node scripts/measure.mjs # 用 headless Edge 量布局
一键跑全部(CI 就是这么跑的):
node scripts/all.mjs --offline
all.mjs 额外包含一个调试用的 scores 套件用于打印评分明细,正式 9 个套件即上面列出来的。CI 矩阵覆盖 ubuntu / windows / macos × Node 20 / 22 / 24。
调试用:
node scripts/scores.mjs # 打印每行的评分明细
node scripts/why.mjs <包名片段> # 某一行为什么被分到那里
node scripts/measure.mjs # 用 headless Edge 量布局
改完代码怎么生效
不用重启客户端:
plugin_manager action: set_plugin target: "include:dsh-plugin-studio" enabled: false
plugin_manager action: set_plugin target: "include:dsh-plugin-studio" enabled: true
禁用再启用会强制 Host 重新加载模块。
跨版本兼容
engines.dsh 写的是 >=0.2.0-rc.1。真正让插件跨版本活下来的不是版本号,是按方法存在性探测能力:
function has(target, name) {
return !!target && typeof target[name] === 'function'
}
版本号告诉你发布者想给你什么,缺失的函数告诉你这个进程实际能做什么。
scripts/compat.mjs 为五个契约建模并逐个验证:
| 契约 | 模拟什么 | 结果 |
|---|
0.2.1-rc.1 | 没有 removeBundle、没有 inspect、没有 skills 服务 | 降级运行,删除按钮禁用 |
0.2.1-rc.2 | 加上 removeBundle | 删除可用 |
0.2.1-rc.3 | 当前版本,全量服务 | 全部功能 |
future-additive | 未来版本:只加不改,多出 somethingBrandNew 等未知方法 | 未知方法被忽略,行为不变 |
future-renamed | 未来版本:删掉 listBundles | 回落到读 profile 文件,清单仍出得来 |
每个契约都断言同一组事:能力探测不抛、路由构建不抛、根路由返回 apiVersion、清单非空且每行有三级分类、无 other、分类有区分度、官方可选包没被判成内核、壁纸判成界面、会话清理判成会话、技能路由不崩、删除不存在的行被拒绝且不产生删除记录。
最后还有一段「空 ctx」:所有服务都拿不到时,capabilityReport() 要报出缺失项而不是抛异常,根路由仍要返回 200——这样 UI 能告诉用户"这个版本缺什么",而不是白屏。
已知限制:本机只装了 0.2.1-rc.3,rc.1 / rc.2 无法真实安装验证,所以用的是契约级验证(模拟各版本的服务面)。这在工程上等价于"按接口编程"的验证,但不等价于"真的在 rc.1 上跑过"。
HTTP 接口
所有接口在 /api/dsh-plugin-studio 下,先过 connection.admit() 鉴权。
| 方法 | 路径 | 作用 |
|---|
| GET | / | 版本与接口清单 |
| GET | /inventory | 插件清单 + 三级树 + 使用时间 |
| GET | /skills | 技能清单 + 三级树 |
| GET | /saved | 已保存的整合包列表 |
| GET | /diag | 能力探测、模型、各根目录 |
| POST | /pack | 打包成整合包 |
| POST | /save | 保存整合包到磁盘 |
| POST | /delete-pack | 删除已保存的整合包 |
| POST | /categories/save | 手动改判分类 |
| POST | /categories/reset | 清空手动改判 |
| POST | /suggest | AI 批量分类 |
| POST | /explain | AI 大白话讲解 |
| POST | /remove | 删除插件 |
| POST | /skills/remove | 删除技能 |
| POST | /skills/enable | 启用/禁用技能 |
| POST | /skills/pack | 打包技能 |
| POST | /plan | 预览应用整合包会做什么 |
| POST | /apply | 应用整合包 |
Agent 工具
给模型用的三个工具:
studio_list —— 列出插件或技能(带三级分类);
studio_explain —— 讲解某个插件;
studio_remove —— 删除插件(支持 dryRun)。
数据存放
<DSH_HOME>/storages/dsh-plugin-studio/
├── plugin.json 安装标记
├── categories.json 手动改判 + AI 讲解缓存
├── remote-cache.json GitHub 检索缓存(7 天)
├── usage-ledger.json v1.0.8 新增:持久使用台账(防时间倒退)
└── packs/ 已保存的整合包
整合包格式:
{
"format": "dsh-plugin-studio-pack",
"formatVersion": 1,
"meta": { "name": "...", "description": "...", "createdAt": 0, "kind": "plugin", "count": 0 },
"entries": [
{
"key": "bundle:xxx",
"kind": "bundle",
"name": "xxx",
"version": "1.0.0",
"spec": "xxx@1.0.0",
"category": { "family": "ui", "domain": "ui.theme", "familyLabel": "界面与交互", "domainLabel": "主题与外观" },
"enabled": true,
"official": false,
"description": "..."
}
]
}
许可
MIT
相关文档