Ship optional bundles with the installation
Ship optional bundles with the installation
The Web plugin page manages only the bundles a person installed into the profile. An official experimental layer such as Agent Teams had to be found on npm and installed by name before it could be switched on, and [default-product isolation](2026-09-12-default-product-experimental-isolation.md) kept every experimental package out of the installation's runtime dependencies, so nothing shipped with dsh could offer it.
English
Problem
The Web plugin page manages only the bundles a person installed into the profile. An official experimental layer such as Agent Teams had to be found on npm and installed by name before it could be switched on, and default-product isolation kept every experimental package out of the installation's runtime dependencies, so nothing shipped with dsh could offer it.
Decision
The launcher names in OPTIONAL_BUNDLES (packages/boot/app-boot/src/profile.ts, beside the profile templates) the bundles the installation ships for a person to switch on. Each must be a runtime dependency of apps/cli that declares dsh.bundle.patch, and no shipped profile template selects it. The plugin manager's listBundles reports such a bundle as optional: switched off until selected, never removable, resolved from the installation like any installation-supplied bundle. The Web plugin page opens its Official group with the optional bundles, tagged experimental when the package is experimental, ahead of the profile's own installed bundles.
Default-product isolation keeps its rules with one declared exception: an optional bundle's dependency graph is outside the default product. The static gate skips the dependencies edge from @deepseek-ai/dsh to a listed bundle and still rejects a runtime import, a shipped composition, a preset, or a default template that names it, an experimental dependency the list does not name, and a listed name that is not a runtime dependency or not a bundle. The workspace-constraints check accepts the same dependencies edges and no other runtime section, and the packed-install release check skips them from the installed entry package while requiring each listed bundle to be installed.
The single-bundle reference supersedes the two Agent Teams selections with one @deepseek-ai/dsh-experimental-agent-team-profile selection. This note retains the installation-owned optional-bundle policy; the optional-bundle decision for experimental capabilities owns composition and display metadata; OPTIONAL_BUNDLES owns the current shipped list.
Alternatives considered
A catalog of installable official bundles. The page would offer names to install from the registry on demand. That keeps the installation unchanged but needs network access at the moment of switching on and a version pin per release. Lightweight bundles retain the shipped policy; the on-demand native-bundle decision owns the exception for costly native runtimes.
A flag on the bundle package. A dsh.bundle.optional declaration would let any published bundle claim a place in the installation; the launcher's own list keeps the choice with the product.
A list in the installation's manifest. dsh.optionalBundles in apps/cli/package.json was the first form; the maintainers keep product decisions in code, where the list is typed, read once, and shared by the manager and the gates.
Consequences
Optional bundles are downloaded with the product and stay inactive until selected; the runtime isolation smokes still observe no experimental module in a default composition. Switching on an optional Web layer loads its client plugin through the live client module graph.
中文
问题
Web 插件页只管理用户装进 profile 的组合包。像 Agent Teams 这样的官方实验层,用户得先去 npm 找到包名并按名安装才能开启;而默认产品隔离又把所有实验包挡在安装的运行时依赖之外,所以随 dsh 一起交付的东西没有办法把它提供出来。
决策
启动器在 OPTIONAL_BUNDLES(packages/boot/app-boot/src/profile.ts,与 profile 模板并列)里点名安装随附、供用户开启的组合包。每一个都必须是 apps/cli 声明了 dsh.bundle.patch 的运行时依赖,且不被任何随附 profile 模板选中。插件管理器的 listBundles 把这类组合包报告为 optional:选中前保持关闭、永不可卸载、像其他安装提供的组合包一样从安装目录解析。Web 插件页以可选组合包开启「官方」分组,属于实验包的带实验性标签,排在 profile 自己已安装的组合包之前。
默认产品隔离的规则保持不变,只声明一个例外:可选组合包的依赖图在默认产品之外。静态门禁跳过从 @deepseek-ai/dsh 到列表中组合包的 dependencies 边,仍然拒绝运行时 import、随附组合、preset 或默认模板对它的引用,拒绝列表没有点名的实验依赖,也拒绝不是运行时依赖或不是组合包的列表项。workspace 约束检查接受同样的 dependencies 边而不接受其他运行时依赖段;发布时的 packed-install 检查对已安装入口包跳过这些边,并要求列表中的每个组合包都已安装。
单组合包参考将两个 Agent Teams 选项替换为一个 @deepseek-ai/dsh-experimental-agent-team-profile 选项。本记录保留由安装方决定可选组合包的策略;实验能力的可选 bundle 决策定义组合与显示元数据;当前随附名单由 OPTIONAL_BUNDLES 管理。
考虑过的替代方案
可安装官方组合包目录。 页面按需提供从注册表安装的包名。安装本身不变,但开启那一刻需要网络,并且每次发布都要钉一个版本。轻量 bundle 仍采用随附策略;按需原生 bundle 决策管理原生运行时成本较高的例外。
组合包自身的标记。 dsh.bundle.optional 声明会让任何已发布的组合包都能自称随安装提供;由启动器自己的列表来决定,选择权留在产品手里。
放在安装 manifest 里的列表。 apps/cli/package.json 的 dsh.optionalBundles 是最初的形式;维护者把产品决定放在代码里,列表有类型、只读一次,管理器与门禁共用。
影响
可选组合包随产品一起下载,选中前保持不活动;运行时隔离 smoke 在默认组合中仍观察不到任何实验模块。开启一个可选 Web 层会通过实时客户端模块图加载它的客户端插件。