4.5 KiB
Pulse Plugin SDK
The official SDK for building Pulse plugins. This package provides TypeScript types and interfaces to extend Pulse with custom functionality.
[!NOTE] Pulse plugins are an experimental feature and the SDK API may change in future releases.
Creating a Plugin
1. Create Plugin Directory
Create a plugin folder, e.g., my-plugin.
2. Initialize Package
Run bun init to bootstrap your plugin.
3. Edit package.json
Make sure your package.json includes the necessary fields.
Required fields:
name: Plugin identifierversion: Semver version (e.g.,1.0.0)pulse.entry: Entry file (must be.js)pulse.author: Plugin author namepulse.description: Brief description
Optional fields:
pulse.homepage: Plugin website/repository URLpulse.logo: Logo image filename
Example package.json:
{
"name": "my-plugin",
"version": "0.0.1",
"module": "src/index.ts",
"pulse": {
"entry": "index.js",
"author": "Me",
"homepage": "https://some-page.com",
"description": "This is my first Pulse plugin!",
"logo": "https://some-page.com/logo.png"
},
"type": "module",
"scripts": {
"build": "bun build src/index.ts --outdir dist --target bun --minify --format esm && cp package.json dist/"
},
"devDependencies": {
"@types/bun": "latest"
},
"peerDependencies": {
"typescript": "^5"
}
}
4. Install SDK
bun add @pulse/plugin-sdk
[!NOTE] The SDK is not published to any package registry. For now, you need to link it locally using
bun link.
3. Edit Entry File
import type { PluginContext } from "@pulse/plugin-sdk";
const onLoad = (ctx: PluginContext) => {
ctx.log("My Plugin loaded");
ctx.events.on("user:joined", ({ userId, username }) => {
ctx.log(`User joined: ${username} (ID: ${userId})`);
});
};
const onUnload = (ctx: PluginContext) => {
ctx.log("My Plugin unloaded");
};
export { onLoad, onUnload };
Compile to JavaScript before loading:
bun run build
Lifecycle
onLoad
Called when the plugin is loaded. This is where you should:
- Register event listeners
- Register commands
- Initialize resources
- Set up external connections
onUnload
Called when the plugin is unloaded or the server shuts down. Use this to:
- Clean up resources
- Close connections
- Save state
Note: All event listeners and commands are automatically unregistered when the plugin unloads.
Commands
Plugins can register custom commands that users can execute. Commands can accept arguments and return results.
Registering a Command
import type { PluginContext, TInvokerContext } from "@pulse/plugin-sdk";
const onLoad = (ctx: PluginContext) => {
ctx.commands.register({
name: "greet",
description: "Greet a user",
args: [
{
name: "username",
type: "string",
description: "The user to greet",
required: true,
sensitive: false, // set to true if the argument is sensitive (e.g., passwords), in the interface it will be shown as ****
},
],
async executes(invokerCtx: TInvokerContext, args: { username: string }) {
ctx.log(`Greeting ${args.username} invoked by user ${invokerCtx.userId}`);
return "Hello, " + args.username + "!";
},
});
};
Adding The Plugin to Pulse
- Go to the Pulse data directory (usually
~/.config/pulse). - Create a
pluginsfolder if it doesn't exist. - Create a folder for your plugin (e.g.,
my-plugin). - Copy your compiled plugin files (e.g., from
dist/) into themy-pluginfolder. - Enable your plugin in the server settings under the "Plugins" section.
- Restart Pulse or reload plugins from the admin panel.
- Your plugin should now be loaded and active!
Best Practices
- Always handle errors: Wrap async operations in try-catch blocks
- Clean up resources: Implement
onUnloadto prevent memory leaks - Use TypeScript: Get type safety and better IDE support
- Log appropriately: Use
debugfor verbose info,errorfor failures - Validate inputs: Check command arguments before using them
- Version carefully: Follow semver for plugin updates
- Prevent blocking operations: Do NOT block the event loop with long-running tasks (example: using Bun.spawnSync). Use asynchronous methods instead.
API Reference
No documentation available yet. Use the types in packages/plugin-sdk/src/index.ts as a reference.
License
This SDK is part of the Pulse project. See the main repository for license information.