Contributing to dshp-plugin-panel
August 30, 2026 · View on GitHub
Thanks for considering contributing! This is a small, focused plugin for
DeepSeek Harness (DSH) session-scoped skill control. Keep changes small,
reviewable, and aligned with the project's stated design (ADR-0007 "three
entrances" sharing one core; ADR-0008 plugin management). Design decisions are
recorded in the DSH monorepo's docs/adr/.
Ground rules
- One surface, one source of truth.
browse/introduce/removebusiness logic lives insrc/actions.ts+src/pool.ts— the model tools (src/tools.ts), slash commands (src/commands.ts) and the panel (src/plugin-panel-service.ts+src/client/) all forward to it. Do not duplicate business logic in a surface. - No typert / Remote. The panel talks to the host over a DSH
webServerHTTP route (POST /plugin-panel/<method>), client uses relative-pathfetch. Keep it that way — it is what keeps this package buildable outside the DSH monorepo. - Session scoping. Introductions are per-session and idempotent; shadow overrides are per-session only. Preserve these semantics.
- i18n. Any new user-facing string must be added to both
zhandeninsrc/client/locale.ts. - Lifecycle. Any side effect registered via
ctx(services, tools, commands, slots, the HTTP route, timers) must be wrapped inctx.effect()/ctx.on()so stop/update cleanup works.
Project structure
index.ts— plugin entry:PluginPanelPlugin(default export),inject: ['agents','tools','skills','commands'],Config.poolRoot?; registers tools + commands (ctx.effect), thePluginPanelServicesub-service (ctx.plugin), and subscribes toagent/session-start(source=resume) to replay the session introduced set.pool.ts— pool read layer:local/directory scan /SKILL.mdfrontmatter parsing (BOM stripping);defaultPoolRootfollows DSH home precedence (explicitpoolRoot>$DSH_HOME>~/.dsh).handles.ts—SessionSkillStore: per-agent+name introduction handles (WeakMap, no leaks, no cross-session) + the on-disk introduced set (.session-skills/<sessionId>.json).actions.ts— core actions shared by all three surfaces: browse / filter / introduce / remove / replaySession.tools.ts— the 5 model tools (ctx.tools.register+ctx.effect).commands.ts— the 5 slash commands (ctx.commands.register+ctx.effect).plugin-panel-service.ts—PluginPanelService(inject: ['agents','skills']): registers the HTTP route viactx.get('webServer').register({kind:'prefix', path:'/plugin-panel'})(ctx.effectcleanup),dispatchroutesbrowse/list/detail/introduce/removeSkillto pool/store; no typert.types.ts— panel boundary payload types (pure serializable, host/client shared).client/— browser half:index.ts(createPluginPanelClient()+ registers thesettings.sectionslot),api.ts(HTTP client: relative-pathfetch('/plugin-panel/<method>'), returns raw business JSON),view.tsx(two-pane view: pool + introduced, search / detail expand / shadow badge),sections.tsx,locale.ts(zh/en),styles.ts(--dsw-alias-*theme tokens).
Development
Prerequisites: Node.js ≥ 20 and pnpm.
pnpm install
pnpm typecheck # lightweight type-check (host + client) — the CI gate
pnpm build # emits lib/index.js + lib/client.js
Type-check configs are self-contained and resolve @deepseek-ai/* from this
package's own node_modules (tsconfig.host.json / tsconfig.client.json),
so the package builds independently of the DSH source tree.
build-client.mjsis the standalone bundle script (node build-client.mjs→ client;--host→ host).lib/is not committed (build artifacts stay out of git). Fresh clones must runpnpm install && pnpm buildbefore running or testing — see the## Developmentblock above.cordis.patch.ymldeclares thedsh.bundlepatch injected on install.
Testing / validation
- Run
pnpm typecheckandpnpm testbefore opening a PR — CI runs both (host + client type-check, plus the test suite). - CI (
ci.yml) runscheck:name,pnpm typecheck,pnpm test,pnpm build, and apack-checkjob that verifies the packed archive contents. - Release (
release.yml) has averifypreflight (type-check + test + build + pack dry-run) that must pass beforepublishruns. - Tests cover: pool/frontmatter parsing, the session introduce-set
(
SessionSkillStore), the shared core actions, plugin-manager write-protection/hot-mount, and the HTTP route protocol (405/404/400, dispatch, method routing). Keep pure-logic tests intest/*.test.ts(Node built-innode:test, no extra deps); each test file uses its own subdir undertest/.tmp/so parallel runs don't clobber each other. - Manual smoke checks: commands main path, idempotency edges, slash-skill invocation, model tools, session isolation, and the panel.
- For browser UI changes, verify in the DSH web GUI Settings → 「插件面板」.
Commit style
Conventional Commits (feat:, fix:, refactor:, chore:, docs:).
CHANGELOG follows Keep a Changelog; update it
in the same PR as the change.
Licensing
By contributing you agree that your contributions are licensed under the project's MIT License (© 2026 super_camel).