返回 Skills 目錄
dontbesilent2025/dbskill包含需要注意的行為

SKILL DETAIL

dbs-update

dontbesilent2025/dbskill/dbs-update

This skill updates the official dbskill repository while ensuring the user's archives, reports, and decision records remain intact. It only updates the official repository dontbesilent2025/dbskill, does not touch other user-installed skills, and does not create background tasks or scheduled jobs. When the user explicitly requests an update, upgrade, or version check, or replies with "1" after an update reminder, this skill performs the update. The process runs an npx command to sync all official skills and records the update time to avoid redundant reminders. On success, it informs the user to start a new conversation to use the new capabilities; on failure, it briefly explains the reason and guides the user to resolve permission or network issues.

安裝量 · 278查看來源

Installation

npx skills add https://github.com/dontbesilent2025/dbskill --skill dbs-update

技能檔案

SKILL.md

最近同步 · 2026年10月18日

agents/openai.yaml›
interface:
  display_name: "dbs-update(更新 dbskill)"
  short_description: "按原安装渠道同步官方 dbskill 更新,保留用户存档与其他 Skill"
  default_prompt: "使用 $dbs-update,同步官方 dbskill 更新并保留用户本地资产。"
references/retired-skills.json›
{
  "skills": [
    {
      "name": "dbs-hook",
      "sha256": [
        "1d63c667d0c55e6565ca132cc791551dcbdf9940dc9876c84c7decc76b17f787",
        "234e52bd6c73dcc9a3e23391062c9d88124d9e912e690bfc4b428d100440e8ca",
        "6198fff3ea0fd68af4dd9af35ad1b15ed7492b98cb91225db8f8d2b3650385a1",
        "6e390d47956cdcc7e8e57529086436bb5492b73633647ad4e03e384b7041707d",
        "902dc2a10940c365cd4da07237117cf14c7ed8f2300782c4f9c333160193532b",
        "a7f9cf1ffe9f218d8fd91f7f2ed767fcd7294c9dbaadfbfce490e65d48329816",
        "a98318aa6f80dfdfa400e24946d1ee99a83f31ce79acf78d4aba99b021010a30",
        "af6352b3d597f6715ca63a10d4dae7f7f1a337a08ceed4d31ec31abcabab644a",
        "b406be716e55784080d55dacf11c2bc023a2f530b01cc80ec965357ec2ff7c08"
      ]
    },
    {
      "name": "dbs-xhs-title",
      "sha256": [
        "0034c63254b9a5dd4ec57fb7d9691e0a97acfb250e7c75508494e1a79a3af79b",
        "23fe0120c6ba53afcf6b927c4025ecc78704f2e18c758b74f78526fef8abcee8",
        "44ca91d64219b06c83884e353dbb9f1f86dccbd4d40b5a4b9d3a94f044a9d762",
        "acbe10ee171c2104227e5e5837003eac0ed5bd7b9685ce1220d6dd93c35edb5a",
        "c765d6e32a8850fadc6f7fd306763ca5b78995deb97e6377ae92bcac143be8c5",
        "ede07db0f582b416f669d45cf42f2b9547d135b8edf9fa17d437d5f944765a0e",
        "f4ebeff529c0526a476708b15b7c88b00791a5bc2914d4a0d15957b2187e7919"
      ]
    }
  ]
}
scripts/cleanup_retired_skills.py›
#!/usr/bin/env python3
"""清理本机残留的已下线 dbskill Skill。

只处理 references/retired-skills.json 中登记的名称,并且只处理能确认来自官方的副本:
- 失效链接(目标已不存在):移除链接;
- 指向官方历史版本的链接或目录联接:只移除链接本身,不碰目标;
- 内容与官方历史版本完全一致的目录:移到 ~/.dbs/retired-skills/<时间>/ 备份,不直接删除;
- 本工具生成、且真源已不存在的 Grok 适配层:同样移到备份目录。
内容被改过、指向其他来源或无法识别的同名项一律保留,并在结果中列出。
"""

from __future__ import annotations

import argparse
import hashlib
import json
import os
import shutil
import sys
import time
from pathlib import Path


SCRIPT_DIR = Path(__file__).resolve().parent
RETIRED_PATH = SCRIPT_DIR.parent / "references" / "retired-skills.json"

