1. Choose the smallest useful extension seam
Start from a documented DSH capability rather than patching the agent loop. Decide whether you are adding a tool, service provider, interface, policy, event listener, background job, or durable session feature.
- State the capability in one sentence.
- List the profiles and platforms it supports.
- List every permission, credential, and external service it needs.
- Define how registration is reversed when the plugin unloads.
2. Write a minimal Cordis plugin
The common plugin shape exports an apply function. Cordis calls it with the shared context, which is where the plugin registers its contributions.
import type { Context } from '@deepseek-ai/cordis'
export const name = 'example-plugin'
export function apply(ctx: Context) {
// Register services, events, tools, or reversible effects through ctx.
}3. Package the plugin as a bundle
An installable DSH bundle is an npm package whose package.json declares dsh.bundle and points to a Cordis patch file. The patch inserts or overrides the plugin rows contributed by the package.
{
"name": "dsh-example-plugin",
"version": "0.1.0",
"type": "module",
"main": "index.js",
"files": ["index.js", "cordis.patch.yml"],
"dsh": { "bundle": { "patch": "./cordis.patch.yml" } }
}4. Insert the plugin through a Cordis patch
Use a stable row id so users can inspect or override the row from a later profile patch. Package rows should reference the package name rather than a source-relative path.
- insert:
- id: example-plugin
name: dsh-example-plugin5. Install the checkout into a test profile
Use a separate profile while developing. The first plugin command creates the profile and adds the base bundle before linking your local package.
dsh plugin --profile plugin-dev add ./dsh-example-plugin
dsh --profile plugin-dev --dump-config
dsh --profile plugin-dev6. Make lifecycle and failure behavior explicit
Cordis mounts entries concurrently, so ordering must come from declared service dependencies rather than list position. A plugin should fail loudly when required services are missing and release resources when it unloads.
- Use service injection for dependencies.
- Register timers, listeners, processes, and tools as reversible effects.
- Keep configuration schemas narrow and documented.
- Test activation, normal use, unload, reinstall, and failure paths.
7. Publish for official discovery
Ship a license, README, supported environments, reproducible install command, build output or a safe prepare path, tests, and a permissions section. Then add the official dsh-plugin GitHub Topic to the public repository.
DeepSeek Harness is in developer preview. Recheck official documentation and plugin evidence when the host version changes.
Official sources
These primary sources were used to verify the technical details in this guide.