88 lines
9.1 KiB
Markdown
88 lines
9.1 KiB
Markdown
# 27 · MCN 工作台插件平台化评估
|
||||
|
|
|
|||
|
|
- 日期:2026-09-11
|
|||
|
|
- 输入:用户提问「能否模拟 admin 安装到 dsh 服务器功能插件中/是否支持多用户/数据与产物如何存储/每个插件自带数据库有无风险/功能插件调用 skill 应整合还是外置」
|
|||
|
|
- 分析对象:`C://Users//Administrator//.dsh//profiles//web//node_modules//` 下的 `dsh-plugin-mcn`(主)、`dsh-plugin-social-workbench`、`dsh-plugin-mcn-schedule`、`dsh-plugin-douyin-*`
|
|||
|
|
- 结论一句话:**机制上可作为"功能插件"投放,但有 3 处必须先改**(DSH_HOME 路径、技能路径硬编码、agent preset 随包投放);**多用户天然成立**(每用户独立实例 → 每用户一份 DB);**技能应"外置"**(平台共享技能层),插件只按名引用。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 一、先看结论(对应你的 5 个问题)
|
|||
|
|
|
|||
|
|
| # | 你的问题 | 结论 |
|
|||
|
|
|---|---|---|
|
|||
|
|
| 1 | 能否模拟 admin 安装为**功能插件** | ✅ 机制可行(标准 bundle:`dsh.client` + `cordis.patch.yml` insert 一行)。**但需 3 处改造**(见 §三),否则装上去功能会残 |
|
|||
|
|
| 2 | 是否支持**多用户** | ✅ 天然成立:平台是"每用户独立实例 + 独立 `DSH_HOME` + uid/bwrap 隔离"→ 插件的单租户 DB **变成每用户一份**,无需加 `userId` 列 |
|
|||
|
|
| 3 | **数据与产物**存储 | DB 在 `DSH_HOME`(平台里 = `<userRoot>/home`,用户在 `ws` 里默认看不到);**产物写在用户工作区内**(如 `视频对标/…/analysis.json`)→ 天然按用户隔离 |
|
|||
|
|
| 4 | 插件**自带数据库**有无风险 | 总体可接受:`node:sqlite` 在平台 Node **22.23.2 实测可用**;风险点见 §五(实验 API 随 Node 变动、用户可损坏自己的库、需备份/重建路径) |
|
|||
|
|
| 5 | 功能插件**调用 skill** 应整合还是外置 | ✅ **外置**(放平台共享技能层),插件**只按技能名引用**;**preset 随插件投放**;MCP 建议**预装**而非每次 `npx` 拉包 |
|
|||
|
|
|
|||
|
|
## 二、插件形态解剖(实测证据)
|
|||
|
|
|
|||
|
|
| 维度 | 事实 |
|
|||
|
|
|---|---|
|
|||
|
|
| 包形态 | `dsh-plugin-mcn`(569K):`dsh.client{platform:web, inject:[dsh-client-runtime, dsh-client-ui-sidebar]}` + `dsh.bundle.patch → cordis.patch.yml`(`insert: mcn-nav → dsh-plugin-mcn`) |
|
|||
|
|
| Host 面拆分 | `lib/{index,db,data,http,mcp,imports,video-tools,workshop,config}.js` |
|
|||
|
|
| 数据库 | `node:sqlite`(`DatabaseSync`),`DB_PATH = join(homedir(), ".dsh", "mcn-plugin.db")`;另读 `homedir()/.dsh/storages/workspace.json`、写 `homedir()/.dsh/mcn-rank-update.json` |
|
|||
|
|
| 表结构 | 10 张表(`hot_accounts` / `account_videos`(362 行) / `account_video_analysis` / `account_persona` / `account_analysis` / `account_video_source` / `creative_log` / `rewrite_log` / `storyboard_log` / `script_review`):**按 `account_id` 组织,无 `userId`/`owner` 字段**(= 单租户设计) |
|
|||
|
|
| 技能调用方式 | **插件不执行技能**:UI 收集参数 → **拼提示词**要求 agent 调用具名技能("请调用「mcn-dou-analysis」技能(路径 `~/.dsh/skills/mcn-dou-analysis/`,已全局注册)…") |
|
|||
|
|
| 硬编码技能路径 | `~/.dsh/skills/` 下:`mcn-dou-analysis` ×6、`script-review` ×3、`short-video-script` ×2、`storyboard-prompt` ×1、`mcn-data-insight` ×1 |
|
|||
|
|
| 能力来源 | `agentPreset`:`ctx.get("agentPresets").resolve("mcn")` + `presets.mount(agentCtx, resolvedId)`;preset 实体在 `<DSH_HOME>/.agent-presets/mcn/{preset.yml, agent.cordis.yml}`(挂 persona / agent-instructions / tool-bash / tool-fs / tool-fs-search / … ) |
|
|||
|
|
| MCP | 自带 **stdio MCP 客户端**(`mcp.js`):`npx myai-mcp`(`NPX_CMD` / `MCP_PACKAGE` / `MCP_ENV`);**且该文件已优先读 `DSH_HOME`**(正确写法) |
|
|||
|
|
| 产物落点 | 用户工作区(如 `{产出根}/<账号>/视频对标/<视频>/analysis.json`);Excel 导入用 `xlsx` |
|
|||
|
|
|
|||
|
|
> 关键洞察:插件的**能力 = preset**(preset 决定挂哪些工具/技能/MCP),插件本体只是 **UI + 数据 + 提示词编排**。
|
|||
|
|
|
|||
|
|
## 三、平台化必改清单
|
|||
|
|
|
|||
|
|
| 优先级 | 改动 | 现状 → 目标 | 为什么 |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| **P0** | **DSH_HOME 路径** | `join(homedir(), '.dsh')` → `process.env.DSH_HOME ?? join(homedir(), '.dsh')`(`config.js` 3 处:`DB_PATH` / `storages/workspace.json` / `mcn-rank-update.json`) | 平台里 `HOME=<userRoot>/ws`、`DSH_HOME=<userRoot>/home`,**两者不等** → 现状会写到 `<ws>/.dsh/`,并**读不到真正的 `storages/workspace.json`**(工作区/账号目录定位失效)。`mcp.js` 已是正确写法,可对照 |
|
|||
|
|
| **P0** | **技能路径** | 删除 `~/.dsh/skills/<name>/` 硬编码(共 13 处),只保留**技能名**;或读平台注入的技能根(共享只读层 env) | 平台技能是"**共享只读层 + 个人层**"两段式(档案 10/11),且实例 `HOME=ws` → `~/.dsh/skills` 不存在;agent 按"已注册技能名"即可加载,不必给路径 |
|
|||
|
|
| **P0** | **agent preset 随包投放** | `<DSH_HOME>/.agent-presets/mcn/` 必须在用户实例里存在 | 平台每用户 `DSH_HOME` 独立 → preset 无人写进去就退化为默认 preset(注释已写明"否则工具集为空/能力缺失")。建议:随插件包或平台 provisioning 写入 |
|
|||
|
|
| **P1** | **MCP 预装** | `npx myai-mcp` → 预装到镜像/实例(或内置实现) | 平台实例有 **512M 内存 + 出网护栏 + 无外网缓存**,每次 `npx` 拉包会慢且可能首启失败 |
|
|||
|
|
| **P1** | **DB 备份/重建路径** | 增加"库损坏 → 重建空库"的兜底(表结构可重建) | 用户在实例内可写 `DSH_HOME`(只有 `cordis.patch.yml`/`package.json`/`pnpm-lock.yaml` 被 ro-bind,DB 不在其中)→ 有自伤风险 |
|
|||
|
|
| **P2** | **技能依赖声明** | 插件 README/元数据声明"需要哪些技能" | 便于平台侧按需投放;避免"装了插件但技能缺失"的静默失败 |
|
|||
|
|
|
|||
|
|
## 四、投放与隔离(怎么做)
|
|||
|
|
|
|||
|
|
1. **投放路径**:admin 在门户 `plugins.html` 上传 tgz → 进候选池(默认禁用)→ 用户在实例设置「功能插件」勾选启用 → 重启实例生效(档案 16 的既有机制)。
|
|||
|
|
2. **安装**:平台走 `pnpm add file:<tgz>`(HOME=`<userRoot>/ws`)→ 每个用户 profile 一份;**新用户**由 `ensure-*` 脚本族 + provisioning 钩子补齐(参照目录选择器插件的做法)。
|
|||
|
|
3. **隔离**:DB/产物/技能都在该用户自己的实例内(uid + bwrap)→ 用户间互不可见;跨租户不成立。
|
|||
|
|
4. **多用户注意**:`mcn-schedule`(定时任务)与 `dsh-plugin-social-workbench` 是独立包,**要一起投放**否则功能缺失;`mcn-schedule.json` 同样在 `DSH_HOME` 根 → 与 P0 同改。
|
|||
|
|
|
|||
|
|
## 五、自带数据库的风险评估
|
|||
|
|
|
|||
|
|
| 风险 | 评估 |
|
|||
|
|
|---|---|
|
|||
|
|
| 引擎可用性 | ✅ 实测:平台 Node **22.23.2** 直接 `require('node:sqlite')` 成功(仅 `ExperimentalWarning`) |
|
|||
|
|
| 与平台 DB 冲突 | ❌ 无:平台用 `better-sqlite3`(`/var/lib/dshs/*.db`),插件用自己的文件,互不相干 |
|
|||
|
|
| 并发 | ❌ 无:每用户独立实例,DB 无跨进程并发 |
|
|||
|
|
| **实验 API 变动** | ⚠️ 中:`node:sqlite` 在不同 Node 版本间 API 可能变 → 应补进**档案 26 升级耦合点**(Node 升级时回归) |
|
|||
|
|
| **用户可损坏自己的库** | ⚠️ 中(自伤):实例内可写 `DSH_HOME` → 建议加"重建空库"兜底(P1) |
|
|||
|
|
| 体积/性能 | ✅ 低:本地 4.2MB(10 表、362 视频行);每用户一份,磁盘可控 |
|
|||
|
|
|
|||
|
|
## 六、技能:为什么"外置"而不是"整合进插件"
|
|||
|
|
|
|||
|
|
| 维度 | 整合进插件 | **外置(推荐)** |
|
|||
|
|
|---|---|---|
|
|||
|
|
| 体积 | 技能副本 × 用户数(每个 profile 一份) | 共享只读层**一份**(档案 10/11) |
|
|||
|
|
| 更新 | 改技能要重装插件 + 重启 | 改技能层即可,插件不动 |
|
|||
|
|
| 与平台能力冲突 | 与"技能管理面(共享/个人技能上传)"冲突 | 复用平台既有技能管理面 |
|
|||
|
|
| agent 加载 | 插件得自己把技能挂进 preset | agent **按技能名**加载已注册技能 ✓ |
|
|||
|
|
| 结论 | ✗ | ✅ |
|
|||
|
|
|
|||
|
|
**做法**:插件里把 13 处 `~/.dsh/skills/<name>/` 换成**只写技能名**(或由平台注入技能根,插件读 env);技能本体由平台技能层(共享只读 + 个人)投放;**preset 仍需随插件投放**(它是"这次会话挂哪些工具"的清单,属插件能力的一部分)。
|
|||
|
|
|
|||
|
|
## 七、落地建议(分三步,建议顺序)
|
|||
|
|
|
|||
|
|
1. **改造(插件侧,P0 三项)**:DSH_HOME、技能路径、preset 投放 → 这是"能不能跑"的门槛;
|
|||
|
|
2. **投放(平台侧)**:按功能插件机制上架 + 新用户自动铺开(复用 `ensure-workspace-picker.cjs` 的`--user-id` 模式,扩成通用 `ensure-plugin` 脚本);
|
|||
|
|
3. **加固(P1)**:MCP 预装、DB 重建兜底、技能依赖声明。
|
|||
|
|
|
|||
|
|
## 八、红线与回归
|
|||
|
|
|
|||
|
|
- 不修改官方 dsh 包;投放走功能插件机制(档案 16);新用户铺开走 provisioning 钩子(档案 18 v3 做法)。
|
|||
|
|
- 升级回归需补两条:① `node:sqlite` API(Node 升级)② 功能插件 client bundle 契约(档案 26 §C4)。
|
|||
|
|
|
|||
|
|
> 本文为**评估**(只读分析 + 推荐),未改动插件源码;改造需按 §七 分步实施并逐项验证。
|