Lightkone docs Open Lightkone

Writing a plugin

A plugin is an ES module whose default export is a LightkonePlugin (or a function returning one). Add its URL under Settings → Plugins. The types live in src/core/types.ts.

// my-plugin.js
export default {
  id: "inspire",
  name: "INSPIRE-HEP",
  description: "Adds papers by INSPIRE record id.",
  lookups: [
    {
      id: "inspire",
      label: "INSPIRE record",
      matches: (s) => /inspirehep\.net\/literature\/\d+/.test(s),
      async resolve(s) {
        const id = s.match(/literature\/(\d+)/)[1];
        const r = await fetch(`https://inspirehep.net/api/literature/${id}`);
        const m = (await r.json()).metadata;
        return {
          title: m.titles[0].title,
          authors: m.authors.map((a) => a.full_name),
          year: Number(m.preprint_date?.slice(0, 4)) || undefined,
          arxiv: m.arxiv_eprints?.[0]?.value,
          doi: m.dois?.[0]?.value,
          fields: {},
        };
      },
    },
  ],
  actions: [
    {
      id: "inspire-citations",
      label: "Citations on INSPIRE",
      available: (p) => Boolean(p.arxiv),
      async run(p, ctx) {
        ctx.open(`https://inspirehep.net/search?p=refersto:arxiv:${p.arxiv}`);
        return { kind: "none" };
      },
    },
  ],
};

What a plugin can provide

Field Purpose
storage Places a library can live. create(config) returns a StorageAdapter with read, write, list and optionally remove and seed (papers the backend already holds in another format).
lookups Turn an identifier or link into a paper. The first lookup whose matches returns true is used.
importers Turn pasted text or a file into papers.
actions Buttons on a paper. run returns text to show, a list of papers the user can add, or nothing.
settings Fields shown in Settings, read back as ctx.settings["<plugin id>.<field>"].

Plugins run in the page with full access, so only load code you trust, and serve plugin files with CORS headers that allow the Lightkone origin.

This page on GitHub