Skip to content

Skills Manager v1.34.0

Choose a tag to compare

@github-actions github-actions released this 15 Aug 14:46

Skills Manager v1.34.0

发布日期:2026-08-16
递交范围:v1.33.1...v1.34.0

发布概览

  • 更新不会再悄悄拿走技能文件夹里的东西。当新版本里没有当前存在的路径时,更新会停下并把它们列出来,而不是直接应用。

用户可见更新

  • 会删掉文件的更新现在会停下,并告诉你是哪些#256)—— 更新是整个替换技能文件夹,所以里面写过、而新版本没有的东西会被无声销毁。报告者丢的是 ppt-master 生成到自己 templates/ 里的 PPT 模板,事后才发现。现在每次更新都会先算出「哪些路径现在存在、而新版本里根本没有」。只要有,就什么都不应用:桌面应用把它们列出来交给你决定,在你决定之前技能原封不动。
  • 无人值守的更新永远不替你做这个决定 —— 启动时的批量更新、后台调度器和 CLI 一律跳过该技能,而不是继续。它的「有更新」角标保留,所以既不会丢也不会被藏起来;你自己手动更新时才会看到具体路径。CLI 以 held_back_removals 报出。
  • 部署出去的副本同样被覆盖,不只是中央库 —— 以复制模式部署的 Agent 目录每次同步都会被重建,写进那个副本里的文件此前面临同样的风险。每条路径都标注了它在哪,你才知道该去哪个目录捞。
  • 重新导入本地技能、以及重新指向来源,也加了同样的守卫 —— 两者都是整个文件夹替换,而且批量按钮把前者也叫「更新」。
  • 一个应当说清楚的限制:这里比较的是路径,不是内容。你改过的、新版本也有的文件路径仍在,会被判为「幸存」,你的改动照样被静默覆盖。请把个人改动放在技能文件夹之外,或在更新前先备份技能库。
  • 支持 DeepSeek Harness —— 部署到 ~/.dsh/skills。开箱支持的 Agent 增至 52 个。
  • Git 备份不再跟踪 Python 编译产物 —— 会运行 Python 脚本的技能,此前每跑一次就往备份仓库里塞一批变动的 __pycache__/.pyc。现在它们被忽略,并从已有备份中取消跟踪。

开发者与治理更新

  • core/removals.rs 只回答一个问题——哪些路径存在于当前目录树而不存在于替换树——不做别的。它按路径比较,因为内容变了的文件更新后仍然存在,列出来只会淹没真正会消失的那些;整个不存在的目录只上报一行,这样用户自建的嵌套 .git 不会用几千个 object 文件淹掉弹窗;文件/目录/符号链接之间的形态变化一律计为移除;对既不能确认存在、也不能确认不存在的路径返回错误而不是猜——一个错误的「什么都不会丢」正是这个模块要防的那种失败。
  • 比较的对象是真正会被换进去的暂存树,而不是原始 clone:installer::copy_skill_dir 会跳过 .git 和所有符号链接,拿 clone 比会产生真实的假阴性。
  • 批准绑定到「修订版 + 精确的、排序后的路径集合」的 SHA-256。确认调用会重新 clone、重新暂存并重算;集合对不上就再次询问,而不是拿一个过期的答案去动手。重新导入和重新指向各自绑定到自己的域。
  • StagedPathGuard 在被拒绝时于 drop 中清理暂存目录,并且只在替换成功之后才释放,所以两者之间的失败不会留下 .staged-<uuid> 目录被元数据重建当成一个新技能收编。
  • 审计日志把被拦下的更新如实记为「held back」,而不是记成一次成功的无变化。
  • manage-skills 技能文档补上了被拦下时的输出形态:字段为空时整个不出现,以及 CLI 没有任何接受它的开关——该字段自己的注释此前指向了一个 skills update 上并不存在的 --force
  • DeepSeek Harness 的路径是从 packages/util/home-pathspackages/skill/skill-filesystem 源码读出来的,不是照搬 README;它共享的 ~/.agents/skills 根目录只登记为发现用途,与 Codex、Copilot 一致。
  • 453 项测试通过。

