DSH 插件 client 半端(依据官方包实现与 dsh-voice-input 实战验证)
包结构
package.json:exports加"./client": "./lib/client/index.js";dsh.client声明{ "platform": "web", "inject": [...] }inject按需列出依赖的 client 插件:@deepseek-ai/dsh-client-runtime(slots)、@deepseek-ai/dsh-client-locale(i18n)、以及插槽声明方(如@deepseek-ai/dsh-client-ui-conversation、@deepseek-ai/dsh-client-ui-settings)- client 源码放
src/client/index.ts,导出export const inject = ['slots']与export function apply(ctx)
注册 UI(slots 契约)
ctx.slots.inject('conversation.input.right', () => ctx.slots.register({
name: 'conversation.input.right', // 插槽名(single/list/chain 由声明方定)
id: 'my-button',
order: 10,
locale: 'my.ns', // 可选:声明后组件收到 t()
}, MyComponent))
- 组件自动收到「标准 kit」:全局
useSessions/useWorkspaces;会话级useSession、useInput(draft 快照)、inputActions(setDraft/submit/…);以及sessionId、useProjection、renderSlot、t - 常用插槽:
settings.plugins.tab(设置页标签)、conversation.input.left/right(输入条按钮区)、tool.call.toolview(工具调用视图,keyed 注册)、conversation.composer.dock
构建(tsup 双目标)
// tsup.config.ts:host 半端
{ entry: { 'host/index': 'src/host/index.ts' }, format: ['esm'], platform: 'node' }
// client 半端
{ entry: { 'client/index': 'src/client/index.ts' }, format: ['cjs'], platform: 'browser',
external: ['react', 'react-dom'] }
- 构建后必须按官方 client-modules 协议包装:
window.__ModuleLoader__.load({ id: '<包名>', factory: (require) => { ...CJS... } })(react 由宿主加载器提供,不打进 bundle) - 自测:Node 里 mock
window.__ModuleLoader__执行 bundle,断言apply/inject导出与注册发生
安装与调试
file:协议是复制安装,改代码必须重装;link:协议建 Junction 指向本地目录,改源码即时生效(开发推荐)- 验证 client 已加载:刷新页面看 UI 是否出现;host 加健康路由
GET /<prefix>/health排查;页面 HTML 的 client 清单里应出现"id":"<包名>"与rev - 页面清单不更新 = 服务端未重启(rev 是启动时计算的);改 lib 后重启 dsh