DeepSeek Harness plugin

dsh-skill-router-mjorgin

Pre-step skill router for DeepSeek Harness: rule-first task-to-skill matching that pours matched skill bodies only on high-confidence hits and stays silent otherwise. Companion to skill-bartender.

Jump to install

Source facts

Repository
MJorgin/dsh-skill-router
Latest update
Aug 17, 2026
Category
Models & Providers
GitHub stars
1
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/MJorgin/dsh-skill-router
Plugin: dsh-skill-router-mjorgin
Author: MJorgin

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer4 files
README.mdSource · read only
README language

<div align="center">

<img src="docs/social-preview.png" alt="dsh-skill-router — rule-first pre-step skill routing for DeepSeek Harness" width="100%">

<br>

🍸→⚙️ dsh-skill-router

Rule-first pre-step skill routing for DeepSeek Harness: pours matched skills, stays silent when unsure.

![License: MIT](LICENSE) ![Test CI](https://github.com/akqwpeter-prog/dsh-skill-router/actions/workflows/test.yml) ![DeepSeek Harness](https://github.com/topics/dsh-plugin) ![Deterministic](README.md#-how-it-works) ![Once per session](README.md#-how-it-works) ![Companion](https://github.com/akqwpeter-prog/skill-bartender) !Docs

<br>

Companion executor to skill-bartender: the skill carries the policy judgment, this plugin carries the execution. Deterministic, zero LLM calls, zero token cost until a rule actually pours:

  • Pre-step hook — reads the latest user message before every step.
  • 🧭 Rule-first matching — user-editable YAML policy (~/.dsh/skill-router.yaml,

bundled defaults in default-policy.yaml), first match wins.

  • 🔇 Silent miss — no hit → zero intervention; the model keeps its normal

catalog flow.

  • ♻️ Once per session — each skill pours at most once.
  • 🛡️ Broken YAML never breaks the session — falls back to bundled defaults.

[Why](#-why) · [How it works](#-how-it-works) · [What you get](#-what-you-get) · [Quick start](#-quick-start) · [See it in action](#-see-it-in-action) · [Policy](#-policy) · [Tested](#-tested) · [Scope & non-goals](#-scope--non-goals) · [FAQ](#-faq) · [Layout](#-layout) · [License](#-license)

English · 简体中文

</div>

---

🤔 Why

Most skill loading is left to the model's judgment: it sees the catalog every step, re-decides every time, and often loads late, wrong, or not at all. A router that runs before the model answers fixes that:

dsh-skill-routerLLM-judge routerManual loading
Decision makerrules (deterministic)LLM / embeddingsthe model, per step
Token costzero until a rule poursevery stepevery step
Latency added~0 msmodel round-tripn/a
Reproducible✅ same message → same pour❌ varies❌ varies
User controledit YAML, doneprompt ithope it remembers

Why rules and not an LLM judge? Speed, cost, and predictability. A URL-path rule routes feishu.cn/x/docx/ to lark-doc in microseconds, for free, every time — and skill-bartender's routing table is where the policy judgment lives. This plugin is the muscle, not the brain.

⚙️ How it works

  • Hooks agent/pre-step, reads the latest user message.
  • Matches it against user-editable rules (~/.dsh/skill-router.yaml, bundled

defaults in default-policy.yaml). First match wins.

  • On a hit: pours the matched skill bodies into the step as

skill-invocation messages — the catalog's "already loaded, don't re-load" rule applies automatically.

  • No hit: zero intervention. The model keeps its normal catalog flow.
  • Each skill pours at most once per session.

✨ What you get

CapabilityWhat it does
⚡ Pre-step hookagent/pre-step — the pour happens before the model starts thinking
🧭 YAML policyUser-editable ~/.dsh/skill-router.yaml; broken YAML falls back to bundled defaults
🔎 whenToUse triggersInstalled skills' whenToUse frontmatter acts as a secondary trigger (literal phrase match, appended after YAML rules)
🚀 Zero costNo LLM judge, no embeddings — rules only (fast, free, deterministic)
♻️ Once per sessionDedupes pours per session; no skill body floods the context
🔗 CompanionWorks with skill-bartender's routing table and taste test

⚡ Quick start

dsh plugin --profile web add github:akqwpeter-prog/dsh-skill-router

Then restart the running instance (profile bundles load at boot).

Verify: say "生成一张海报" — media-tools pours automatically; say "这个截图帮我检查一下" — vision-review pours. No rules matched? The model just works as usual.

📸 See it in action

One picture: a rule hits → the skill pours before the model answers; no hit → total silence.

<img src="docs/screenshots/how-it-works.png" alt="How the router works: agent/pre-step reads the message → rule match (YAML first, then whenToUse) → hit? → pour skill-invocation (once per session) or stay silent (zero tokens)" width="100%">

🧭 Policy

# ~/.dsh/skill-router.yaml
rules:
  - match: "(生成|画).{0,12}(图|海报|banner)"
    pour: [media-tools]
  • Ordered by precision: URL-path routing first, media, delegation, workflow

skills before atomics.

  • First matching rule wins; pour lists the skill names to load.
  • Broken YAML falls back to bundled defaults and never breaks the session.
  • Write it as data: improve matching by editing YAML, not code.
  • Full reference: [docs/POLICY.md](docs/POLICY.md) · bundled defaults: [default-policy.yaml](default-policy.yaml) · walkthrough: [docs/EXAMPLES.md](docs/EXAMPLES.md).

🧪 Tested

Integration suite (10 cases) run against a live profile: pour, dedupe, zero-touch, reject passthrough, URL routing, mail-vs-IM disambiguation, false-positive guards. See test/ in the repo, plus the design notes in [DESIGN.md](DESIGN.md) and the gold-task list in [GOLD-TASKS.md](GOLD-TASKS.md).

🎯 Scope & non-goals

  • No LLM judge, no embeddings: rules only (fast, free, deterministic).
  • No auto-install of missing skills: that stays in skill-bartender's

quarantine → SkillSpector → human-approval flow.

  • Rule table is data: improve matching by editing YAML, not code.
  • whenToUse frontmatter on installed skills acts as a secondary trigger

(literal phrase match, appended after YAML rules). Write it as a short trigger phrase; long prose never matches. Today's skill data mostly lacks the field — skill-bartender's taste test can backfill it.

❓ FAQ

Does it consume tokens when nothing matches? No. No hit → zero intervention, zero LLM calls. The router only reads text already in the step and runs regex rules — microseconds, free.

How is it different from skill-bartender? skill-bartender is the judgment (which skill fits, when to stay silent, how to install safely). This plugin is the execution (a deterministic pre-step hook that pours). They complement each other; the router works standalone too.

Can I use my own rules? Yes — copy default-policy.yaml to ~/.dsh/skill-router.yaml and edit. First match wins; broken YAML falls back to defaults.

Does it pour the same skill twice in one session? No — each skill pours at most once per session, so context never floods.

🗺️ Layout

dsh-skill-router/
├── index.js               # Cordis plugin: pre-step hook + pour logic
├── policy.js              # rule loading / matching (unit-tested)
├── default-policy.yaml    # bundled defaults (copy to ~/.dsh/skill-router.yaml)
├── test/                  # policy unit tests + integration suite
├── DESIGN.md / GOLD-TASKS.md    # design notes + gold tasks
├── docs/
│   ├── screenshots/how-it-works.png
│   ├── POLICY.md / EXAMPLES.md
│   ├── social-preview.png  # banner (regenerate via scripts/)
│   └── lang/README_ZH.md   # 简体中文
├── scripts/
│   ├── make-banner.py      # composes docs/social-preview.png
│   ├── make-diagram.py     # composes the how-it-works diagram
│   └── check-policy.mjs    # policy validation
├── cordis.patch.yml / package.json   # DSH bundle manifest
└── LICENSE (MIT)

🤝 Join the DSH plugin ecosystem

DeepSeek Harness developer preview is still in its testing phase for Harness developers; core plugins and base APIs will keep iterating. We look forward to exploring the upper limits of intelligence together with developers worldwide, on top of open-source, open, reusable, and composable infrastructure.

> This repo is tagged dsh-plugin and > listed in the awesome-dsh-plugin > curated list. PRs, issues and translations are welcome.

📄 License

[MIT](LICENSE)