Register locally-defined custom agents as callable subagents in dsh: the main conversation invokes any agent by name via use_agent, each running as a real dsh subagent with its own persona. Supports breakpoint resume for interrupted runs.
Install
# from npm (prebuilt)
dsh plugin --profile web add @aiwayds/dsh-subagent-registry
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:fan56/dsh-subagent-registry
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
Register locally-defined custom agents (~/.dsh/agents/*.md) as callable
subagents in dsh — the main
conversation invokes them by name through use_agent, background runs take
follow-ups via ask_agent, and interrupted runs resume from their saved
partial work. No host patching, no code — a markdown file per agent.
Why
- One markdown file is one agent — frontmatter carries the model/thinking settings, the body is the system prompt, changes take effect immediately.
- Resumes interrupted runs — after an error, cancellation, token limit or crash, the next call for the same agent continues from the saved partial work instead of starting over.
- Background dispatch + two-way follow-ups —
background: trueruns the agent as a durable background conversation while the parent keeps working;ask_agentsends a follow-up and waits for the reply. - Three personas out of the box —
workhorse/oldfox/rubber-duckare seeded on first start (see below). - Built on the official subagent machinery — no reimplementation: every
custom agent starts through dsh's stock
spawnprovider, so each child is a real dsh subagent (full session, persistence, continuable). New capabilities in the official subagent stack (bidirectional messaging, say) are inherited automatically; the nativesubagenttool keeps working alongside — the two coexist without interference. - Pure plugin — only relies on dsh ≥ 0.2.0-rc.2's public subagent machinery; uninstalls cleanly at any time.
The three shipped agents
Seeded into ~/.dsh/agents/ on first start (only when the directory holds no
parsable agent — your edits are never overwritten). All three are ordinary
markdown files: edit them freely.
| Agent | Role | Example |
|---|---|---|
| workhorse (牛马狗) | The workhorse: writes code, investigates, tests, deploys — all the grunt work; default deepseek-flash, guarded against dangerous operations |
"Use workhorse to turn the release checklist into a table" |
| oldfox (老法师) | The advisor who doesn't build: analysis, trouble shooting, review, audits — checks, never implements; glm-5.3 |
"Have oldfox review this design" |
| rubber-duck (小黄鸭) | Multimodal visual agent: reads screenshots / charts / handwriting, draws plotext / mermaid / matplotlib figures; runs on an image-capable model | "Use rubber-duck on this screenshot, extract the page text" |
Usage
Install, restart dsh, then just ask in the conversation — the main model picks the agent by name:
Use workhorse to turn today's release checklist into a table
Under the hood that is use_agent(agent: "workhorse", prompt: "…"). For
background runs, follow up with ask_agent(agent: "worker", message: "…") —
it waits for the reply.
Define your own
Drop a file into ~/.dsh/agents/:
---
name: my-agent
description: "One-line subtitle shown in the use_agent roster"
model: opencode-go/deepseek-flash
thinking: high
---
You are my-agent. This markdown body is used verbatim as the system prompt.
Frontmatter keys: name (required), description, display_name, model
(provider/model; absent = inherit), thinking
(off/low/medium/high/max; absent = inherit), deep (0 = leaf, may not
spawn subagents; default 1), background (true = dispatch in the
background by default). Unknown keys are silently ignored.
Concurrency and round limits (since 0.1.7)
Concurrency and nesting depth are owned by the official dsh-subagent
service — this plugin keeps no concurrency counter or queue of its own (the
official ActivationManager schedules): maxActiveSubagents (live-children
cap, default 8) and maxDepth (delegation-depth cap, default 1). Both are
volatile fields, tunable without a restart — via a profile patch
subagent: { maxActiveSubagents: N, maxDepth: M } or at runtime with
settings.update('subagent', …). The use_agent deep frontmatter only
tightens within that official depth budget (deep: 0 leaves strip every
agent-spawning tool outright).
maxRounds (a per-agent turn budget) stays: the official subagent seam
has no round-budget capability, and the key is still consumed by the host
TUI's hard-stop ladder.
→ Full reference: docs/AGENT-FORMAT.md — every key's
validation and failure modes, deep/thinking semantics, resume mechanics,
background dispatch, configuration fields, known limitations.
Bundled skill
The plugin ships a bundled skill named dsh-subagent-registry-config. Whenever the
conversation touches custom subagents, agent .md authoring, resume semantics,
or this plugin's configuration, dsh loads the bundled usage & configuration
guide, so the model can write agent files for you (collecting choices via
ask_user_question) and adjust the plugin config without digging through the
README. The skill is versioned and published with the package
(skills/dsh-subagent-registry-config/SKILL.md).
Installation
Requires dsh >= 0.2.0-rc.2 (the RC/stable line; the alpha line is not supported).
Option A — mount a checkout into a dsh profile:
dsh plugin --profile tui add ~/github/dsh-subagent-registry
Option B — npm dependency: npm i @aiwayds/dsh-subagent-registry, then load
the plugin under the stable id dsh-subagent-registry in your profile's
config, or mount it through a bundle patch (see cordis.patch.yml in this
repo for the pattern).
Uninstall
dsh plugin --profile <name> remove @aiwayds/dsh-subagent-registry
The host splices the plugin out of the profile; restart dsh and the
use_agent / ask_agent tools are gone. Your agent files in
~/.dsh/agents/ stay — they are user-owned and never re-seeded or
overwritten. dsh-tui-pi degrades gracefully without this plugin (you just
lose custom-agent dispatch).
Development
npm run check # tsc --noEmit
npm run build # tsc -> lib/
npm test # all unit tests (no LLM, no network)
The @deepseek-ai/* dependency contract (why optional peers)
This repo declares the @deepseek-ai/* packages (cordis, dsh-subagent,
dsh-llm, schemastery, …) as optional peerDependencies only
(>=0.2.0-rc.2). That is a deliberate two-layer split:
- Release semantics (for consumers): the declaration says "use the host's
own copies, floor
>=0.2.0-rc.2". Optional peers are never auto-installed by pnpm or npm, so they cannot materialize a second copy in the profile'snode_modulesthat shadows the host's bundled closure. What does break hosts is a hard dependency pinned to an old rc — that can render a 0.2.x host unbootable (a known community failure mode). - Dev typecheck (for this repo): since peers are not installed,
scripts/link-dsh-closure.mjs(postinstall) symlinksnode_modules/@deepseek-ai/*to the global dsh install's closure, keeping exactly one@deepseek-ai/cordisin the type graph — a second copy breaks the cordisdeclare moduleaugmentation (Property 'settings' does not exist on type 'Context').
Maintenance rule: keep these entries as optional peers — never move them back
to dependencies/devDependencies, and never drop optional: true (a
non-optional peer is auto-installed under pnpm's auto-install-peers and the
second-copy breakage returns).
License
MIT
Links
More in this category
Tencent/WeKnora#dsh-weknora★ 33277
Four read-only tools over a WeKnora knowledge base: list knowledge bases, hybrid passage search, reassemble one document's chunks in order, and WeKnora's own cited RAG or ReAct-agent answer with a resumable session id.
superdesigndev/treg★ 4991
Tool catalog for agents: search ~2,600 external endpoints (SEO and SERP, backlinks, social, people and company enrichment, ad libraries, scraping) by the task you want done, read each one's parameters and per-call price, then call it with the credential injected server-side. Ships the skill plus an MCP row that stays disabled until TREG_TOKEN is set.
TencentCloudBase/CloudBase-AI-Toolkit#dsh-plugin★ 1136
Tencent CloudBase backend for DeepSeek Harness — scaffold and deploy full-stack apps from chat, render query results as table cards with paging, sorting and CSV export, preview a deployment on its domain, and call the CloudBase MCP toolset (`mcp__cloudbase__*`) with device-code login.
gitroomhq/postiz-agent#dsh-postiz★ 511
Connects DeepSeek Harness to Postiz over MCP: list connected social media channels, fetch per-platform posting rules, and schedule, draft, or publish posts to X, LinkedIn, Instagram, Facebook, Threads, TikTok, YouTube, Reddit, Bluesky, Mastodon, Discord, Slack, Telegram and more; adds a postiz workflow skill.
EthanYoQ/Invoice-Downloader#dsh-invoice-downloader★ 503
Local IMAP invoice download, OCR, archive, and Excel reimbursement summaries for DeepSeek Harness.
anysearch-team/anysearch-dsh★ 458
AnySearch-powered real-time web and vertical search provider for DeepSeek Harness.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.