npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@luoxunhao/dsh-skill-manager

v0.1.5

Published

DSH web plugin: manage skills from the Settings panel — browse the merged skill catalog, read each skill's body, and toggle model/user invocation per skill.

Readme

dsh-skill-manager

DSH 的 web 插件:在「设置 → 技能」分区管理技能——浏览合并后的技能目录、查看每个技能的正文(body)、按技能切换模型/用户调用策略。

挂载

dsh plugin --profile <name> add dsh-skill-manager

本地开发用 dsh 源码根目录:

pnpm dsh web --patch <本仓库绝对路径>/cordis.patch.yml

host half(Node 侧)改动需重启 dsh web;client half(UI)改动浏览器硬刷新即可。

dsh 技能加载机制

插件建立在一个核心事实之上:dsh 的技能不是一次性注入的会话配置,而是一个运行时动态合并、按需重读的目录系统。 理解这套机制才能理解本插件为什么这样设计。

1. 技能从哪来:四个发现根,合并成目录

dsh 在启动时从四个根目录发现技能(packages/skill/src/index.ts):

| 发现根 | 作用域 | 路径 | |---|---|---| | dsh.skills(已配置目录) | project | 项目源码树里的 skills/ | | user-dsh | user | ~/.dsh/skills/ | | user-agents | user | ~/.agents/skills/(Docker/Codex 技能根) | | 其他自定义源(@deepseek-ai/dsh-skill-filesystem 的 provider) | — | 各 provider 自行声明 |

所有来源合并为一个共享目录(catalog),目录条目就是技能的「注册表定义」,每个定义带 namedescriptionsource(来源桶)等元数据。每个技能对应磁盘上的一个目录:<root>/<skill>/SKILL.md(frontmatter + 正文)。

2. 三个对象

  • 注册表定义(registry definition)ctx.skills.get(name) 返回的目录条目。source 字段表明它来自哪个发现根。
  • skill 工具执行/skill 斜杠指令或模型自动调用触发时,@deepseek-ai/dsh-skill 从注册表找到定义,再从磁盘读取该 SKILL.md 的正文。
  • 文件系统 provider@deepseek-ai/dsh-skill-filesystem 用 chokidar 监视各技能根目录,文件变化时自动更新注册表定义并失效缓存。

3. 调用策略由两个 frontmatter 字段决定(不是加载机制的一部分)

每次从磁盘读取定义时,解析 frontmatter 中的两个键(skill-filesystem/src/index.ts:996-1000):

modelInvocable: disableModelInvocation !== true,   // 缺席 → 默认 true(模型可调用)
userInvocable: userInvocable !== false,            // 缺席 → 默认 true(用户可调用)
  • disable-model-invocation模型是否可自动调用。名字带 disable-,是反向键false = 模型可调用,true = 禁用。
  • user-invocable用户是否可通过 /skill 斜杠指令手动调用。正向键true = 用户可调用,false = 禁用。

两个键语义独立:disable-model-invocation: false + user-invocable: true 字面相反,但表达同一个状态「全部启用」。缺省即启用——字段缺席时两者都默认 true;只有主动修改后字段才会写进文件。

「开关」只是元数据。真正决定「调不调得起」的是:模型侧由 tool-skill 在每次 agent/pre-step 重新计算目录摘要(digest)并过滤不可调用的技能(变了才追加一条替换消息,没变不重复),用户侧由 /skill 指令每次执行前从磁盘重读正文并检查 user 门禁。

4. 关键结论(决定本插件设计的事实)

  • 技能目录不是会话开始时一次性注入的tool-skill 在每个请求的 pre-step 重算 digest;skill 工具执行时每次从磁盘重读正文(fresh-definition 门)。因此修改 SKILL.md 后,下一条请求即被感知,无需重启 dsh、无需重新加载会话。
  • 技能文件内容不能被锁死在内存里。dsh 每次真正使用时都回读磁盘;插件修改 frontmatter 后必须保证落盘且文件格式合法,dsh 的 watcher 会自动把新状态同步进注册表。
  • 来源桶是元数据,不参与调用策略user-agents 等 source 徽标只表示「从哪发现」,以及只读性(bundled/runtime 来源的技能不可写、不可开关)。
  • 技能根可能对进程不可见。例如 ~/.agents/skills 可能被某些项目的 ctx.fs 遮蔽(resolve 失败返回 0 技能),此时必须走独立于 ctx.skills 的磁盘兜底才能管理这些技能。

插件实现对照

| 加载机制事实 | 插件做法 | |---|---| | 注册表 + 磁盘双层 | 列表优先用注册表,磁盘兜底合并;正文读取注册表优先、磁盘兜底(getSkillBody),保证所有技能都能查看正文 | | 双键语义相反 | 单个「启用」开关同时写两键:启用 → disable-model-invocation: false + user-invocable: true;关闭 → 相反。两键始终成对写、永不删除 | | 文件会被 dsh 实时重读 | 修改走原子写(临时文件 + rename,Windows 下 EPERM 重试并降级就地写),落盘即生效 | | CRLF 兼容 | frontmatter 解析/写入对换行无关,不破坏文件原 EOL |

开发

pnpm typecheck   # 类型检查
pnpm test        # vitest 单元测试
pnpm build       # 构建 lib/
pnpm pack --pack-destination <dir>   # 出 tarball(pnpm build 与 pack 分开跑)

重装同版本 tarball 到真实 profile:先删 <profile>/node_modules/dsh-skill-manager<profile>/pnpm-lock.yaml,再 dsh plugin --profile <name> add file:...tgz

验证:

  • GET /skill-manager/api/workspaces(工作区列表,项目级下拉数据源)
  • GET /skill-manager/api/skills?scope=user(用户级目录)、GET /skill-manager/api/skills?scope=project&cwd=<workspace>(该工作区项目级目录,仅 project-dsh/project-agents
  • GET .../<name>/body?scope=...&cwd=...(正文)、PUT .../<name>/invocation?scope=...&cwd=... { enabled }(开关,200 后文件双键同步)
  • 项目级缺 cwd → 400 missing cwd for project scope