Files
workbuddy_skills/dsh-workflow/references/dsh-change-workflow/05-插件与数据源口径.md
T
admin e03465c398 按用户令提交:把此前未纳管的 9 个技能目录一并入库
用户令逐字:「E:/ProgramData/.workbuddy/skills  提交仓库是指的这里」——
即本目录就是仓库(2026-10-07 已在本目录建仓,见当日日志 §22),本轮把余下未纳管的 9 个技能一并提交。

本次入库(9 个技能,46 个文件):
1、`AI HOT`
2、`draw-ui`
3、`dsh-diagnose`
4、`dsh-knowledge`
5、`dsh-local-env`
6、`dsh-opensource-release`
7、`dsh-workflow`
8、`oil-motion`
9、`skills-security-check`

提交前核对:
· **凭据类扫描**(`*.env` / `*token*` / `*.key` / `*secret*` / `*.pem`)⇒ **零命中** ✓;
· 体积合计约 20 MB(`draw-ui` 12M + `oil-motion` 6.5M 是大头,形态为配图/素材 ——
  仓库 `.gitignore` 里明写「`assets/*.png` 是内容不是产物」⇒ 属刻意入库);
· 运行产物仍按既定规则排除(`__pycache__` / `logs/` / `tmp/` / `.venv/` / `*.egg-info` / `uv.lock` / `.workbuddy/`)。
2026-10-08 22:29:08 +08:00

6.8 KiB
Raw Blame History

插件与数据源口径 · 缓存版本守卫 / 白名单来源 / 技能 vs 插件 / 术语与环境约定

归属:技能 dsh-change-workflow 的详情档(按需读,不是每次都要读)。 本档覆盖:外部数据源缓存必须带结构版本守卫 · 官方白名单插件来源 · 技能 vs 插件:怎么区分 · 术语与环境约定(原行 L539–L554 + L907–L934)。 主文件 / 判据与流程主干 = ../SKILL.md(§1 六阶段流程 · §2 红线 R1–R8 原文速查 · §3 本机 Git Bash 环境坑 · §4 并行调度结论)。 来源:2026-09-22「技能重组线」把 ../SKILL.md 的 L539–L554 + L907–L934 段逐行原样下沉到本文件,未改一字。 跨档引用:正文里的「§N / 见 §8 坑 N / 见下表」等编号,用 ../SKILL.md 末节「详情索引」的原章节列定位。 维护:本文件与 ../SKILL.md 的指针行成对;改内容时同时核对主文件的指针描述是否仍准确。


外部数据源缓存必须带结构版本守卫(2026-09-11 实证)

换数据源或在缓存条目里增删字段时,必须同时 bump 一个 CACHE_VERSION,并在读缓存时校验版本/结构(不符即视为未命中重拉)。

踩坑实录(档案 29):白名单路由从「git clone + 解析 yml」改为「拉 plugins.json」后,whitelist-cache/index.json 仍是旧格式且 fetchedAt 在 TTL(6h)内 → 被直接复用 → 条目缺 owner/importKind 字段 → 按字段过滤时 e.owner.toLowerCase() 抛异常 → 接口 500。加 CACHE_VERSION 守卫后自动重拉修复。

配套好习惯:① 缓存读失败/不可用时降级用旧缓存并返回 stale: true,前端提示;② 排序按「热度」字段降序,让无效条目自然沉底,默认首页就是最有价值的那些。

官方白名单插件来源(档案 29 定型口径)

  • 数据源:https://awesome-dsh-plugin.com/plugins.json(官方规范地址,3.1MB / 3408 条 / 23 分类;npm 镜像包 dsh-plugin-catalog)。字段:name/owner/url/page/category/description{zh,en}/npm/version/stars/downloads/install/added。不要再去 git clone 仓库解析 3431 个 yml —— 其 tarball 是可选字段,覆盖率仅 6%(211/3431)。
  • 导入口径 = 仅预构建(平台侧绝不执行第三方构建脚本):有 npm → registry.npmjs.org/<name> → dist-tags.latest → dist.tarball(scoped 包地址 @scope%2Fname,即 encodeURIComponent(name).replace('%40','@'));有 tarball → release 资产;两者皆无(install 为 github:owner/repo)→ 拒绝并回显原因。可导入 1792/3408 = 52.6%,官方下载量 TOP10 全覆盖。
  • npm 官方 tarball 可直接喂现有 stageTgzArchive(package/ 包装层已被 findPackageJson 兼容)→ 无需改 DB schema。
  • 筛选排序技巧:给列表加 onlyImportable=1,并在前端把「只看可导入」默认打开;按 downloads 降序使未发 npm 的条目自然沉底。
  • 安全兜底不外包:收录 ≠ 安全审计(上游 README 明确)。所有导入包仍走平台 stageTgzArchive 扫描,P0 命中即阻断,并把原因在页面内回显给 admin 判断(例:热门插件 FuRongJun-1999/dsh-memory 因 docs/…example.yml 被判 P0,疑似误报)。

