deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
INSTALL REFERENCE
dsh plugin --profile web add github:lengdanran/dsh-claude-plugin-loader
该命令指向仓库当前默认分支;尚无绑定当前 commit 的完整验证结果。
PROJECT README
English | 中文
Standalone extraction. This repository mirrors
packages/claude-plugin/claude-plugin-loaderfrom the DeepSeek Harness monorepo under its MIT license. The@deepseek-ai/dsh-*peer dependencies are built inside that monorepo and are not published to npm yet, sonpm installhere cannot resolve them; run tests and builds from the monorepo checkout (pnpm exec vitest run packages/claude-plugin/claude-plugin-loader).docs/design-report.htmlis the Chinese design report for the implementation.
A cordis plugin that loads Claude Code plugins directly on the harness: it discovers plugin roots (explicit plugins entries plus recursively scanned roots), parses each plugin's mapped surface, and mounts every component onto its native harness seam. Everything a plugin contributes is effect-owned by the loader fiber, so disposing the loader unloads the whole plugin surface.
| Claude component | Harness seam |
|---|---|
skills/<name>/SKILL.md |
one claude-plugin skill provider from @deepseek-ai/dsh-skill over every parsed skill |
commands/<name>.md |
one dsh-commands (@deepseek-ai/dsh-commands) slash command steering a rendered prompt into the agent |
agents/<name>.md |
one dsh-tool-subagent (@deepseek-ai/dsh-tool-subagent) delegation tool per agent (needs subagentProvider) |
hooks/hooks.json |
one dsh-hooks-claude-code (@deepseek-ai/dsh-hooks-claude-code) bridge instance per plugin |
.mcp.json servers |
one dsh-mcp-client (@deepseek-ai/dsh-mcp-client) instance per server |
import type { Config } from '@deepseek-ai/dsh-claude-plugin-loader'
const config: Config = {
plugins: ['/path/to/plugin'], // optional: explicit plugin roots, each required to carry .claude-plugin/plugin.json
roots: ['/path/to/marketplace'], // optional: scan roots searched up to maxScanDepth for plugin roots
maxScanDepth: 4, // optional: directory levels below each roots entry to descend (0–16)
subagentProvider: 'spawn', // optional: ctx.subagents provider that mounts plugin agents as delegation tools
mcpToolCallTimeoutMs: 60_000, // optional: per-tool-call timeout forwarded to every mounted MCP client
mcpFailOnStartupError: false, // optional: whether an MCP server startup failure fails the loader activation
}
In a cordis.yml:
- dsh-claude-plugin-loader:
plugins:
- ./.claude/plugins/my-plugin
roots:
- ./.claude/plugins
subagentProvider: spawn
Loading is fail-loud: a missing explicit root, a malformed manifest or component file, a duplicate plugin/command/agent name, or two MCP servers mapping to the same sanitized serverName all throw at load with the offending path. A config with neither plugins nor roots warns and mounts nothing. Claude-valid inputs the harness cannot serve are skipped with a warning instead — a skill's allowed-tools, an agent's model/description overrides, an sse MCP server, an agent body containing a {{…}} group (the persona seam would interpolate it as a prompt variable), agents when subagentProvider is unset, and hooks when no shell service is loaded. Skill files load with model-invocable on and user-invocable off unless the file overrides them; argument-hint becomes the candidate's whenToUse.
Commands render Claude Code's argument rules: $ARGUMENTS receives the full input, $1…$9 receive whitespace-split arguments (missing ones become the empty string), a body referencing neither appends the input, and ${CLAUDE_PLUGIN_ROOT} is replaced with the plugin's absolute root (also in MCP command/args/env/cwd/url/header values). The command description comes from frontmatter or the first non-empty body line.
Each parsed skill joins the skill catalog as a candidate named by its SKILL.md name (source claude-plugin:<plugin>, rank 350), with its description, invocation flags, and optional whenToUse. Invoking a skill loads its SKILL.md body verbatim as skill instructions.
Catalog listings carry names, descriptions, and hints only; each skill body costs tokens only while the skill is loaded, and reloads on demand.
Append-only: skill bodies enter later model requests as newly added context after the reusable prefix, without rewriting it.
Running a plugin slash command steers the rendered command body into the session as a user-sourced message, exactly like a typed command line.
One user message per invocation, sized by the command body plus the supplied input.
Append-only; the steered message joins the conversation after the reusable prefix.
Each agent becomes a delegation tool named subagent_<name>; the agent's body is the subagent persona sent with every delegated child conversation.
A one-line tool schema per agent; the persona text is resent as part of each delegated child request.
Persona text is child-session context and does not touch the parent request prefix.
allowed-tools is ignored: the harness has no per-skill tool restriction, so restricted skills load unrestricted (warned). Tool control is available through the guard and permission planes instead.description/model overrides are not surfaced: the subagent seam owns its own description and model policy, so overrides are warned about and dropped.sse MCP transport is unsupported: only stdio and http (Streamable HTTP) servers load; an sse server is skipped with a warning.{{…}} group are skipped: the subagent persona seam interpolates {{name}} references as prompt variables and fails at child render, so such agents are skipped at mount with a warning; reword the braces to load the agent.dsh-hooks-claude-code (@deepseek-ai/dsh-hooks-claude-code) maps; without ctx.shell the plugin's hooks are skipped.mcpFailOnStartupError is set.roots at the cache (or list chosen entries in plugins when siblings collide on command names). Scans skip hidden directories, node_modules, and symlinks, and stop at a plugin root.CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。