Skip to main content

How to use dsh-suite

Event/lifecycle template examples in the create-dsh-plugin scaffolding: zero runtime dependencies, demonstrating listening to session/event, tools/change, tools/pre-execute and ctx.effect resource cleanup.

This article is auto-derived from indexed fields (wiki / faq / compatibility_json), not freshly AI-generated.

This article is derived from the plugin's already-indexed fields (wiki / faq / compatibility_json / readme), not freshly generated by AI. Source field is noted at the end of each section.

Quick start

dsh-suite (create-dsh-plugin/events Template)

— source: plugin_wiki.wiki_content

Install & verify

dsh plugin --profile web add github:whyihaveyou/dsh-suite#path:packages/create-dsh-plugin/templates/events

Run the command above in your DSH Web Profile. Then enable the plugin in the plugin list.

— source: plugins.install

Key points

— source: plugin_wiki.readme_en (fallback readme_raw)

FAQ

Which specific events does the events template listen to?

Subscribe to three: session/event (session log changes, printed by type/count), tools/change (tool registry additions/deletions, printed per event), tools/pre-execute (tool call interception waterline, must call next() to pass after printing, otherwise it will short-circuit and block the tool call) (templates/events/src/index.ts:21-43).

Why is it called 'zero runtime dependencies'?

Because all dsh-related imports in src/index.ts have the import type prefix (templates/events/src/index.ts:7-9), after compilation there are no actual requires of the dsh package in dist/; package.json#dependencies is empty, dsh-tools / dsh-session all fall to devDependencies only for types (templates/events/package.json:24-34).

What is its relationship with the create-dsh-plugin tool itself?

It is one of the sub-template directories of the create-dsh-plugin scaffold (templates/events/). When create-dsh-plugin generates a project, it recursively reads this directory, replaces placeholders like {{PKG_NAME}} / {{PLUGIN_ID}} / {{CORDIS_VERSION}} and other tokens, outputting a complete, independently installable event plugin project (packages/create-dsh-plugin/src/generate.js:67-74 / packages/create-dsh-plugin/src/templates.js:3).

Will dsh plugin add github:.../templates/events install successfully?

Yes. The template root directory is a valid cordis bundle: package.json declares dsh.bundle.patch: ./cordis.patch.yml, the host loader will inject this into the loading list after replacing {{PKG_NAME}} with the package name according to this patch, provided you first run pnpm install && pnpm run build to produce dist/index.js (templates/events/package.json:15-19 / templates/events/cordis.patch.yml:7-9).

Why doesn't my timer stop automatically when uninstalling?

Because ctx.on() is a host-managed effect, uninstallation automatically cleans it up; but timers you start with setInterval are not managed by the host, you must wrap them like in the template: ctx.effect(() => { const timer = setInterval(...); return () => clearInterval(timer) }), the returned disposer is the uninstall hook (templates/events/src/index.ts:45-59).

After modifying the template code, how do I verify I didn't break the scaffold?

Run node --test in the packages/create-dsh-plugin directory, which contains snapshot tests for the three generate templates; they assert that the events template has no leftover {{token}}, runtime dependencies are still empty, and it contains ctx.on( and ctx.effect(; to run the full chain (pnpm install → tsc → dsh plugin add) you need DSH_SMOKE_VERIFY=1 (packages/create-dsh-plugin/test/smoke.test.mjs:66-79 / 109-119).

What if the plugin generated by it doesn't match the official DSH version?

The scaffold fetches the current next-tag exact version via npm view @deepseek-ai/dsh-tools dist-tags.next and writes it to devDependencies during generation, falling back to 0.1.0-rc.6 when offline. When DSH has a major version bump, just re-run generation to get the new version number without manual changes (packages/create-dsh-plugin/src/util.js:54-80).

Why does the template's cordis.patch.yml use the package name instead of a relative path?

Because the patch's name resolves through node_modules / $DSH_HOME/profiles/node_modules, the template has already injected the package name via the {{PKG_NAME}} token; writing a relative path would make the host unable to find the entry point. The template top comment specifically documents this pitfall (templates/events/cordis.patch.yml:1-9).

— source: plugin_wiki.faq_json

Compatibility

  • DSH: 0.1.0-rc.6(模板本身的 host peerDependency 由 @deepseek-ai/cordis@^{{CORDIS_VERSION}} 解析,默认 cordis=4.0.1;运行时 dsh 版本由用户在生成时通过 next-tag 锁定,默认 0.1.0-rc.6,见 packages/create-dsh-plugin/src/util.js:54-80)
  • Node: ^22.19.0 || >=24.0.0(脚手架根 package.json 的 engines 字段;模板自身未声明 engines)

— source: plugin_wiki.compatibility_json

Pitfalls

Review the upstream repo before installing. This guide is auto-derived from indexed fields and may lag the latest release. If anything contradicts the official docs, treat the upstream source as authoritative.

— source: general rule