DSH Plugin MarketA community catalog for DeepSeek Harness plugins

dsh-skills-symlink

Verified Skills & agents ★ 2 0.4.0

Project-scoped custom SKILL roots for DeepSeek Harness, with multi-level (category) discovery

What it is

Project-scoped custom SKILL roots for DeepSeek Harness, with multi-level (category) discovery

How to install

Run this in the DSH web profile, then refresh the page.

$ dsh plugin --profile web add 'git+https://github.com/MYSTERY2019/dsh-skills-symlink.git#31cb0719ea47d4fc6a70c3d1776f93c094fc30e5'

DSH versions accepted

>=0.2.1-rc.5

Author and traction

MYSTERY2019 · ★ 2 · Updated 2026-11-04

About this plugin

[](https://github.com/MYSTERY2019/dsh-skills-symlink/releases) [](LICENSE) [](https://github.com/deepseek-ai/deepseek-harness)

[English](https://github.com/MYSTERY2019/dsh-skills-symlink#readme) · [中文](https://github.com/MYSTERY2019/dsh-skills-symlink/blob/main/README.zh.md)

Give every project in [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH) its own set of skills. It replaces the skill symlink from Hermes: one shared library, and each project loads only the categories it lists. The plugin creates no symbolic links; the name only borrows the Hermes term.

✨ Highlights

  • 🗂️ Per-project skill sets: one .dsh/skill-paths.yaml per project, and each project sees only what it lists
  • 📚 One path for a categorised library: maxDepth reads category/skill/SKILL.md layouts up to 6 levels deep
  • 🔥 Hot reload: add or remove a skill without restarting DSH
  • 🛡️ Safe by default: paths and symlinks outside the project are rejected, and the plugin makes no outbound requests
  • 🩺 Diagnostics built in: a log of every root scanned, plus a post-install check script
  • 🧭 Visual overview: see each project's skill mix on the Plugins page

🤔 Why

If you came from Hermes, you will miss its skill symlink. A skill lives once in a central repository, and any project that wants it symlinks it into its own skills directory. Edit the original and every project follows, with nothing to copy. Project A links the three writing skills, project B links the two tools skills, and each sees exactly its own set. Adding a skill is one more link; nothing else changes.

DSH replaced that with skill roots configured through customSkillDirs. Three things break on the way over.

First, each root only accepts //SKILL.md. A library laid out as category/skill/SKILL.md yields nothing when you point at the parent, with no error and no log line.

Second, the setting belongs to the host or the preset, not to the project. Every project sees the same skills, and "this project sees category A only" cannot be expressed.

Third, every skill's name and description goes into context each turn. With a large library that cost is fixed and cannot be scoped down.

This plugin moves the paths into the project, one .dsh/skill-paths.yaml per project, and maxDepth in the plugin row lets it read category folders, so a single parent path is enough. From one library, project A loads 17 skills and project B loads 28.

One library, two projects: A loads 17 skills, B loads 28.

📦 Install

Requires DSH >=0.2.1-rc.5 <0.3.0 (the 0.2.x line), Node.js ^22.19.0 || >=24.0.0, and access to GitHub while installing.

DSH Desktop: open Plugins in the sidebar and add

github:MYSTERY2019/dsh-skills-symlink#v0.4.0

Restart DSH afterwards; dsh-skills-symlink should appear on the Plugins page. The 0.2.x dsh CLI refuses --profile desktop, so Desktop installs from the Plugins page only.

Other profiles (for example web) from the command line:

dsh plugin --profile web add github:MYSTERY2019/dsh-skills-symlink#v0.4.0

You can also download dsh-skills-symlink-0.4.0.tgz from the Release and pass its path instead of the github:... spec.

🚀 Use

Create .dsh/skill-paths.yaml in the project root:

version: 1
skillPaths:
  - skills
  - tools/skills

The project now sees only the skills under those two directories. Other projects do not. Paths are relative to the project root (the nearest Git root, otherwise the session's working directory).

A shared library outside the project needs allowExternalPaths in the plugin row first (see Configuration). Without it, that entry is skipped and the log says why:

# needs allowExternalPaths: true in the plugin row
version: 1
skillPaths:
  - ../shared-skills

The project file knows two keys, version and skillPaths. Options such as maxDepth and ignore belong to the plugin row; written into the project file they have no effect. The plugin ignores them, logs where they belong, and still loads the paths. An invalid entry (outside the project, not a string) is skipped on its own as well.

One path for a categorised library

If the library is laid out as category/skill/SKILL.md, the project file still names the parent:

version: 1
skillPaths:
  - skills

and maxDepth in the plugin row says how deep to go (see Configuration):

| Layout | maxDepth |

|---|--:|

| root/skill/SKILL.md | 1 (default) |

| root/category/skill/SKILL.md | 2 |

| root/group/category/skill/SKILL.md | 3 |

Valid values are 1 to 6. Anything else (0, 7, 2.5) is treated as 1, with a warning in the plugin log.

When you add a skill later

| Where you put it | What happens | Work needed |

|---|---|---|

| Inside a category you already list, as category/new-skill/SKILL.md | picked up like its neighbours | none |

Compare in this category

The five most-starred plugins in the same category.

PluginAuthor StarsVersionUpdated
archify tt-a1i 95.2K 0.0.0 2026-11-10
nuwa-skill alchaincyf 37.9K 2.0.1 2026-11-10
distilly titanwings 26.5K 1.0.0 2026-10-13
learn-harness-engineering walkinglabs 24.1K 0.1.0 2026-10-22
dsh-Go ccch1mneyyy 18.1K 0.0.0 2026-11-10