Plugin Development
Plugins are extension packages that add capabilities to DSH — models, tools, interfaces, and workflows can all be made into plugins. PicoAide Harness does not fork or modify the upstream source; everything is a plugin composition: the desktop shell itself (window, tray, updates, the fixed desktop profile) is a legitimate DSH plugin, taking the same official Cordis composition path as third-party plugins.
Plugin Mechanism Overview
Section titled “Plugin Mechanism Overview”- Upstream Holder: official capabilities such as agent, model, tool, session, settings, webServer, and subprocess run as-is at a pinned version;
- Desktop Host Services: window, tray, and updates; the third-party contract is documented in the repository at
packages/host/desktop/docs/plugin-services.md(link) — thedsh-plugin-desktoproot entry plus subpaths such as./desktop-home,./diagnostics,./updates, and thedesktopRuntime.registerTrayItemtray registration; - Web Client: the official Web UI plus third-party browser interfaces, working through the loopback carrier and not calling Electron directly;
- Native runtime: Electron BrowserWindow, system tray, and file/network/installer adapters —
desktopRuntimeis for use only by Desktop’s own rows, not a third-party API.
Two Plugin Forms
Section titled “Two Plugin Forms”| Form | Convention |
|---|---|
| Service-class packages | default-export a service class (e.g. SessionService / HostCronService) and provide it via ctx.get; example: dsh-enterprise/session-service |
| Function plugins | only named exports name / inject / Config / apply, no default export; Config is validated with a Schemastery schema; all side effects are wrapped inside ctx.effect (rollback on HMR/unload); examples: pico-cron, pico-connectors, pico-browser |
Client Plugins
Section titled “Client Plugins”Client plugins are built with the clientBundle preset (tsdown), aligning external dependencies with the platform module table (PLATFORM_MODULES; the single source of truth in this repository is scripts/platform-modules.mjs, 9 entries: react, react/jsx-runtime, react-dom, react-dom/client, @deepseek-ai/cordis, @deepseek-ai/dsh-client-store, @deepseek-ai/dsh-client-ui-slots, @deepseek-ai/dsh-client-ui-primitives, @deepseek-ai/dsh-client-ui-dockkit) and the client packages actually imported. That table mirrors the pinned upstream deepseek-harness/packages/client/web/src/platform.ts; node scripts/verify-inventories.mjs diffs the two entry by entry (any drift fails the gate).
- Client-side cross-package imports are forbidden: the source package injects via
ctx.slots.injectinsidectx.effect, and the target package registers viactx.slots.registerin its own client; - The type-check
tsconfig.client.jsonneedsskipLibCheck: true(to avoid internal type errors in the upstreamdsh-client-ui-sidebard.ts); immediately: trueis limited to stage-one-prefetch infrastructure plugins; regular plugins omit it;- Each package carries its own
./invariantsubpath and explicit exports such as./index.
UI Extension Points (slot)
Section titled “UI Extension Points (slot)”Every functional panel of the product UI is injected through a slot (e.g. sidebar.footer.action). Example (connector):
ctx.slots.inject('sidebar.footer.action', () => ctx.slots.register({ name: 'sidebar.footer.action', // …panel identifier, open/close events, icon and copy}))The same pattern is used for: the capability center entry (sidebar.footer.action id=capability-center), the scheduled tasks Tab, the browser entry, settings sections (settings.section), and branding areas (sidebar.brand.mark / conversation hero mark), among others.
Server (Host) Plugins
Section titled “Server (Host) Plugins”- Service-class packages default-export a service class; function plugins only have named exports
name/inject/Config/apply; - Host plugins provide capabilities through official services such as
webServer/apiProxy/tools/systemPrompt; - Loopback API pattern (the common approach for connectors/scheduled tasks/browser): the plugin registers same-origin HTTP APIs (
/api/pico/...), which the client UI consumes via fetch;isLoopbackRequest/browserSameOriginMarkervalidate that the request comes from a same-origin client; - Model tool registration:
ctx.tools.register(defineTool({...}))— scheduled tasks exposecron_create/cron_list/cron_set_enabled/cron_run/cron_remove; the browser exposes thebrowser_*tool group; tools are registered insidectx.effectso they can be unloaded; - Cross-plugin events: types are only declared (
declare module '@deepseek-ai/cordis'); runtime events are emitted by their owner — e.g.pico/session-changed(owned by enterprise, only consumed by connectors/cron/browser).
Common Constraints Checklist
Section titled “Common Constraints Checklist”- Service-class packages default-export a service class; function plugins have no default export;
- Each package carries its own
./invariantsubpath; ctx.slots.injectis wrapped insidectx.effect; client-side cross-package imports are not supported;- Password/secret fields use SecretInput for show/hide toggling; upload/download bodies have limits (e.g. 24MB uploads, 100MB browser downloads);
- Archive safety (skill/preset packaging and unpacking) is validated on both sides (
assertArchiveSafeinarchive-utilis made shared); - Directory/file path permissions: credentials are written atomically with 0600/0700, symlinks are prevented; DSH_HOME is validated for safety (rejecting critical system directories).
Enterprise Server (Go) Development
Section titled “Enterprise Server (Go) Development”The server is modularized under server/internal/ (serverauth / llmgateway / marketplace / sharedskills / agentshare / capabilities / serverstore / bootstrap / util), and the admin console is server/webadmin/src/ (a shadcn React SPA embedded via go:embed). See the repository server/docs/ and AGENTS.md for developer conventions.
More Resources
Section titled “More Resources”- Plugin ecosystem manifesto — the ecosystem vision and its three principles
- Desktop plugin service contract (repo) — types, lifecycle and failure semantics
- Community Fabric (repo, community interoperability RFC)
- System Architecture