# 与 dbs-install-skill 支持的 Agent 目录保持一致,含已停止维护的旧目录。
AGENT_SKILL_DIRS = (
    ".agents", ".claude", ".codex", ".workbuddy", ".hermes", ".kiro", ".qwen", ".cline",
    ".aider-desk", ".augment", ".codeartsdoer", ".codebuddy", ".codemaker", ".codestudio",
    ".continue", ".copilot", ".cursor", ".factory", ".forge", ".gemini", ".junie",
    ".kilocode", ".openclaw", ".openhands", ".qoder", ".roo", ".trae", ".trae-cn",
    ".vibe", ".zencoder",
)


def normalized_sha256(path: Path) -> str | None:
    try:
        return hashlib.sha256(path.read_bytes().replace(b"\r\n", b"\n")).hexdigest()
    except OSError:
        return None


def is_link(path: Path) -> bool:
    return path.is_symlink() or (hasattr(os.path, "isjunction") and os.path.isjunction(path))


def remove_link(path: Path) -> None:
    if path.is_symlink():
        path.unlink()
    else:
        os.rmdir(path)  # Windows 目录联接:只移除联接本身


def grok_bridge_source(skill_file: Path) -> str | None:
    try:
        text = skill_file.read_text(encoding="utf-8")
    except OSError:
        return None
    if "## Grok Bridge" not in text:
        return None
    for line in text.splitlines():
        if line.startswith("- Source of truth: "):
            return line.removeprefix("- Source of truth: ").strip()
    return None


def plan_for(path: Path, name: str, known: set[str]) -> tuple[str, str]:
    """返回 (动作, 说明)。动作为 unlink、backup 或 keep。"""
    if is_link(path):
        target = Path(os.path.realpath(path))
        if not target.exists():
            return "unlink", "失效链接"
        if normalized_sha256(target / "SKILL.md") in known:
            return "unlink", f"指向官方旧版本的链接({target})"
        return "keep", f"链接指向其他内容({target})"
    if path.is_dir():
        skill_file = path / "SKILL.md"
        if normalized_sha256(skill_file) in known:
            return "backup", "与官方旧版本一致的副本"
        source = grok_bridge_source(skill_file)
        if source and source.replace("\\", "/").endswith(f"/skills/{name}/SKILL.md") and not Path(source).exists():
            return "backup", "真源已不存在的 Grok 适配层"
        return "keep", "内容与官方版本不一致,可能是你自己的同名 Skill"
    return "keep", "同名文件,不是 Skill 目录"


def main() -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--dry-run", action="store_true", help="只列出计划,不改动文件")
    parser.add_argument("--home", default=os.environ.get("DBS_INSTALL_HOME") or str(Path.home()))
    args = parser.parse_args()

    home = Path(args.home)
    retired = json.loads(RETIRED_PATH.read_text(encoding="utf-8")).get("skills", [])
    backup_root = home / ".dbs" / "retired-skills" / time.strftime("%Y%m%d-%H%M%S")
    result = {"dry_run": args.dry_run, "removed": [], "backed_up": [], "kept": [], "backup_dir": None}

    for entry in retired:
        name = entry["name"]
        known = set(entry.get("sha256", []))
        for agent in (*AGENT_SKILL_DIRS, ".grok"):
            path = home / agent / "skills" / name
            if not (path.exists() or is_link(path)):
                continue
            action, reason = plan_for(path, name, known)
            record = {"path": str(path), "reason": reason}
            if action == "keep":
                result["kept"].append(record)
                continue
            if action == "unlink":
                if not args.dry_run:
                    remove_link(path)
                result["removed"].append(record)
            else:
                destination = backup_root / agent.lstrip(".") / name
                if not args.dry_run:
                    destination.parent.mkdir(parents=True, exist_ok=True)
                    shutil.move(str(path), str(destination))
                    result["backup_dir"] = str(backup_root)
                record["backup"] = str(destination)
                result["backed_up"].append(record)

    print(json.dumps(result, ensure_ascii=False, indent=2))
    return 0


if __name__ == "__main__":
    sys.exit(main())
SKILL.md›
---
name: dbs-update
description: 更新官方 dbskill,并保留其他 Skill 与用户存档。用户要求更新、升级、检查 dbskill 版本,或在更新提醒后回复 1 时使用。
---

# dbs-update:更新 dbskill

用户已经明确要求更新 dbskill,或在上一条 dbskill 更新提醒后回复了 `1`。两种情况都直接执行更新,不再做第二次文字确认;宿主若要求 Shell 权限,由用户在宿主的权限窗口中决定。

只有上一条助手回复明确包含 dbskill 更新提醒时,单独回复的 `1` 才代表更新。缺少这段上下文时,不要自行解释数字含义。

