Installing a plugin now activates it without a restart: the CLI boot provides a dshReloadProfile handle that re-runs the profile composition and applies it to the running root Include, and the install/uninstall Remotes recompose live when the handle is present (restartRequired: false). Registry installs try the ordered INSTALL_REGISTRIES mirrors with the official npm registry as the final fallback, erroring only when every source is unreachable. The enable/disable guard splits into a REQUIRED_PLUGINS blacklist and a USER_TOGGLEABLE_PLUGINS whitelist (default toggleable) generated from the running plugin list, and the offline optional-bundle catalog is emptied (default bundles are not installable/uninstallable). The plugin-list tab becomes a registry install form and shows immediate-activation instead of a restart notice. Co-Authored-By: Claude <noreply@anthropic.com>
@deepseek-ai/dsh-host-plugin-inventory
English | 中文
Host projection of the current Cordis Loader tree with per-plugin enable/disable. PluginInventoryGateway registers the pluginInventory service and publishes two generated direct Remotes: pluginInventory/list and pluginInventory/setEnabled. list reads ctx.loader.entries() directly, skips structural group rows, and returns the remaining entries in Loader order with only their Loader entry id, module specifier, effective enablement, and current root Fiber phase.
The phase is pending, loading, active, failed, or unloading; it is null when the entry has no live root Fiber. The snapshot is intentionally point-in-time: Loader remains the sole lifecycle authority, while this package owns no cache, history, provenance model, or event stream. setEnabled toggles one entry live through ctx.loader.update and persists an explicit disabled override into the profile's user patch layer so the choice survives a restart (a bundle-default disable needs the disabled: false override to stick).
Every entry carries a protected flag. The guard in src/required.ts is default-open with two code-editable lists: REQUIRED_PLUGINS (the blacklist of load-bearing core that must never be disabled — the entry tree, the Remote RPC spine, the session and agent spines) and USER_TOGGLEABLE_PLUGINS (the whitelist, which overrides the blacklist for an explicitly toggleable plugin); a plugin on neither list is toggleable by default. The full dependency-derived taxonomy of the shipped base bundle is in docs/plugin-system.md. setEnabled refuses to disable a required plugin and, after enabling, verifies the fiber becomes active (reverting a dependency-missing enable). The Web plugin-list tab renders one flat list of every entry: each shows its real enabled state, a toggleable plugin carries an enable or disable button (so a bundle-default-disabled plugin can be re-enabled), and a required plugin shows only a read-only note.
The gateway also manages installation through availableBundles/installPlugin/uninstall. availableBundles lists the curated offline-installable optional bundles in src/bundles.ts (AVAILABLE_BUNDLES); that catalog is empty until an optional bundle ships — the profile's default bundles (dsh-base, dsh-web-app, dsh-image-recognition-bundle) are part of the deployment, not optional add-ons, and uninstall refuses to remove them. installPlugin runs pnpm against the writable profile directory via the bundled Node and vendored pnpm for a registry package spec (the settings plugin-list tab offers this as the "install plugin" form); a registry install is gated behind the dshAllowPluginInstall context flag, which only the desktop boot sets. It tries the ordered INSTALL_REGISTRIES list (src/install.ts) until one succeeds, with the official npm registry last as the fallback, and errors only when every registry is unreachable. When the boot provides a dshReloadProfile handle, the gateway recomposes the running tree after the write so the plugin activates immediately (restartRequired: false); without it, the install persists the manifest and requires a restart (restartRequired: true). Its public payload types live under ./types, and Typert generates the Host and Client Remote artifacts exposed by ./typert and ./remote.
The service is Remote-only and deliberately declares no same-process Cordis Context merge. Client packages consume it through the explicit api-remotes assembly rather than importing the Host implementation.
Model Experience
None, as this Host-only inventory projection registers no prompt, tool, message, or provider request.
KV Cache effect
None; this package never assembles model input.
Known Limitations and Deferred Work
- Point-in-time state only — the result contains no durable failure history or subscription; a missing root Fiber is reported as
null, regardless of why no live root exists. - No provenance or add/remove — the service does not identify which bundle, profile, or override introduced an entry, and it cannot add or remove plugins. Enable/disable persists to the profile's user patch layer; a row the profile does not mount (absent from every bundle) cannot be toggled from here.