Publishing to dsh.fish
Tag your repository with the dsh-plugin topic, or submit it directly. The registry reads your real manifest — what it lists is what the harness would load.
A bundle declares dsh.bundle
A package without that declaration still installs, but the harness activates no layer for it — so the registry does not list it as a plugin either.
{
"name": "dsh-hello-plugin",
"version": "0.1.0",
"type": "module",
"files": ["index.js", "cordis.patch.yml"],
"dsh": { "bundle": { "patch": "./cordis.patch.yml" } }
}Publishing to npm ships prebuilt code, so users need no build allowance. A git install fetches sources: add a self-contained prepare script, and expect users to allowlist it.
A skill is a SKILL.md with frontmatter
name must be kebab-case and description is required — the provider drops a skill missing either.
--- name: release-notes description: Draft release notes from a commit range. --- # Release notes Steps the agent should follow…
An MCP server is a client row
The registry stores credential references, never values. Declare the environment variable names your server needs and the harness resolves them through ctx.credentials.
{
"dsh": {
"hub": {
"kind": "mcp-server",
"mcp": {
"serverName": "github",
"transport": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"credentials": [{ "envName": "GITHUB_TOKEN", "required": true }]
}
}
}
}An agent preset is one agent.cordis.yml
Put it at the repository root (or in the submitted subdirectory). The directory name becomes the preset id.
- id: tools
name: 'dsh-tools'
- id: prompt
name: 'dsh-system-prompt'
config:
persona: ./persona.mdA profile lists bundles in order
Later layers win per row, and a patch replaces a row's whole config rather than deep-merging it — so order is meaningful.
{
"dsh": {
"profile": {
"bundles": ["@deepseek-ai/dsh-base", "dsh-hello-plugin"]
}
}
}