Plugin API Reference

The field-by-field reference for aoe-plugin.toml, the manifest every Agent of Empires plugin ships. The schema lives in the aoe-plugin-api crate (PluginManifest) and is the source of truth; this page documents it for plugin authors. The host parses the manifest strictly (unknown keys are rejected), so every key here maps to a schema field.

For a guided introduction see Writing Plugins. To scaffold a working plugin, use the starter template:

cookiecutter gh:agent-of-empires/plugin-template

Versioning

A manifest carries two independent version axes.

KeyMeaning
api_versionThe manifest schema version. The current schema is 6. The host rejects a manifest whose api_version is newer than it supports. Bump it as you adopt newer sections (see below).
aoe_versionA semver requirement on the host app version, e.g. ">=1.11.0, <2.0.0". The host refuses to install, and skips loading, a plugin whose requirement excludes the running version. Optional; requires api_version >= 4.

Schema additions by api_version: 2 added contributions (commands, keybinds, settings, ui), 3 added the pane UI slot, 4 added status and aoe_version, 5 added screenshots, 6 added a command action.

Top-level fields

id = "dev.example.my-plugin"
name = "My Plugin"
version = "0.1.0"
api_version = 6
aoe_version = ">=1.11.0, <2.0.0"
description = "What the plugin does."
capabilities = ["runtime.worker"]
KeyTypeRequiredNotes
idstringyesPlugin id (see Plugin id). Namespaces config, events, and action names.
namestringyesHuman-readable display name.
versionstringyesSemantic version of the plugin.
api_versionintegeryesManifest schema version, 1 to 6.
descriptionstringnoShown in plugin listings. Defaults to empty.
aoe_versionstringnoHost-app semver requirement. Requires api_version >= 4.
capabilitiesarray of stringnoRuntime grants the worker needs (see Capabilities). Static contributions need none.
screenshotsarraynoUp to 8. Requires api_version >= 5. See Screenshots.
setting_defaultstablenoOverrides for core host settings, keyed by canonical path (e.g. "theme.idle_decay_minutes"). Resolution is user value, then plugin override, then core default.

Plugin id

A dotted, lowercase ASCII identifier such as dev.example.review-helper. Each dot-separated segment starts with a lowercase letter and may contain digits and hyphens; the whole id is at most 64 bytes. The aoe.* and agent-of-empires.* namespaces are reserved for bundled and officially featured plugins; a community install cannot claim them.

Capabilities

Capabilities gate runtime resource access. They are prompted once at install and pinned to the manifest hash; an update that widens them must be re-approved. Declare only what the worker uses. Static contributions (commands, keybinds, themes, ui, status) need no capability.

CapabilityGrants
runtime.workerRunning any plugin code at all (host RPCs the worker initiates). Any worker needs this.
session.readReading the attached session.
session.writeMutating the attached session.
config.readReading host or other-plugin configuration (not the plugin’s own settings).
config.writeWriting host or other-plugin configuration.
process.spawnSpawning processes beyond the plugin’s own worker.
netOutbound network access.
fs.readFilesystem reads outside the plugin directory.
fs.writeFilesystem writes outside the plugin directory.
clipboard.readReading the clipboard.
clipboard.writeWriting the clipboard.
notificationsPosting desktop / TUI notifications.
browser_openOpening a URL in the user’s browser from a command action.

A capability this host version does not recognize is rejected, not granted.

Commands

Palette and CLI entries, namespaced by the host as plugin.<id>.<command-id>.

[[commands]]
id = "status"
title = "My Plugin: status"
description = "Show the status summary."
KeyTypeRequiredNotes
idstringyesCommand id. Empty is unaddressable.
titlestringnoDisplay name.
descriptionstringnoHelp text.
actiontablenoA client-executed action. Requires api_version >= 6 and the browser_open capability.

Command action

[commands.action]
kind = "open-ui-link"
slot = "row-badge"
id = "my_badge"

The only kind is open-ui-link: it opens the href from the plugin’s own (slot, id) UI-state entry in the browser, with no worker round-trip. The (slot, id) pair must match a declared [[ui]] entry on a per-session slot.

Keybinds

[[keybinds]]
command = "status"
key = "Ctrl+Shift+G"
KeyTypeRequiredNotes
commandstringyesTarget command id (a plugin or core command).
keystringyesKey chord, e.g. Ctrl+Shift+G. Core bindings win a collision.

Settings

