用户令逐字:「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/`)。
6.8 KiB
插件与数据源口径 · 缓存版本守卫 / 白名单来源 / 技能 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 idbusiness-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。