Analysis checks
Add a check to Athanor's issues badge with a plugin: return findings for atoms on the page, keep within the time budget, and pick a severity.
What a check is
A check looks at the page after each edit and reports findings: something worth a second look, tied to an atom. Findings appear in Athanor's issues badge (the one that reads No issues when there are none) beside Athanor's own, and each title ends with your plugin's name, so the person knows where it came from.
A minimal check
This is the Analysis check template from New plugin: Analysis check template…. It flags structures heavier than 500 g/mol.
manifest.json:
{
"id": "local.heavy-structures",
"name": "Heavy structures",
"version": "0.1.0",
"api": "1.0.0",
"author": "You",
"description": "Heavy structures, made from the check template.",
"main": "main.js",
"permissions": ["document.read"],
"contributes": {
"checks": [{ "key": "heavy", "title": "Heavy structures", "runOn": "change" }]
}
}main.js:
// @ts-check
/// <reference path="./athanor.d.ts" />
// A check: runs half a second after each edit (keep it under 300 ms). Findings show in the issues badge.
athanor.checks.on('heavy', (page) => page.structures
.filter((s) => (s.mw ?? 0) > 500)
.map((s) => ({ atom: s.atoms[0].id, severity: 'note', title: 'Heavy structure', message: `${s.formula} weighs ${s.mw} g/mol, over 500 (Lipinski).` })));The handler receives the page snapshot (the same object athanor.snapshot() returns) and returns a list of findings, or a promise of one.
A finding
| Field | Meaning |
|---|---|
atom |
The id of the atom the finding points at. Required: a finding whose atom is not on the page is dropped |
severity |
error, warning or note (the default) |
title |
A short name, up to 80 characters. Athanor adds " · plugin name". Defaults to the check's title |
message |
One or two sentences saying what is wrong and what to do, up to 400 characters |
A finding for a whole structure points at one of its atoms, as the template does with s.atoms[0].id.
A second example
This example plugin flags unusual charges on single atoms. It shows how to return several findings per structure:
athanor.checks.on('charges', (page) => page.structures.flatMap((s) => s.atoms
.filter((a) => Math.abs(a.charge) >= 3 || (['F', 'Cl', 'Br', 'I'].includes(a.element) && a.charge > 0 && s.atoms.length > 1))
.map((a) => ({ atom: a.id, severity: 'warning', title: 'Unusual charge',
message: a.element + ' carries a charge of ' + (a.charge > 0 ? '+' : '') + a.charge + ', which is rare. Check it is meant.' }))));When checks run
Checks with "runOn": "change" run half a second after the last edit, and once when the plugin is installed. The findings from the previous run stay until the next one replaces them.
Rules and limits
| Rule | Value |
|---|---|
| Permission | document.read is required; a manifest with checks and without it is refused |
| Checks per plugin | 50. key follows the command key rule; title is required, at most 60 characters |
| Time budget per run | 300 ms for community plugins, 1 second for official ones |
| Over budget | That run's findings are skipped. Three overruns in a row pause the check for the rest of the session |
| Findings per run | 200; any beyond are dropped |
Keep a check fast and pure: read the snapshot, return findings. A check that throws counts as a plugin error and toward the three failures that turn a plugin off.
Declared but not used yet
"runOn": "demand" is accepted, for checks the person runs by hand. API 1 has no control that runs them yet, so a demand check never runs. Use "change".
Findings in API 1 have no fixes. To offer a fix, add a command that proposes the change.
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
