Skip to content
dsh.fish
Bundle

dsh-skills

Global skill hub for dsh: aggregates Claude Code, project, and .skill-package skills into ~/.dsh/skills with reference/copy import and slash-menu usage

Source
CocoSgt
stars
16 stars
License
MIT
Updated
Updated 16 days ago

Readme

# dsh-skills

[简体中文](README.zh-CN.md) | English

npm package: `dsh-skills` · GitHub repository:
[CocoSgt/dsh-skills](https://github.com/CocoSgt/dsh-skills)

Third-party skill hub for DeepSeek Harness (dsh): **aggregate skills scattered
everywhere into one global library.** Claude Code's `~/.claude/skills`, project
directories, `.skill` packages — everything lands in `~/.dsh/skills` (the
official skill-filesystem's default scan root, watched live), and once
imported appears in the "/" slash menu of the input box. Adds a "Skills" page
to the settings dialog.

## Two import identities

| | Link (recommended) | Copy |
| --- | --- | --- |
| Implementation | `skills/<name>` is a **symlink** to the source | full tree copy |
| Sync | **No sync problem**: one file on both sides, editing edits the source | evolves independently (state records the source for reference) |
| Source deleted | panel marks it "broken link", one-click removal (source untouched) | unaffected |
| Fits | long-lived sources you maintain | throwaway sources (.skill packages, repos you'll delete), or a global version you can change freely |

The harness's skill scanner, fs provider, and watcher all follow symlinks
natively (skill-filesystem's `nodeEntryKind` handles them explicitly), so
links need no patches and work across every loading form (including SDK/ACP,
where plugins cannot be installed).

## Aligned with how the harness actually works

- **There is no "install"**: a skill takes effect the moment it sits in a scan
  root. This page manages the global library (`~/.dsh/skills`, rank 400, all
  sessions); skills in project directories (`.dsh/skills`, `.agents/skills`,
  rank 100/200) are scanned by the harness directly and never pass through
  this page — that is exactly why they are "always invocable", and why project
  skills win on name collisions.
- **A skill is a file tree, not one MD**: the editor edits `SKILL.md` only and
  tells you how many resource files exist; manage resources via "Open
  directory". Export packages the whole tree as .skill (links are
  dereferenced: real files are packed).
- **Editing a link = editing the source**: the editor header says so; saving
  writes straight to the source file.

## Tabs

1. **Global skills**: the top action row has "+ New skill" (inline expander,
   no scrolling) and "Upload .skill" (imports as soon as a file is picked, no
   intermediate confirmation); a filter box appears with many skills. Each
   card: identity badges (`Link → source` / `Copy` / `Created locally` /
   `Broken link`), resource count, non-default invocation policy; descriptions
   clamp to 3 lines by default (click to expand); primary action "Edit
   SKILL.md", with export / open directory / copy name in the ⋯ menu and an
   inline two-step delete confirmation (links only remove the link).
2. **Discover**: scan directories managed inline as chips at the top (each
   chip shows its skill count or "missing", ✕ removes immediately, + adds in
   place — there is no separate "Sources" tab); each scanned item offers
   "Link" (primary) / "Copy", and "Link all" goes through a single batch RPC;
   a filter box appears with many results.

## Architecture

- **Host half** (`lib/index.mjs`): `SkillHubGateway` extends
  `TypertRemoteService` and exposes three RPCs: `skillHub/getState`,
  `skillHub/runCommand`, and `skillHub/browseDirs` (the last one powers the
   source picker's directory browser). The runCommand payload is a command
   union carried verbatim over src-json. The earlier 3180–3189 port-probing
   sidecar HTTP service is gone. Because SRC discovery is blind in the
   third-party dual-copy scenario, a weak manifest is also registered into
   the host typert registry.
- **Browser half** (`lib/client.js`): $mount identity-codec descriptors →
  `ctx.remote.skillHub`; the panel registers into the `settings.section` slot;
  "Open directory" goes through the official `host.openPath`.
- **i18n**: all visible copy renders through the official locale service.
  zh/en dictionaries live in `src/client/locales.ts`; the slot registration
  declares `locale: NS`, so the framework injects a reactive `t` seat into
  the component props. Host runCommand results carry a stable `code`
  (e.g. `import.linked`, `err.read.notFound`) plus optional `params` and an
  explicit `level: 'error'`; the client translates by code and falls back to
  the Chinese `message` field, and colors the status line by `level` instead
  of guessing from message text.

The state file `~/.dsh/skills/.skill-manager.json` records the source
configuration and each skill's `{mode, source, addedAt}` (schema reserved for
future drift detection). Its filename is deliberately kept from the old
skill-manager so existing installations keep their state.

## Install

Install from npm:

```sh
dsh plugin --profile web add dsh-skills
```

The three dsh plugins can be added together in one command:

```sh
dsh plugin --profile web add dsh-skills dsh-attachments dsh-inspector
```

GitHub fallback:

```sh
dsh plugin --profile web add github:CocoSgt/dsh-skills
```

> Note: a self-built profile's `~/.dsh/profiles/<name>/package.json` must list
> `@deepseek-ai/dsh-base` and `@deepseek-ai/dsh-web-app` in
> `dsh.profile.bundles`, otherwise startup hangs silently.

Restart `dsh web` afterwards. Uninstall:
`dsh plugin --profile web remove dsh-skills`.

## Companion plugins

The other two plugins from the same suite:

- [dsh-attachments](https://github.com/CocoSgt/dsh-attachments)
  ([npm](https://www.npmjs.com/package/dsh-attachments)) — bring any file
  into the conversation as cards above the composer; the model reads images
  by path via `read_image`, so even non-vision models are never blocked.
- [dsh-inspector](https://github.com/CocoSgt/dsh-inspector)
  ([npm](https://www.npmjs.com/package/dsh-inspector)) — an "Instruction
  Files" panel showing the exact AGENTS.md/CLAUDE.md instruction chain in
  effect for the session, in real load order, with in-place editing and
  skill-root status.

## Known limitations

- Drift detection/pull/push between copies and their sources is phase two;
  for now copies only record the source.
- Directory links use junctions on Windows; file-level links fall back to a
  copy without privilege, and say so honestly.
- A linked skill's in-library link name is fixed at import time; if the
  source's frontmatter name changes later, the skill name follows the source
  but the link name does not (harmless — only the directory name and the
  skill name diverge).
- "Link all" runs serially; failures are collected and summarized (first
  failure shown) without flooding the status line.
- Host-side messages for a few low-level failures (e.g. corrupt zip details)
  ride inside a `{message}` param and remain Chinese in the English UI.

## Development

```sh
pnpm install
pnpm run check   # tsc --noEmit
pnpm run build   # tsdown (host ESM + browser bundle)
```

Note: host method parameter names ARE the RPC wire field names (Gateway SRC
mode); the build must never minify or rewrite parameter names.

## Tags

This package and its repository carry the `dsh-plugin`, `dsh`, `deepseek-harness`
and related keywords/topics. DeepSeek Harness ships no official plugin
marketplace and no official discovery tag — once a third-party plugin is
published, nothing links it back to the ecosystem and users have no way to
find it. These community tags are the only practical discovery channel
(npm: `keywords:dsh-plugin`; GitHub: `topic:dsh-plugin`). Unofficial, but
essential — that is why they are here.

## License

MIT

Install

dsh plugin --profile web add github:CocoSgt/dsh-skills#e1eff623f3bd3e6c26a24d49a9ac953e28778cc9

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
Source