Files
deepseek-harness/packages/boot/plugin-manager/src/errors.ts
T
Yichen Jiang 7b713ca83b refactor(plugin-manager): move plugin management out of the Web host
What plugin management does now lives in `dsh-plugin-manager`, a boot-group
package beside `app-boot`: `PluginInstaller` runs pnpm, probes, and judges new
packages over the profile on disk, and `PluginManager` adds every operation
over the booted tree, each refusal a `PluginOperationError` with a `plugins/*`
code and no Remote protocol attached. The manager reads the profile runtime,
the preset roster, and the running-agent count through per-call readers, and
the roster only as `PresetLayers`, so the package depends on neither the
roster nor the agent registry.

`dsh-host-plugin-manager` keeps `pluginManager` and the `plugins` Remote as a
relay: one Remote method per manager method, and one exhaustive switch
turning a failure into the Remote error of the same code (`plugins/bad-request`
into `gateway/bad-request`). Its `./types` re-exports the manager's types, so
`api-remotes` and the client import one vocabulary unchanged.

`dsh plugin add` and `remove` now run the installer instead of a bare pnpm
forwarder: every new package is probed, a package that declares neither a
bundle nor a plugin module is removed again with its reason, and newly
installed bundles are enabled as before. Other pnpm verbs still forward.
2026-09-07 17:47:08 +08:00

49 lines
1.9 KiB
TypeScript

/**
* The failure a plugin operation raises: a code from the `plugins/*`
* vocabulary and details typed by that code, with no Remote protocol
* attached. The Web host's adapter turns one into a `RemoteError` of the same
* code; the `dsh plugin` command prints it.
* @module @deepseek-ai/dsh-plugin-manager/errors
*/
import type { PluginOperationCode, PluginOperationDetailsMap } from './types.ts'
/**
* One refused or failed plugin operation. Discriminate by `code`: the
* {@link PluginOperationFailure} union narrows `details` per code.
*/
export class PluginOperationError<Code extends PluginOperationCode = PluginOperationCode> extends Error {
/** The stable failure code declared in {@link PluginOperationDetailsMap}. */
readonly code: Code
/** The structured payload the code declares. */
readonly details: PluginOperationDetailsMap[Code]
/**
* @param code - the stable failure code.
* @param message - human diagnostic.
* @param details - structured payload typed by the code.
* @param options - standard Error options; `cause` keeps the underlying failure.
*/
constructor(code: Code, message: string, details: PluginOperationDetailsMap[Code], options?: ErrorOptions) {
super(message, options)
this.name = 'PluginOperationError'
this.code = code
this.details = details
}
}
/** A plugin operation failure as the code-discriminated union, so a `code` branch narrows `details`. */
export type PluginOperationFailure = {
[Code in PluginOperationCode]: PluginOperationError<Code>
}[PluginOperationCode]
/**
* Narrow a caught value to a plugin operation failure.
* @param value - a caught value.
* @returns the failure when `value` is one, otherwise undefined.
*/
export function pluginOperationFailureOf(value: unknown): PluginOperationFailure | undefined {
return value instanceof PluginOperationError ? value as PluginOperationFailure : undefined
}