xiaxi626/dsh-skills-nexus

xiaxi626/dsh-skills-nexus

通用 skill 适配器,将含 SKILL.md 的 GitHub 仓库克隆并 symlink 到官方 skills 根目录,注册为 DSH skill。

技能包deepseek-harnessdshimport

dsh-skills-nexus

English | 中文

⭐ If this project helps you, welcome to Star for support!

DSH skill lifecycle manager — from git repo cloning, external directory linking, package import/export, to group management, health checks, and cross-machine transport. Keeps up with the latest DSH version, compatible with the official filesystem provider.

dsh-skills-nexus is a community-maintained DeepSeek Harness (DSH) plugin, not an official DeepSeek AI product.

Why

dsh plugin --profile add "github:owner/repo" forwards to pnpm, and only packages with `dsh.bundle.patch` are activated as profile layers. A content repo with just SKILL.md + references/ + scripts/ has no Cordis wrapper, so this path doesn't work. dsh-skills-nexus fills the gap:

command · installs · requires dsh.bundle.patch? dsh plugin add github:owner/dsh-skills-nexus · nexus itself (once) · yes dsh-skills-nexus add github:owner/any-skill · pure SKILL.md content repo · no

Not sure which command fits your repo? Read
nexus vs `dsh plugin` — when to use which.
Short version: repo has SKILL.md → nexus; repo is a pure plugin
(cordis.patch.yml / dsh.bundle.patch, no SKILL.md) → dsh plugin;
has both → your choice (nexus = content, plugin = code).

Install nexus

Optional: register as a DSH plugin

To register nexus in the DSH web profile, run the following (replace web if you use a different profile):

dsh plugin --profile web add "github:xiaxi626/dsh-skills-nexus"