Plugin-declared settings, rendered on the TUI and web settings surfaces and stored under [plugins."<id>".settings]. The worker reads them via the config.get host RPC.

[[settings]]
key = "refresh_secs"
label = "Refresh interval (seconds)"
description = "How often the worker polls."
type = "integer"
default = 120
min = 0
max = 86400
advanced = true
KeyTypeRequiredNotes
keystringyesSetting key, stored under the plugin’s settings table.
labelstringnoDisplay label.
descriptionstringnoHelp text.
typestringnoValue type (see below). Defaults to string.
optionsarray of stringnoAllowed values for select; ignored otherwise.
min / maxintegernoInclusive bounds for integer; ignored otherwise.
defaultanynoDeclared default. Must match type. Absent means the type’s zero value.
advancedboolnoGroup under the Advanced fold. Defaults to false.

Setting types:

typeWidget
stringText input (default).
bool (or boolean)Toggle.
integerNumber input, bounded by min / max.
selectDropdown over a non-empty options array.

UI slots

Declares the host-rendered slots the worker pushes state into via the ui.state.set host RPC.

[[ui]]
slot = "pane"
id = "my_pane"
KeyTypeRequiredNotes
slotstringyesOne of the slot names below. Unknown slots are rejected.
idstringnoAddressing id for (slot, id) state pushes. Required to be non-empty when a command action targets it.
SlotScopeRenders
status-barglobalA segment in the dashboard status bar.
cardglobalA card on the dashboard overview.
sort-keyglobalA named sort option over a row-column value.
filter-facetglobalA named filter over a row-column value.
row-badgeper-sessionA badge on the session row.
row-columnper-sessionA text column on the session row.
detail-badgeper-sessionA badge in the session detail view.
paneper-sessionA dockable tool-window pane (requires api_version >= 3).
notificationn/aA transient notification pushed via ui.notify; gated by the notifications capability, not a slot declaration.

Status

Status segments the plugin contributes, consumed by the status surface. Requires api_version >= 4.

[[status]]
id = "pr_state"
label = "PR state"
KeyTypeRequiredNotes
idstringyesStable segment id.
labelstringnoHuman-readable text.

Themes

[[themes]]
name = "My Theme"
path = "themes/my-theme.toml"
KeyTypeRequiredNotes
namestringyesTheme name in the picker. Must not collide with a builtin.
pathstringyesTheme TOML path, relative to the plugin directory.

Screenshots

Up to 8 marketplace screenshots, shown in the plugin detail view. Requires api_version >= 5.

[[screenshots]]
path = "assets/screenshots/overview.png"
alt = "The plugin's pane showing live status."
caption = "Live status in the pane."
KeyTypeRequiredNotes
pathstringyesRepository-relative image path. No URL scheme, no leading separator, no ..; must be PNG, JPEG, GIF, or WebP.
altstringyesAccessible description; non-empty.
captionstringnoCaption shown beneath the image.

Runtime

The worker the host spawns and supervises. Omit it for a static, metadata-only plugin. Two kinds.

Command

The host runs the build steps at install or update, then launches command.

[runtime]
kind = "command"
command = [".aoe-build/venv/bin/my-plugin-worker"]

[[runtime.build]]
command = ["python3", "-m", "venv", ".aoe-build/venv"]
platforms = ["linux", "macos"]
KeyTypeRequiredNotes
commandarray of stringyesargv. Plugin-relative by default (must contain a path separator, never absolute) so the daemon’s PATH never decides whether the worker launches. With system = true it must instead be a bare program name resolved on PATH.
systemboolnoResolve command[0] on the host PATH (for genuine system tools only). Defaults to false.
buildarraynoOrdered build steps, run once at install or update inside the plugin directory, in the user’s interactive shell.

Build into .aoe-build/ (the host’s build-output directory); the host excludes it from the plugin tree hash, so a venv, node_modules, or target/ there does not break integrity verification.

Build step

KeyTypeRequiredNotes
commandarray of stringyesargv, same resolution policy as the launch command.
platformsarray of stringnoRestrict to OS names: linux, macos, windows. Empty runs on all.

Release binary

The host downloads a release asset instead of building from source.

[runtime]
kind = "release-binary"
asset = "my-plugin-${target}.tar.gz"
bin = "my-plugin-worker"
KeyTypeRequiredNotes
assetstringyesAsset-name template; ${os}, ${arch}, ${target} are substituted before matching the release.
binstringnoExecutable path inside the extracted archive. Omit to run the downloaded asset directly (a raw, non-archive binary).