All types are exported from @binder/plugin-sdk.
The descriptor object your plugin must export as its default export.
interface Plugin {
id: string
name: string
description: string
author: string
version: string
tabType?: string
tabTitle?: string
githubUrl?: string
TabComponent?: React.ComponentType<PluginTabProps>
commands?: PluginCommand[]
checkRequirements?: () => string | null | undefined
}| Field | Required | Description |
|---|---|---|
id |
✓ | Unique kebab-case identifier. Must not clash with other plugins. |
name |
✓ | Human-readable display name shown in the Plugin Store. |
description |
✓ | Short description (1–2 sentences) shown in the Plugin Store card. |
author |
✓ | Author name or GitHub handle. |
version |
✓ | Semver version string (e.g. "1.0.0"). |
tabType |
The tab type string this plugin owns. Inbound app:open-tab events with this type render your TabComponent. Should match your slash command name. |
|
tabTitle |
Text shown on the tab when opened. Defaults to tabType. |
|
githubUrl |
Link shown in the Plugin Store card. | |
TabComponent |
React component rendered inside the plugin's tab pane. | |
commands |
Slash commands this plugin contributes to the terminal. | |
checkRequirements |
Pre-flight check. Return an error string if a dependency is missing, or null if all is well. Shown in the Plugin Store. |
Props injected into your TabComponent by the host app.
interface PluginTabProps {
tabId: string
active: boolean
context: PluginContext
}| Prop | Description |
|---|---|
tabId |
Unique tab ID within the current session. |
active |
true when this tab is the visible/focused one. Use to pause expensive work when hidden. |
context |
Sandboxed API surface — see PluginContext. |
The API surface the host app exposes to each plugin tab.
interface PluginContext {
terminalId?: string
cwd?: string
executeCommand?: (cmd: string) => void
openFile?: (path: string) => void
}| Method / Property | Description |
|---|---|
terminalId |
ID of the terminal that opened this plugin tab. May be undefined if no terminal is associated. |
cwd |
Working directory at the time the plugin tab was opened. May be undefined. |
executeCommand |
Run a shell command in the associated terminal. Only available when terminalId is set. |
openFile |
Open a file path in the editor. |
Sandboxing note: Plugins must not access
windowglobals or the Go backend directly. UsePluginContextfor all host interactions.
A slash command contributed by a plugin.
interface PluginCommand {
name: string
description: string
handler?: () => void
}| Field | Description |
|---|---|
name |
Command name without the leading /. E.g. "my-command" registers /my-command in the terminal. |
description |
Shown in the /help output. |
handler |
Optional callback invoked when the command is typed. If omitted, the command is informational only. |
When a user types /your-tabtype in the terminal, Binder emits an app:open-tab event with type: "your-tabtype". Your plugin is then mounted as the active tab.
You can also trigger it programmatically via context.executeCommand:
context.executeCommand?.('/my-plugin')TabComponentis mounted fresh each time the tab becomes visible after having been fully unmounted (not just hidden). Useactiveprop to gate expensive operations.- Plugins are loaded asynchronously at startup. A tab of your type may already be in the session before your plugin finishes loading — the host handles this gracefully.