当前校验状态

  • ✅ 跨平台构建通过(macOS Intel / macOS ARM / Windows x64 / Linux x64)
  • ✅ TypeScript typecheck 通过

English release notes

Release date: 2026-08-16
Commit range: v1.33.1...v1.34.0

Release Overview

  • An update can no longer quietly take away files that live inside a skill's folder. When the new version does not have paths that exist now, the update stops and names them instead of applying.

User-facing

  • An update that would remove files now stops and says which ones (#256) — Updating replaces a skill's folder wholesale, so anything written inside it that the new version does not have was destroyed without warning. The reporter lost the PowerPoint templates ppt-master had generated into its own templates/, and only found out afterwards. Every update now first works out which paths exist today and are simply absent from the new version. If any are, nothing is applied: the desktop app lists them and lets you decide, and the skill stays exactly as it was until you do.
  • Unattended updates never make that decision for you — The startup batch, the background scheduler and the CLI hold the skill back rather than proceed. Its update badge stays, so nothing is lost or hidden; you see the paths when you update it yourself. The CLI reports them as held_back_removals.
  • Deployed copies are covered, not just the library — An agent you deploy to in copy mode gets its folder rebuilt on every sync, so files written into that copy were at the same risk. Each reported path says where it lives, so you know which directory to rescue it from.
  • Re-importing a local skill and re-pointing its source are guarded the same way — Both replace the whole folder, and the batch button calls the first one "update" as well.
  • Known limit, worth stating plainly: this compares paths, not contents. A file you edited that the new version also ships keeps its path, so it reads as surviving and your edits are still overwritten silently. Keep local modifications outside the skill folder, or back the library up before updating.
  • DeepSeek Harness is supported — Deploys to ~/.dsh/skills. 52 agents out of the box.
  • Git backup no longer tracks compiled Python artifacts — A skill that runs Python scripts filled the backup repository with __pycache__/ and .pyc files that change on every run. They are now ignored and untracked from existing backups.

Developer & Governance

  • core/removals.rs answers one question — which paths exist under the current tree and not under the replacement — and nothing else. It compares by path, since a file whose contents change still exists afterwards and listing it would bury the ones that do not; rolls a wholly-absent directory up to a single entry, so a nested .git cannot bury the dialog under thousands of object files; treats a file/directory/symlink shape change as a removal; and returns an error rather than guessing when a path can be neither confirmed present nor confirmed absent, because a wrong "nothing will be lost" is the exact failure it exists to prevent.
  • The comparison runs against the staged tree that actually lands, not the raw clone: installer::copy_skill_dir drops .git and every symlink, so comparing against the clone produced real false negatives.
  • Approving is bound to a SHA-256 over the revision and the exact sorted set of paths. The confirming call re-clones, re-stages and recomputes; a set that no longer matches asks again rather than acting on a stale answer. Re-import and relink bind to their own domains.
  • StagedPathGuard removes a declined skill's staged directory on drop, and is released only after the swap has succeeded, so a failure between the two cannot leave a .staged-<uuid> directory behind for the metadata rebuild to adopt as a new skill.
  • Audit logs record a held-back update as such instead of as a successful no-op.
  • The manage-skills skill documents the held-back shape, including that held_back_removals is omitted when empty and that no CLI flag accepts it — the field's own doc comment had pointed at a --force that skills update does not have.
  • DeepSeek Harness paths were read out of packages/util/home-paths and packages/skill/skill-filesystem rather than taken from its README; its shared ~/.agents/skills root is registered for discovery only, as with Codex and Copilot.
  • 453 tests pass.

Current Verification

  • ✅ Cross-platform build passed (macOS Intel / macOS ARM / Windows x64 / Linux x64)
  • ✅ TypeScript typecheck passed

完整变更v1.33.1...v1.34.0

Full changelog files: English | 中文