Commands
Add commands to Athanor's Plugins menu, the canvas right-click menu and Ctrl+K, handle them in main.js, and act on the current selection.
What a command is
A command is an action a person runs by name. It has no window of its own: it runs, does its work, and ends. A command can read the page, change it, open a window, or tell the person something with a short message.
Each command you declare appears in three places, as soon as the plugin is installed:
- Main menu › Object › Plugins › command title
- Right-click on the canvas › Plugins › plugin name › command title
Ctrl+K, on the Plugins tab and in ordinary search
A minimal command
This command colors every selected structure red. It needs Edit the document and nothing else: a plugin without Read the open document can still learn which structures are selected, by id.
manifest.json:
{
"id": "yourname.color-red",
"name": "Color red",
"version": "1.0.0",
"api": "1.0.0",
"author": "Your Name",
"description": "Colors the selected structures red.",
"main": "main.js",
"permissions": ["document.edit"],
"contributes": {
"commands": [{ "key": "color-red", "title": "Color the selection red" }]
}
}main.js:
// @ts-check
/// <reference path="./athanor.d.ts" />
athanor.commands.on('color-red', async () => {
const sel = await athanor.selection();
if (!sel.structures.length) {
athanor.notify('Select a structure first.');
return;
}
await athanor.apply({
label: 'Color red',
ops: sel.structures.map((id) => ({ op: 'setStyle', id, color: '#d03030' })),
});
});The handler's key, color-red, must match the key in the manifest. Running the command calls the handler; the whole edit is one undo step named "Color red: Color red".
Reading the selection
athanor.selection() resolves with { structures, atoms }: structure ids such as "s:12" and atom ids as numbers. It works with or without Read the open document. To learn anything else about those structures (their atoms, bonds, formula or name), the plugin needs Read the open document and calls athanor.snapshot(), where each structure carries selected: true when any of its atoms is selected. See API reference.
The right-click menu passes nothing special: whatever was selected when the menu opened is what athanor.selection() returns.
Telling the person something
athanor.notify('Numbered 3 structures.');
athanor.notify('The page has no structures.', { error: true });The message shows as Athanor's toast, starting with your plugin's name. It is cut at 100 characters, and a plugin can show at most 12 a minute; any beyond that are dropped.
athanor.closePlugin(message) shows an optional message and closes the plugin's floating window if it has one.
Errors
If the handler throws or its promise rejects, the person sees "Plugin hit an error: first line of the message". The full message goes to the plugin console. A change the handler was making is never half applied: athanor.apply either makes the whole change or none of it. Catch errors you expect, and say something useful with athanor.notify instead.
athanor.commands.on('color-red', async () => {
try {
const sel = await athanor.selection();
await athanor.apply({ label: 'Color red', ops: sel.structures.map((id) => ({ op: 'setStyle', id, color: '#d03030' })) });
} catch (e) {
athanor.notify(String(e.message), { error: true });
}
});Rules and limits
| Rule | Value |
|---|---|
| Commands per plugin | 50 |
key |
Lowercase letters, digits, dots, dashes and underscores, starting with a letter or digit; at most 64 characters; unique within the plugin |
title |
Required, at most 60 characters |
| Handlers per key | Register one. If you register two for the same key, only the first runs |
| Time | One run of synchronous code may take 5 seconds (15 for official plugins) before the plugin is stopped |
| A plugin that is off | Its commands are refused with "Plugin is turned off" |
Declared but not used yet
The manifest accepts two more fields on a command. API 1 stores them but does not act on them yet, so do not rely on them:
menu: a submenu path such as["Export"], up to three names. Commands appear directly under the plugin's name for now, and the words helpCtrl+Kfind the command.parameters: up to ten{ key, name, optional }entries. The handler receives an object, but API 1 has no control that fills it in, so it is always{}.
Next: Panels and windows to give a command a window.
Is this helpful?
Last updated Nov 11, 2026
- Still stuck? Read the FAQ or contact support.
- Something wrong on this page? Tell us.
- For AI tools: llms.txt
