deepseek-ai/deepseek-harness--packages-client-modules ↗★ 226k

@deepseek-ai/dsh-client-modules

客户端模块系统:宿主组装启动图并分发插件包,浏览器懒加载。 面向维护或调试客户端插件的开发者,普通用户无需关注。

包名
@deepseek-ai/dsh-client-modules
兼容性
待验证
Cordis 依赖范围
workspace:^
版本
0.1.6-alpha.1
许可证
MIT
最近更新
2026年9月15日

同名包的其他仓库

安装

此插件尚未提供可验证的 bundle,或兼容性检查未通过。请先阅读仓库说明。 阅读完整 README ↗


description: "Client module system for the web GUI: the host composes the boot graph and serves plugin bundles, and the browser loads them lazily, for users and maintainers composing or debugging client plugins." kind: "package-reference"

@deepseek-ai/dsh-client-modules

English | 中文

Summary

dsh-client-modules turns a plugin package's dsh.client declaration into a loadable browser bundle: the host half scans enabled Loader entries and composes the boot graph, an available Web carrier serves each bundle over /plugins, and a shell-owned carrier dispatches the same exact bundle responses through fetchBundle(). The browser half loads those bundles lazily on demand. Plugin bundles execute lazily — running a bundle only registers a factory, and module side effects run at materialization — so nothing runs until a plugin is first used. Everything here is browser-kernel machinery; the model never sees it.

Table of Contents


Use this package

Use DshClientManifest for the declaration type. Client-modules validates the JSON and owns the normalized boot graph.

Use it when you compose or build a browser client plugin: the package turns a package's dsh.client declaration into a loadable browser bundle with no per-plugin wiring. It activates with the web composition; the shell boots it before any plugin runs.

Declaring a client plugin

A browser plugin package declares dsh.client in its package.json with platform: 'web', exports a ./client bundle, and lists any non-baseline module requests under dsh.client.external. The host half turns each declaration into a served bundle under /plugins, ordered so dynamic providers load before their consumers.

What the browser loads

The application combo scripts register plugin factories once during boot; module bodies remain lazy and run only at first import or materialization. Rows that share a combo URL share one in-flight script task. HMR switches one changed row to its revisioned one-resource combo URL. /client and the bare id resolve to the same exports, because a plugin bundle is its package's client half.

Sharing modules

The shell seeds a frozen module table (PLATFORM_MODULES: React, Cordis, and static UI libraries); every dynamic bundle resolves its externals against exactly that baseline. dsh.client.external adds only exact non-baseline requests, each answered by the dynamic package row it names or an exact static-table key. Type-only imports are erased and create no request. Composition rejects malformed requests, missing suppliers, self-requests, and synchronous request cycles.

Build requirements

The host serves built client bundles, so pnpm run build must have produced each lib/client.js before launch; a missing bundle fails activation loudly with one build instruction and a package/path list. Source launch maps host imports to TypeScript source but still consumes the built client export. The package accepts no plugin config of its own.


Understand the implementation

Implementation internals — click to expand

This section explains how the module system is built; observable behavior is covered in Use this package.

Design concept

The package has two sides: the Node half is the composition and serving side (ctx.clientModules, ClientModuleRegistry), the browser half is the loading side (ctx.modules, ClientModuleSystem). The wire between them is the boot graph — WebBootEntry rows injected as window.__DSH_BOOT__, with ``: the window.__ModuleLoader__ queue facade, advisory preloads for every application combo, the parser-blocking bootstrap combo scripts, then the boot graph before the shell reads it. A Web carrier renders those rows into its index response; a shell-owned carrier can render the same rows without a Web server. The facade's create() materializes the modules bundle, delegates construction to its createClientModuleSystem export, and leaves the same facade in live-registration mode. The shell installs that returned system as its Loader's internal; the modules plugin publishes that instance as ctx.modules, so separate Cordis trees never select an instance through module-global state.

Source map

FileRole
src/index.tsNode half: ClientModuleRegistry, scan, artifact snapshots, optional combo route, structured index rows
src/client/index.tsBrowser half: bootstrap export, ctx.modules enrollment
src/client/system.tsClientModuleSystem: load/materialize/invalidate machinery
src/client/manifest.tsWire types, boot-manifest parsing, and the dsh.client declaration parser

Further Exploration

Read these when the module contract is not enough: the subsystem reference, the shell that boots the tree, and the client authoring rules behind the graph.


Model Experience

None, as the module loader is browser-side kernel machinery that registers nothing model-facing.

KV Cache effect

None; this package neither assembles nor sends a provider request.

Known Limitations and Deferred Work

These limits define what the module system does not do. They are current package constraints, not a task backlog.

  • Flat module graph by design — every bundle is one module node whose edges point only at table leaves; the interface (loadCache/edges/invalidate) already supports a general module graph, so the externalization granularity can change without an interface change.
  • No unload bookkeeping of its own — style removal and fiber teardown ordering live with the HMR driver (@deepseek-ai/dsh-client-hmr); the loader only inventories owned style tag ids per record.
  • Lazy delivery retains requested bodies — the Host holds each bundle and lazy response plan; a script or map body remains cached after its first GET, and HMR additionally retains one prior startup generation. Memory grows only for response bodies that clients request while preserving one-generation race tolerance.
  • An unrequested prior-generation map reads the current map file — combo revisions track executable bundles, not debug artifacts. If HMR rebuilds a map before the retained prior URL receives its first map GET, that response uses the current authored map with the prior bundle offsets; requesting the map before the rebuild fixes that URL's response.

Dev Note

Working context for maintainers — click to expand

None.