Skip to content

Plugin Development Guide ​

Open Plugins → Plugin Manager → New Plugin and choose Hello, Webview, or Seed&Key DLL. Templates include plugin.json, src/extension.ts, tsconfig.json, and types/. Panel templates also include webview/. BeiniLink compiles background TypeScript or JavaScript when it activates the plugin.

Manifest and activation ​

Set manifestVersion: 1 in plugin.json. Supply a lowercase, dot-separated id, plus name, version, publisher, and engines.beinilink. The template contains the schema at types/plugin.manifest.schema.json. Set main to the background entry and declare commands, ribbon buttons, and views under contributes.

The optional description supports Chinese and English. The manager displays a declared PNG icon up to 256 KiB and 1024 × 1024 pixels, and a Markdown introduction up to 128 KiB that defaults to README.md. Resolve these paths relative to the plugin directory.

A command, a view, or a declared onStartupFinished, onProjectOpen, or onMeasurementStart event can activate the plugin. Add registered subscriptions to context.subscriptions in activate(context). The host disposes them on shutdown. Use deactivate() for any resources your plugin owns.

Project plugins and trust ​

Use the manager to open the global plugins/ folder in app data. For project plugins, place each plugin in its own directory under plugins/ next to the .blproj. A project entry takes precedence over the same global ID, including while it awaits trust. Duplicate IDs in one scope are invalid.

Trusted plugins can access local files and run programs. Trust matches the local project directory, plugin ID, version, and manifest SHA-256. Manifest changes require another decision. Use the manager to grant or revoke trust. The app stores trust locally. It stores disabled settings by global plugin ID or by project directory and plugin ID. Trusting and enabling a project plugin applies to that project.

Background API and state ​

Import the API with import * as bl from "beinilink". See types/beinilink.d.ts in the template for signatures.

  • Use bl.commands.registerCommand for declared commands. Log with bl.window.createOutputChannel or console.log.
  • Subscribe to the measurement lifecycle with bl.measurement. Read variables with bl.variables. The background bl.signals cache uses received frames. Webview signal reads also include transmitted frames.
  • bl.bus.onCanFrame(0x100, callback) matches both standard and extended frames with that ID. Check msg.msgType.idType in the callback. Writing variables and signals and sending frames require an online measurement.
  • bl.workspace.getProjectState() reads this plugin’s state in the open project. Calling await bl.workspace.updateProjectState({ counter: 1 }) marks the project modified. Each plugin state must serialize to at most 1 MiB of JSON. Saving the project writes the state to pluginStates.
  • Use context.storagePath for machine-local files. Project plugins have separate storage per project directory. Global plugins use global storage.

DBC and LDF models are limited to 64 MiB each. Background workers hold their own database copies, so memory use grows with the number of active workers.

Webview ​

Call acquireBeiniLinkApi() in the HTML script. Wait for api.ready before calling getState(). Use setState() for transient state in the open panel, and postMessage and onMessage to communicate with the background. Closing the panel ends its session. Use the project state API for persisted data.

Seed&Key DLL ​

Declare "capabilities": { "native": true }. Call bl.native.dllArchitecture(path) to detect x86 or x64. Pass an absolute path, a Uint8Array seed, and a security level to bl.native.computeSeedKey. Providing options selects GenerateKeyExOpt. The two hosts run in separate processes. Calls default to a 5-second timeout and allow up to 30 seconds.

On x86, automatic mode checks the decorated stdcall export first and then checks the undecorated cdecl export. Select callingConvention: "stdcall" for an x86 stdcall DLL with undecorated exports. This mode checks the decorated export first, then calls the undecorated export using the stdcall ABI. The host passes variant and options as UTF-8. Use ASCII for DLLs that interpret these arguments as ANSI.

Debug and distribute ​

Reload the plugin from the manager after editing its source. Compilation and worker errors appear in the output window. Check API arguments against the generated TypeScript declarations.

Zip the plugin contents and change the extension to .blplugin. Put plugin.json at the root or in a single top-level directory. Use UTF-8 paths and regular files. The expanded package can contain up to 200 MiB and 10,000 entries. The manager installs the package globally and asks to confirm replacement when the ID already exists. When uninstalling a global plugin, choose whether to remove its machine-local data.