技能 vs 插件:怎么区分(2026-09-11 更正,别用"有没有代码/界面"判)

先纠正一个常见误解:技能可以带 scripts/(实证:短视频工作台/scripts/MCN_CYLG_API.py、mcp-config.json)。所以「技能=纯内容无代码」「不带界面的插件就是技能」都不成立。

正确判据 = 「代码何时、被谁执行」:

技能(skills) dsh 插件(plugins)
包形态 目录 + SKILL.md(+ scripts/、references/) npm 包 + dsh.bundle.patch(+ 可选 client.js)
代码执行者 agent 通过 bash 工具按需调用(SKILL.md 指示 → 模型决定) cordis 在实例启动时加载执行(无人决定)
是否经审批/沙箱 ✅ 走统一工具管线(approval + 沙箱 + uid/cgroup) ❌ 不经,它自己就是实例进程的一部分
参与框架生命周期 否(纯文件) 是(注册服务/工具/UI,进 profile.bundles)
装载时机 运行时按需发现,watch 即时生效 启动时,改后必须重启
失败后果 脚本报错 / agent 表现不佳 实例起不来(崩溃循环)
透明度 命令进会话记录,可追溯 静默运行

可编程判据(我们代码里已在用):看包里有没有 dsh.bundle(isBundle() 判 dsh.bundle.patch)→ 有=插件,无=技能。有无 client 面(UI)只是插件的可选属性,与"是不是技能"无关。

风险分层(理由要准):技能低风险靠三条——惰性(不调用不执行)+ 可见(命令在 transcript)+ 失败不致命;插件高风险的核心理由是 开机即执行、无人介入、失败致命。

⚠️ 注意:档案 33 把默认档改成 danger-full-access + approval: never 后,技能脚本也不再弹确认(仍受沙箱/uid/cgroup 约束),两条路线的"人工拦截面"差距因此缩小——分层的主要依据从"审批"转为"是否被框架主动加载 + 失败是否致命"。

术语与环境约定(2026-09-11 档案 38b)

  • 术语:统一叫「功能插件」(2026-09-11 起由「业务插件」改名)。只改显示文案/注释,代码标识符保持不变:表名 business_plugins、包名 @dsh-local/business-plugins、section id business-plugins、API 路径 /api/plugins/{business,mine}、文件名 business-plugins.ts / ensure-biz-plugins.cjs、目录 poc/business-plugins/。
  • ensure-biz-plugins.cjs 已是「版本感知 + 自动取最新产物」:升级流程 = 把新包丢进 /opt/dsh/artifacts/ → 跑一次脚本(落后会自动 pnpm add)。升级时不要先删旧包,否则依赖表里的旧 file: 指向失效文件会让 pnpm 整体 ENOENT 失败(正确顺序:先放新包 + 改依赖指向 → pnpm add → 再删旧包)。
  • .gitignore 已忽略 *.bak-*:git add <dir> 会把同目录的未跟踪备份一并暂存(已踩一次)。提交前用 git status --short 核对,或定向 git add <具体文件>。
  • 服务器 Python 是 3.6.8,不要动系统 python3:/usr/libexec/platform-python 是 dnf/yum 的 shebang,替换/升级会直接搞坏包管理器。运维脚本一律用 Node(平台技术栈就是 Node);必须用 Python 时写 3.6 兼容代码(无 subprocess.run(capture_output=)、无 f-string = 调试等 3.7+ 特性)。确需现代 Python 就并行装 python3.11(仓库有),别切 alternatives。