Plugins, Bundles, and Profiles are different abstractions
A Plugin is a runtime unit mounted by Cordis. A Bundle is an npm package that exports a patch layer describing which Plugin rows to insert or override. A Profile is a named composition in the local DSH Home containing an ordered Bundle list, extra dependencies, and its own patch.
The DSH install command manages dependencies inside the Profile directory. The CLI only adds a dependency to the ordered layer list when the installed package declares dsh.bundle. A plain library can be installed without becoming a runtime layer.
The manifest turns a package into a composable layer
A Bundle points to its cordis.patch.yml through dsh.bundle.patch in package.json. A Profile stores Bundle package names in dsh.profile.bundles and treats their order as part of the composition.
npm, Git, path, or tarball specifications handle code distribution and dependency resolution. DSH reads an explicit manifest and patch instead of reinventing a package manager.
{
"dsh": {
"bundle": { "patch": "./cordis.patch.yml" },
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
"@deepseek-ai/dsh-web-app"
]
}
}
}Composition starts from an empty tree; later layers win
Every launch starts from an empty entry list. DSH applies the Profile's Bundle layers in order, then its cordis.patch.yml, the DSH Home patch, command-line --patch overlays, and runtime switches.
A patch targets a stable row id. A later layer can insert a row, disable one, or override an existing row. A config override replaces the entire config rather than deep-merging it, so authors must restate every field they intend to keep.
- id: tools
config:
mode: both
maxParallelSubCalls: 8
- insert:
- id: team-policy
name: '@acme/dsh-team-policy'Dependencies control activation; patch order controls configuration
Bundle order determines which layer gets the last write to a row; it does not manually schedule Plugin startup. Once the final tree exists, Cordis activates Plugins according to inject declarations and service availability.
This separation keeps composition deterministic: patch precedence answers what will be mounted and with which configuration, while the Cordis lifecycle answers when it can run safely.
The result is inspectable and live-reloadable
dsh --profile <name> --dump-config prints the exact composed tree DSH is preparing to mount and identifies the layers that contributed its rows. It is the first tool for understanding overrides or a missing row.
On long-lived surfaces, watchers reread and recompose the Profile and Home patches. Cordis uses the same effect ownership to unload the old generation and mount the new one, while command-line overlays remain above user layers.
dsh --profile web --dump-config
dsh plugin --profile web add @acme/dsh-team-tools