A Step-by-Step Build of a DeepSeek Harness Plugin, from Tool Definition to HMR Debugging
Plugin systems that enforce typed configuration, explicit dependency injection, and whole-row config replacement eliminate silent misconfiguration — a class of bug that wastes hours in looser frameworks. The git-install security warning about `allowBuilds` is a concrete supply-chain concern any developer distributing agent plugins should address before shipping.
The DeepSeek Harness plugin system runs on Cordis, a dependency-injection and event framework. A minimal tool plugin starts with `defineTool`, `inject`, and `apply`, registering a callable function that the model can invoke. Configuration is handled through Schemastery schemas — not optional JSON blobs but validated, typed objects that fail loudly on mismatch, with `!!js` tags available for runtime-computed values. Event listeners like `tools/result` fire synchronously during result materialization, before the tool's promise resolves, letting observer plugins log or react without the tool knowing they exist. Packaging a plugin into a bundle requires a `package.json` with a `dsh.bundle` declaration and a `cordis.patch.yml` that maps plugin ids to npm package names. Installing into a profile layers configuration in a strict order — bundle patches, profile patch, machine-level patch, then CLI overlays — and each layer replaces entire config rows by id, never deep-merging. A git-install pitfall means TypeScript plugins need a self-contained `prepare` script, and pnpm >=10 users must explicitly allow build scripts for git dependencies. The HMR loop works when plugins carry explicit ids, dependent services are present, and the runtime uses `tsx` for direct TypeScript execution.
The 'fail loud' design — exiting with code 1 on config validation failure rather than running with defaults — is a deliberate safety choice that prevents misconfigured agents from operating silently.
Whole-row config replacement instead of deep merging forces explicitness: changing one field requires rewriting the entire config row, which eliminates ambiguity about which layer owns which value.
The `tools/result` event firing before the promise resolves is a subtle ordering guarantee that lets observer plugins act on results without race conditions relative to the caller.
The git-install `allowBuilds` warning frames a real supply-chain tradeoff: convenience of direct GitHub installs versus the risk of executing arbitrary build scripts outside any agent sandbox.
The checklist item 'no hardcoded tunable values' encodes a testable boundary — if `cordis.yml` cannot change a value without editing code, that value is not properly configurable.