Loam is free and open source for macOS. Your notes stay plain Markdown files on your disk. Download for macOS.[Download for macOS.]
All pages

Plugins

Plugin commands

.md

How a plugin registers a command, what its arguments and result look like, and where the CLI and agents find it.

A command is an action a plugin registers. The palette, the loam command line and AI agents all run it the same way. This page shows how to define a command, how arguments and results work, and where the command shows up.

Register a command

Call context.registerCommand in activate(context:). The handler receives the arguments as text, and returns text, usually JSON:

try context.registerCommand(Command(
    id: "word-count.hello",
    title: "Word Count: say hello",
    summary: "Says hello and how many notes the vault has. No arguments; optional: name."
) { arguments in
    let notes = try vault.markdownPaths().count
    return "Hello \(arguments["name"] ?? "from Word Count"). Notes in this vault: \(notes)."
})
  • id: <plugin id>.<verb>. A second command with the same id is refused.
  • title: the name shown in the command palette.
  • summary: what the command does, for agents. Name its arguments, and say whether it writes.
  • shortcut: an optional default key, such as KeyShortcut("up", [.command]). The user can change it in .loam/config.json.
  • isInPalette: set it to false for a command that needs arguments, or that returns data the palette cannot show. The CLI and agents still run it.

Arguments and results

On the command line, arguments are key=value. For example, loam word-count.hello name=Ada gives the handler ["name": "Ada"].

  • Read a required argument with arguments.require("title"). If it is missing, the command fails with missing argument "title".
  • Return text. For structured data, return JSON with JSON.string(value), which prints pretty output with sorted keys.
  • A successful command prints its result on stdout and exits with status 0.
  • A failed command prints a JSON object with an error key on stderr, and exits with status 1.

Where commands appear

  • The command palette, unless isInPalette is false.
  • loam list, which prints every command as JSON, with its id, title and summary.
  • AI agents, which read the same list and the summary of each command.
  • The open window: loam app run <id> runs a command inside the app, UI commands included.

The commands of a plugin that is off are not listed. loam plugin list shows which plugins are on.

For AI agents: loam list returns every command as JSON. loam guide commands describes the commands of the app itself.