## 更新范围

- 只更新官方仓库 `dontbesilent2025/dbskill`。
- 保留用户在 `~/.dbs/` 中的存档、报告和决策记录。
- 不更新用户安装的其他 Skill。
- 清理已下线的官方旧入口时,只处理能确认来自官方的副本;用户改过的或同名的自有 Skill 一律保留。
- 不创建后台任务、定时任务或 Agent Hook。

## 执行步骤

1. 判断 dbskill 的安装渠道。两种渠道可能同时存在,只更新实际检测到的渠道:

   - **Claude Code 插件**:本 Skill 所在路径包含 `/.claude/plugins/`,或 `claude plugin list` 的输出中有以 `@dontbesilent-skills` 结尾的插件。
   - **Skills CLI**:`~/.agents/skills/`、`~/.claude/skills/` 或其他 Agent 的 Skill 目录中存在 `dbs` 等官方 Skill,且它们不在 `/.claude/plugins/` 下。

2. 更新 Claude Code 插件渠道:先刷新 marketplace,再逐个更新 `claude plugin list` 中以 `@dontbesilent-skills` 结尾的插件。

   ```bash
   claude plugin marketplace update dontbesilent-skills
   claude plugin update dbs@dontbesilent-skills
   ```

   用户单独安装过其他插件(例如 `dbs-diagnosis@dontbesilent-skills`)时,对每个插件分别执行 `claude plugin update`。不要为插件用户再执行 Skills CLI 安装,否则会多出一套副本。

3. 更新 Skills CLI 渠道:

   ```bash
   npx -y skills add dontbesilent2025/dbskill -g --all
   ```

   两种渠道都检测不到时,按这个命令更新。

4. 清理已下线的官方旧入口。名单与官方历史版本指纹在本 Skill 的 [references/retired-skills.json](references/retired-skills.json):

   - **Claude Code 插件渠道**:`claude plugin list` 中以 `@dontbesilent-skills` 结尾、且名称在名单里的插件,逐个执行 `claude plugin uninstall <名称>@dontbesilent-skills`。
   - **本地 Skill 目录**:解析本 Skill 所在目录的绝对路径,运行其中的 `scripts/cleanup_retired_skills.py`(macOS 与 Linux 用 `python3`,Windows 用 `python` 或 `py`)。脚本只移除失效链接和指向官方旧版本的链接;与官方旧版本完全一致的目录移到 `~/.dbs/retired-skills/<时间>/` 备份;其余同名项保留并说明原因。
   - 当前环境没有 Python 时跳过脚本,在回复中列出名单里的名称,请用户自行检查各 Agent 的 Skill 目录。

5. 命令成功后记录本次更新时间,避免当前对话仍加载旧 Skill 时重复提醒:

   ```bash
   mkdir -p "$HOME/.dbs" && date +%s > "$HOME/.dbs/update_check_at"
   ```

6. 根据命令的退出状态确认是否完成。命令成功时告诉用户更新已完成:插件渠道提醒用户运行 `/reload-plugins` 或新建对话;Skills CLI 渠道提醒用户新建一次对话后再使用新能力。

7. 命令失败时,用一句话说明失败原因和下一步需要用户处理的权限或网络问题。不要把完整终端日志直接贴给用户,除非用户要求。

## 回复格式

成功:

> dbskill 已更新完成({更新的渠道})。当前对话如果还没有读取到新能力,{插件渠道:运行 `/reload-plugins`;其他渠道:新建一次对话}后即可使用。

清理了旧入口时追加一句:

> 已清理下线的旧入口:{名称与位置}。{有备份时:原文件备份在 `{备份目录}`。}{有保留项时:`{路径}` 与官方版本不一致,已保留。}

没有残留时不提清理。

失败:

> dbskill 没有更新完成:{简短原因}。处理完 {权限或网络问题} 后,再说一次「更新 dbskill」。

## 边界

- 用户只问版本、更新内容或是否需要更新时,先回答问题,不执行命令。
- 用户明确要求检查更新且希望实际同步时,按本 Skill 更新。
- 不使用 `npx skills update`,该命令可能更新用户安装的其他 Skill。

---

完成当前任务后直接结束。用户的请求超出本 Skill 的范围、任务完成后用户的材料里出现明确的后续需求,或用户询问下一步时,用一句话说明还需要哪种能力,不点名其他 Skill;当前环境已经安装 `/dbs` 时,补一句「可以输入 `/dbs`,由它匹配对应的 Skill」。