In a web session this adds the Skills Nexus settings panel along with its /skills-nexus/* HTTP routes; in non-web hosts the layer stays dormant. It still does not provide a global CLI command and is not a prerequisite for the CLI install below — skip it if you only need the CLI to manage skills.

Install the CLI globally

Install the CLI globally — this is what puts the dsh-skills-nexus command on your shell PATH (provided npm's global command directory is already on PATH):

npm 12: after confirming that you trust the repository and its dependencies, explicitly allow Git dependencies for this installation:

npm install -g --allow-git=all github:xiaxi626/dsh-skills-nexus

Older npm versions (where Git dependencies are not blocked): the original command works. Choose one of these two commands based on your version and policy:

npm install -g github:xiaxi626/dsh-skills-nexus

Troubleshooting EALLOWGIT

If the original command reports:

npm error code EALLOWGIT
npm error Fetching packages of type "git" have been disabled

npm's Git dependency policy blocked the installation before download; this is not a missing Nexus installation or a repository build failure. Starting with npm 12, allow-git defaults to none instead of allowing Git dependencies. A github:owner/repo spec is a Git dependency and therefore requires explicit permission. Check your version with npm --version; on npm 12, check the active policy with npm config get allow-git.

The stricter default reduces supply-chain risk: Git dependencies access remote repositories and may introduce configuration the project does not control. This error does not mean npm detected malicious code in Nexus, nor does it indicate that Nexus is incompatible with npm 12. There is no need to reinstall the DSH plugin or downgrade npm for this error. If you trust the source, use the command with --allow-git=all above to remove this specific block; subsequent download and installation steps still need to satisfy other requirements.

--allow-git=all applies only to this invocation and does not permanently
change npm configuration. It permits all Git dependencies in this installation,
including transitive dependencies; it does not certify their safety. Avoid
setting allow-git=all globally and permanently. dsh plugin add uses pnpm,
whose configuration is independent of npm's; a successful plugin installation
does not change npm's policy.

lib/ compiled artifacts are committed with the repo, so there is no build step — install and use.

If you only need the published npm registry release (currently 0.3.0), you can use this command instead:

npm install -g dsh-skills-nexus

This installs a registry package, not a Git dependency, so Nexus itself does not require --allow-git=all via this route. The published release may differ from the latest code on GitHub.

The plugin layer is optional. It installs the package into the
profile's node_modules and — when the host is a DSH web session —
registers the settings panel and HTTP routes described in
Web panel. Skill discovery itself never
depends on that layer: skills are picked up through the symlinks nexus
creates in ~/.dsh/skills/ plus the official filesystem provider. The
global CLI comes from the npm installation above (or npm link during
development).

Usage

# register a skill repo (cloned under ~/.dsh/skills-nexus/repos/<name>/)
dsh-skills-nexus add github:owner/repo
dsh-skills-nexus add github:owner/repo#dev          # pick a branch/tag
dsh-skills-nexus add https://github.com/owner/repo
dsh-skills-nexus add https://gitlab.com/group/project  # any git host
dsh-skills-nexus add owner/repo                     # shorthand (GitHub only)
dsh-skills-nexus add github:owner/a github:owner/b  # install several repos in one call
dsh-skills-nexus add github:owner/repo --yes         # skip "wrapped repo?" prompt
dsh-skills-nexus add github:owner/repo --subdir skills/foo   # install one subdir of a collection repo
dsh-skills-nexus add github:owner/repo --subdir skills --name owner-skills   # custom entry name (fallback chain: --name > subdir leaf > repo name)

# inspect / maintain
dsh-skills-nexus list                               # all entries (+ source, commit, subdir, explicit lock, status)
dsh-skills-nexus list --filter <query>              # narrow to entries whose name, URL or subdir contain the query
dsh-skills-nexus list --json                        # ...or the same inventory as a versioned JSON report
dsh-skills-nexus update [name]                      # refresh (branch pin: pull; tag/commit pin: verify)
dsh-skills-nexus switch-version <name> <ref> [--type <branch|tag|commit>]  # move a clone to another ref (fetch, checkout, re-normalize, rebuild links)
dsh-skills-nexus enable  <name>...                  # create symlink (default); several names in one run
dsh-skills-nexus disable <name>...                  # remove symlink without deleting clone
dsh-skills-nexus enable  --group trae-cn/skills     # batch-enable every entry whose groupPath starts with the prefix
dsh-skills-nexus disable --group trae-cn            # batch-disable every entry under the L1 group
dsh-skills-nexus remove <name>...                   # delete clone + symlink + unregister (one or more)
dsh-skills-nexus remove 'theme-*'                   # ...or a * / ? glob matched against skill names
dsh-skills-nexus remove --group trae-cn             # batch-delete every entry whose groupPath starts with the prefix
dsh-skills-nexus remove --group trae-cn/skills      # ...or only the skills sub-group
dsh-skills-nexus doctor [--json] [--updates] [--quiet]  # read-only full checkup of nexus state (exit 0/1/2)
dsh-skills-nexus purge  [--yes] [--json]                # clean up accumulated artifacts (dry-run by default)
dsh-skills-nexus completions --shell <bash|zsh|fish|powershell>  # print a completion script for that shell

# move skills to another machine — a package carries provenance, never .git
dsh-skills-nexus export --all -o migrate.zip        # package every entry (disabled ones included)
dsh-skills-nexus export <name>... -o one.zip        # ...or just some of them
dsh-skills-nexus import migrate.zip --dry-run       # per-entry preview: clone or snapshot; touches nothing
dsh-skills-nexus import migrate.zip                 # rebuild entries from their recorded refs
dsh-skills-nexus import migrate.zip --locked        # restore each exact recorded commit
dsh-skills-nexus adopt <name> --url github:owner/repo   # give a source-less entry its git identity back

# link external skills (reference directories you already own — no clone)
dsh-skills-nexus link trae-cn                       # discover skills under ~/.trae-cn/skills/
dsh-skills-nexus link trae-cn --dry-run             # preview without creating entries
dsh-skills-nexus link trae                         # discover skills under ~/.trae/skills/
dsh-skills-nexus link qoder                        # user-level skills + marketplace plugins under ~/.qoder
dsh-skills-nexus link trae --source-dir /path       # override the source root (not skills/)
dsh-skills-nexus remove --group trae --yes          # unlink the group; keep external directories
dsh-skills-nexus link trae-cn --group custom        # override the L1 group name (default: trae-cn)
dsh-skills-nexus link trae-cn --force               # replace existing entries on conflict

link supports trae-cn (~/.trae-cn, env TRAE_CN_DIR), trae (~/.trae, env TRAE_DIR) and qoder (~/.qoder, env QODER_DIR). The Trae variants scan only /skills/ one level deep; qoder adds the skill directories declared by the plugins installed from its marketplace, and leaves out the plugins Qoder ships itself (qoder-bundler), which need the Qoder host runtime. Root precedence: --source-dir > legacy alias --trae-cn-dir > the selected source's environment variable > default. An override selects one root only — for qoder that is the agent root (~/.qoder), not its skills/ child; a nonexistent overridden directory does not fall back to the default. Unlink with remove --group --yes (use your custom group if you set --group); this preserves the external directories. See source details. For isolated CLI checks and the panel acceptance checklist, see Verifying local source links.

Value options (--name, --ref, --subdir, --source-dir) also accept the --flag=value form (e.g. --subdir=skills/foo, --name=owner-skills); the boolean --yes takes no value.

For scripts, --json turns any of add, list, update, remove, enable and disable into a machine interface: a version-1 report on stdout and nothing else, diagnostics on stderr, and the same exit codes (0 ok / 1 error or partial failure / 2 usage error). A report tells you what the operation *did* — the commit an install landed on, the before→after pair of an update, which name of a batch was not found:

$ dsh-skills-nexus add github:owner/repo --json | jq '.results[0]'
{ "spec": "github:owner/repo", "status": "added", "name": "repo",
  "commit": "…", "ref": "main", "links": ["repo"] }

--json runs never prompt, so pass --yes where the interactive run would have asked. See for the full contract and its explicit non-promises.

add accepts multiple repo specs and remove accepts multiple names plus */? globs; each target is handled independently and the exit code is non-zero if any one failed. Because --name/--ref/--subdir are per-repo, they cannot be combined with multiple add specs — run separate add commands to customize each. A remove glob matching more than one skill lists them and asks for confirmation first (--yes skips it); quote the pattern ('theme-*') so your shell does not expand it.

