Skip to content

Plugins

This is the runtime and manifest reference for workspace plugins. For the authoring walkthrough (the extension-point TypeScript contracts, a complete minimal publisher, register(api)), see Writing plugins.

Plugins extend the engine at four points - publishers, renderers, lint-rules, and auth-strategies - and run in-process, unsandboxed, under the same no-model-API contract as the engine itself.

FieldType / shapeRules
apiVersionexact semver string (x.y.z)Must share the runtime’s major version with minor at or below the runtime’s. A plugin built for 1.0.0 runs under runtime 1.5.0; one built for 1.6.0 or 2.0.0 load-errors.
namespacekebab-case, /^[a-z][a-z0-9-]*$/Mandatory. Every registered artifact is exposed as <namespace>:<name> (the runtime prefixes; plugins pass bare names). Reserved: docsxai, docsxai, core, plugins. Two plugins claiming one namespace are both disabled.
registerrelative path stringThe module exporting register(api) (named or default export).
kindsarray of publisher | renderer | lint-rules | auth-strategyAt least one. Registering an undeclared kind throws and load-errors the plugin.
capabilitiesarray of capability strings (default [])Subset-checked against the workspace’s plugin_capabilities; a mismatch disables the plugin.
dependsOnarray of { plugin, version } (default [])Package name plus a ^x.y.z, ~x.y.z, or exact range. Load order is topological; cycles are rejected as a unit; a disabled dependency disables its dependents.
trustkalebtec | community | local (default local)A review signal, not a sandbox boundary.

A missing docsxai field means “not a plugin”; a malformed manifest is a load error - the plugin never reaches register().

The only capability family today is target-host egress:

egress:<host-glob> e.g. egress:*.atlassian.net

Globs allow * in host positions. Unknown capability prefixes are rejected at manifest parse time, so a manifest cannot smuggle an undisclosed capability past review. Publisher plugins are the only wiki/VCS egress path in the engine.

docsxai plugins list reports one status per configured plugin. Every failure is a status, never a crash of the resolve:

StatusMeaning
loadedManifest valid, lock verified, register() succeeded.
disabled-by-capability-mismatchDeclared capabilities are not a subset of the workspace’s plugin_capabilities.
disabled-by-cycleThe plugin participates in a dependsOn cycle (the whole cycle is disabled).
disabled-by-dep-missingA dependsOn entry is absent, disabled, or fails its version range.
disabled-by-namespace-conflictAnother plugin claims the same namespace (both are disabled).
load-errorMalformed or incompatible manifest, lock mismatch, or register() threw (that plugin’s artifacts are rolled back).

A statusReason string accompanies every non-loaded status.

Two optional .docsxai.json keys:

{
"plugins": [{ "package": "@docsxai/plugin-confluence" }, { "path": "../my-local-plugin" }],
"plugin_capabilities": ["egress:*.atlassian.net"]
}

A source is either { package } (resolved through Node from the workspace) or { path } (a local directory). Plugins are resolved once per CLI invocation; there is no hot reload.

Schema docsxai/plugins-lock@1, next to the workspace config:

{
"schema": "docsxai/plugins-lock@1",
"plugins": {
"@docsxai/plugin-confluence": {
"source": "package:@docsxai/plugin-confluence",
"version": "0.1.0",
"sha256": "<hex sha256 of the register module's bytes>"
}
}
}

The lock pins the sha256 of each plugin’s register-module file bytes. When the file exists, every resolve verifies the bytes before importing; a silently-swapped module fails closed with a “run docsxai plugins sync” message. Commit the lock; re-sync deliberately when you upgrade a plugin.

docsxai plugins list <workspace> status table (loaded / disabled reasons); exit 1 if any plugin is not loaded
docsxai plugins info <workspace> <namespace> manifest + registered artifact names
docsxai plugins sync <workspace> (re)write plugins-lock.json - never executes plugin code

All three accept --format json. A typical session, from wiring to verification:

$ docsxai plugins sync ~/docsxai/my-app
plugins sync: wrote ~/docsxai/my-app/plugins-lock.json (2 plugin(s))
$ docsxai plugins list ~/docsxai/my-app
plugins (2 configured, 2 loaded):
confluence loaded v0.1.0 kalebtec publisher package:@docsxai/plugin-confluence
demo loaded v0.0.1 local publisher path:../my-local-plugin
$ docsxai plugins info ~/docsxai/my-app confluence
confluence loaded v0.1.0 kalebtec publisher package:@docsxai/plugin-confluence
apiVersion: 1.0.0
capabilities: egress:*.atlassian.net
dependsOn: (none)
artifacts (1):
publisher push

A plugin that is not loaded shows its status plus a ↳ <statusReason> line, and list exits 1 - wire that into CI so a silently disabled publisher cannot pass unnoticed.

Made by Kalebtec · GitHub · Apache-2.0 licensed