Skip to main content

Plugin Entry Points

Every plugin exports a default entry object. The SDK provides three helpers for creating them.
Looking for a walkthrough? See Channel Plugins or Provider Plugins for step-by-step guides.

definePluginEntry

Import: velaclaw/plugin-sdk/plugin-entry For provider plugins, tool plugins, hook plugins, and anything that is not a messaging channel.
  • id must match your velaclaw.plugin.json manifest.
  • kind is for exclusive slots: "memory" or "context-engine".
  • configSchema can be a function for lazy evaluation.
  • Velaclaw resolves and memoizes that schema on first access, so expensive schema builders only run once.

defineChannelPluginEntry

Import: velaclaw/plugin-sdk/channel-core Wraps definePluginEntry with channel-specific wiring. Automatically calls api.registerChannel({ plugin }), exposes an optional root-help CLI metadata seam, and gates registerFull on registration mode.
  • setRuntime is called during registration so you can store the runtime reference (typically via createPluginRuntimeStore). It is skipped during CLI metadata capture.
  • registerCliMetadata runs during both api.registrationMode === "cli-metadata" and api.registrationMode === "full". Use it as the canonical place for channel-owned CLI descriptors so root help stays non-activating while normal CLI command registration remains compatible with full plugin loads.
  • registerFull only runs when api.registrationMode === "full". It is skipped during setup-only loading.
  • Like definePluginEntry, configSchema can be a lazy factory and Velaclaw memoizes the resolved schema on first access.
  • For plugin-owned root CLI commands, prefer api.registerCli(..., { descriptors: [...] }) when you want the command to stay lazy-loaded without disappearing from the root CLI parse tree. For channel plugins, prefer registering those descriptors from registerCliMetadata(...) and keep registerFull(...) focused on runtime-only work.
  • If registerFull(...) also registers gateway RPC methods, keep them on a plugin-specific prefix. Reserved core admin namespaces (config.*, exec.approvals.*, wizard.*, update.*) are always coerced to operator.admin.

defineSetupPluginEntry

Import: velaclaw/plugin-sdk/channel-core For the lightweight setup-entry.ts file. Returns just { plugin } with no runtime or CLI wiring.
Velaclaw loads this instead of the full entry when a channel is disabled, unconfigured, or when deferred loading is enabled. See Setup and Config for when this matters. In practice, pair defineSetupPluginEntry(...) with the narrow setup helper families:
  • velaclaw/plugin-sdk/setup-runtime for runtime-safe setup helpers such as import-safe setup patch adapters, lookup-note output, promptResolvedAllowFrom, splitSetupEntries, and delegated setup proxies
  • velaclaw/plugin-sdk/channel-setup for optional-install setup surfaces
  • velaclaw/plugin-sdk/setup-tools for setup/install CLI/archive/docs helpers
Keep heavy SDKs, CLI registration, and long-lived runtime services in the full entry. Bundled workspace channels that split setup and runtime surfaces can use defineBundledChannelSetupEntry(...) from velaclaw/plugin-sdk/channel-entry-contract instead. That contract lets the setup entry keep setup-safe plugin/secrets exports while still exposing a runtime setter:
Use that bundled contract only when setup flows truly need a lightweight runtime setter before the full channel entry loads.

Registration mode

api.registrationMode tells your plugin how it was loaded: defineChannelPluginEntry handles this split automatically. If you use definePluginEntry directly for a channel, check mode yourself:
Treat "setup-runtime" as the window where setup-only startup surfaces must exist without re-entering the full bundled channel runtime. Good fits are channel registration, setup-safe HTTP routes, setup-safe gateway methods, and delegated setup helpers. Heavy background services, CLI registrars, and provider/client SDK bootstraps still belong in "full". For CLI registrars specifically:
  • use descriptors when the registrar owns one or more root commands and you want Velaclaw to lazy-load the real CLI module on first invocation
  • make sure those descriptors cover every top-level command root exposed by the registrar
  • use commands alone only for eager compatibility paths

Plugin shapes

Velaclaw classifies loaded plugins by their registration behavior: Use velaclaw plugins inspect <id> to see a plugin’s shape.