Skip to content
源码版本47f9438 (dsh@0.1)

Plugin Registry

dsh has two "plugin registration" paths:

  • Static registration: cordis.patch.yml → Loader → ctx.plugin → RegistryService. Repo-bundled plugins, plugins installed by profile, and bundle-layered plugins all go this way.
  • Dynamic registration: the agent injects code into the process at runtime via the cordis_define tool. Session-scoped, not persisted, lost on restart.

Static Registration: PluginInventoryGateway

class PluginInventoryGateway at packages/host/plugin-inventory/src/index.ts:43-70:

  • inject=['loader']
  • @Remote('list') directly iterates loader.entries()
  • Maps entry.fiber.state to the strings pending / loading / active / failed / disposed / unloading
  • No caching on reads; consistency is maintained via Cordis's own events

PluginInventoryGateway.list() exposes only entryId / moduleName / enabled / fiberPhase on non-group entries — it deliberately omits config, because config may contain secrets.

Dynamic Registration: DynamicCordisRegistry

Registry Structure

class DynamicCordisRegistry at packages/extensions/cordis-host-runner/src/registry.ts:141-184:

ts
plugins: Map<…, DynamicCordisPlugin>
nextPlugin / nextPackage / nextRun / nextApproval  // four counters

The four counters mint prefix-N / pkg-N / run-N / approval-N IDs respectively.

DynamicCordisPlugin Structure

DynamicCordisPlugin at packages/extensions/cordis-host-runner/src/registry.ts:36-70:

  • packages: Map<…, DynamicCordisDefinition> — version history
  • approvedClientPackages / clientVersionUpdatesApproved — user authorization gates
  • currentPackageId / nextPackageId / run / latestRun — current and target versions

Runner Service

class DynamicCordisRunnerService extends TypertRemoteService at packages/extensions/cordis-host-runner/src/index.ts:124-145:

  • static inject = ['tools']
  • Holds a DynamicCordisRegistry + CordisInspectRegistryService + a starting Map (to prevent concurrent activations)

define: Define Without Executing

define(request) at packages/extensions/cordis-host-runner/src/index.ts:151-202:

  1. Validates name / purpose.
  2. precheckCode sandbox pre-parse.
  3. Mints plugin / package IDs.
  4. Writes definition.hostCode / clientCode.

Define does not execute — this is the safety boundary of dynamic registration. Code is stored first; activation goes through a separate run.

Immutable Package Versions for Dynamic Plugins

Editing code = cordis_define appending a new packageId; activation = cordis_run switching versions:

  • currentPackageId only advances after success.
  • On failure it does not roll back to the old version (the caller must explicitly run to roll back).

This gives dynamic-plugin version evolution an audit trail, and failure states are observable via the inspect tools.

Two Identity Models

Static PluginDynamic Plugin
IdentityLoader entry idplugin-{prefix}-{N}
Persistencecordis.patch.yml / profileminted in-process, lost on restart
Sourcenpm package / local pathgenerated by the agent at runtime

Docs and Tools Share One Source

class CordisCatalogProjector at packages/typert/generator/src/cordis-catalog.ts:136-200 projects a Service / Event catalog out of the Typert model.

collectEvents / collectServices at packages/typert/generator/src/cordis-catalog.ts:403-413: scans interface Events / interface Context blocks, parsing @mode tags + JSDoc.

cordis-catalog.ts is both the doc generator and the data source for the cordis_inspect_list tool (tool-cordis/src/api-catalog.ts is generated by scripts/gen-cordis-api.ts using the same AST walk), ensuring that "docs" and "the API the model sees" share one origin.

Approval and Cancellation

The pendingRequests index of DynamicCordisRegistry supports cancellation / claiming (claimRequest is first-answer-wins) for an activation request "awaiting user approval". This is the human-in-the-loop gate for dynamic plugins — the agent defines the code, the user approves it in the UI, and only then does the system activate it.

Unofficial community learning site. Content based on the MIT-licensed deepseek-ai/deepseek-harness source. · Privacy · Terms · About