Accepted repo forms: github:owner/repo[#ref], full https:// URL (any git host — GitLab, Gitee, Bitbucket, self-hosted; incl. /tree//... subpaths), git+https://, git@/ssh://, and bare owner/repo shorthand (GitHub only — resolves to github.com). For other platforms, use the full URL.

When you add a repo, nexus inspects the clone before registering it:

  • Plain SKILL.md repo — registered directly.
  • SKILL.md + DSH plugin wrapper — asks whether to ignore the wrapper and manage as a plain SKILL.md repo. Type y to continue, n to abort and suggest installing via dsh plugin add. Use --yes to skip the prompt.
  • Pure DSH plugin (no SKILL.md) — prints a message telling you to use that repo's own DSH plugin installation flow, then exits without registering.
  • Neither — reports that no SKILL.md or DSH plugin marker was found and exits with an error.
  • Collection repos (skills//SKILL.md layout, e.g. trae-community/trae-skills) — installing the whole repo yields no installable skill at the root; nexus rejects it and suggests --subdir . Installations that yield more than 20 skills trigger a confirmation prompt (skip with --yes).

Moving skills to another machine: export / import

A package is a container, not an installation format. export writes the skill files plus a nexus-package.json label recording where each entry came from; import rebuilds those entries on another machine — or from a package somebody handed you.

  • A package never contains `.git`, and no credentials. What it carries is

the skills *and their provenance*: url / gitUrl / ref / commit / subdir, the enabled state and the link names of every entry. export --all includes disabled entries, so a migration reproduces the sending machine.

  • `import` prefers a real clone. When the label records a remote that

answers, the entry is rebuilt through the same install path as add — a genuine shallow clone, updatable and switchable. Only when there is no source (or it cannot be reached) does the payload land as a snapshot — and even then the exporting machine's state is restored: a skill disabled over there stays disabled here, under the same link names.

  • `--locked` restores the exported revision exactly. It requires a labelled

package whose selected entries contain a safe gitUrl, non-empty ref, and full 40–64 digit commit SHA. Nexus skips the reachability probe, performs a depth-1 fetch of that commit, checks it out detached, and marks the manifest entry as explicitly locked. Only an explicit remote "commit unavailable" response falls back to the packaged snapshot; network, authentication, and ambiguous Git failures remain errors. Bare packages are rejected, and --locked cannot be combined with --no-remote or --no-net-check.

  • `--dry-run` decides without touching anything, printing one verdict per

entry: will clone from (), will import as snapshot ( unreachable), will import as snapshot ( check timed out) — a 5s probe, because a slow network must never read as a deleted repository — or will import as snapshot (source unknown) for an unlabelled package. Another tool's zip is such a package: its skills are found by a more forgiving scan, and --subdir names the root explicitly when they are nested deeply.

  • Packages are for crossing machines, not for installing. With network

access add is the direct route; export / import move a whole nexus (or take delivery of skills someone sent you). --no-net-check skips the probe entirely (offline, zero waiting), --no-remote always lands a snapshot, --each makes one entry per skill (and, with --locked, one independent clone per skill at the recorded commit), and --force replaces an entry that is already registered. list shows explicit package locks in its LOCK column; doctor --updates distinguishes them from ordinary detached tag/commit pins. A successful switch-version clears the explicit lock.

Giving a frozen entry its identity back: adopt

A snapshot cannot update or switch-version — it has no history to fetch. When you later find the repository it came from, attach it:

dsh-skills-nexus adopt daily-trend-writer --url github:owner/repo
dsh-skills-nexus adopt daily-trend-writer --url github:owner/repo --subdir skills/daily-trend-writer

adopt keeps the entry name and its subdir identity, clones that repository into repos// and rebuilds the links, so the entry ends up indistinguishable from one add created. The previous directory is kept as repos/.pre-adopt- (delete it with --prune), a source that would expose a *different* set of skills is refused unless you pass --force, and a failure at any step restores the directory, the links and the manifest.

Web panel (optional plugin side)

When nexus runs inside a DSH web session — registered via dsh plugin add, or mounted with the local --patch overlay from Local testing steps — a Skills Nexus section appears in the Settings page. The panel and the CLI drive the same manifest, the same clones and the same cross-process file locks, so you can mix both freely (a skill one side is working on answers busy / locked on the other).

The panel is built from the same interface components DSH uses in its own settings — status dots, switches, tags, disclosure rows and a terminal-style output surface — and its colors follow the host's light/dark theme automatically, so it reads as a native part of Settings rather than a third-party add-on.

From the panel you can:

  • browse entry cards — link names, enabled state, pinned commit, status tags

like no source / linked directory / disabled, and an update available badge for branch-tracked entries;