KJDRAW / PLUGINS
Plugins
Extend commands, entities, files and workbench surfaces through versioned manifests and explicit cooperative grants.
Declare the contract
{
"schema": "com.kanjie.kjdraw.plugin",
"schemaVersion": 1,
"id": "community.center-marker",
"name": "Center marker starter",
"version": "1.0.0",
"compatibility": { "sdk": ">=1.0.0 <2.0.0", "kernel": "*" },
"permissions": ["commands.register"],
"contributes": { "commands": ["KJ_MARK_CENTER"] }
}
The host inspects the manifest, checks SDK/kernel compatibility and decides which requested permissions to grant. Contributions must be declared before activation.
Activate through a scope
import type {
KJCommandDefinition,
KJDrawSDK,
KJPluginManifest,
} from '@kanjieteam/kjdraw'
export function activate(sdk: KJDrawSDK, manifest: KJPluginManifest) {
const scope = sdk.createPluginScope(manifest, {
grantedPermissions: ['commands.register'],
})
scope.registerCommand({
id: 'KJ_MARK_CENTER',
title: 'Add center marker',
execute: ({ transaction }, args) => transaction.createEntity('CIRCLE', {
center: [Number(args.x ?? 0), Number(args.y ?? 0), 0],
radius: Number(args.radius ?? 5),
}),
} satisfies KJCommandDefinition)
return scope
}
Disposing the returned scope removes registrations owned by that plugin. Keep geometry changes inside commands so validation, receipts, revisioning and undo remain intact.
Extension points
The 1.0 contract includes commands, entity definitions/renderers, file adapters, algorithms, tools, snaps, property panels, keymaps, workspaces, scene sources, ribbons, panels and symbols. Use only declared public extension points; do not patch SDK internals.
Security boundary
Plugin permissions are cooperative declarations, not hostile-code isolation. Run untrusted third-party code in a host-owned Worker, process or sandbox. Start from the official TypeScript plugin starter.