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