plugin.toml reference
Every plugin carries a plugin.toml declaring what kind of plugin it is, how to load it, and what it is allowed to touch.
plugin.toml lives at the root of a plugin folder inside ~/.dna/plugins/. It is a small text file, read at every startup and on every reload, and it is what registers the plugin's nodes. Anything wrong in the file stops the plugin loading and reports why, so a typo fails loudly rather than doing nothing.
Writing shader and node plugins is covered in Authoring a shader plugin and Authoring a node plugin. This page is the manifest reference.
The [plugin] section
Every manifest starts with a [plugin] block describing the plugin itself.
[plugin]
name = "Fast Noise"
version = "0.1.0"
api_version = "2.0.0"
name. The display name shown in DNA.
version. Your plugin's own version, your choice.
api_version. Which DNA plugin API the plugin was built against. The host is at
2.0.0, and the match is by major version: a plugin declaring2.0.0loads into any2.xhost, and anything outside that range is refused with a version-mismatch message rather than producing a mysterious crash from a mismatched build.
Right after [plugin] comes exactly one plugin type. A manifest that declares none, or more than one, will not load.
Choosing a plugin type
There are four kinds, each a small sub-section under [plugin].
Shader adds image-effect nodes written in shader code. It is the lightest and safest type, and the one to start with.
[plugin.shader]
The section is a marker with no fields. The shaders themselves are listed separately in [[shader]] blocks, below.
Python runs a Python script. Point entry at the script file.
[plugin.python]
entry = "main.py"
Rust loads a compiled Rust library. Give the library's base name; the right file extension for your operating system is added.
[plugin.rust]
library = "libfast_noise"
Native loads a compiled C-compatible library, same idea as Rust.
[plugin.native]
library = "libfast_noise"
[[shader]] entries
A shader plugin lists one or more nodes, each in its own [[shader]] block; the double brackets mean one of a list. At least one is required.
[[shader]]
id = "custom.chromatic_aberration"
display_name = "Chromatic Aberration"
description = "Splits colour channels for a lens-fringe look"
category = "Stylize"
keywords = "lens, fringe, glitch"
file = "chromatic.wgsl"
language = "WGSL"
shader_type = "Fragment"
inputs = ["content"]
id (required). The node's unique identifier, like
custom.chromatic_aberration. No two shaders in the plugin may share one.display_name (required). The name shown on the node and in search.
description. A short line explaining what it does.
category. Which group it appears under in the node search and palette.
keywords. Extra search terms, comma-separated.
file (required). The path to your shader source, relative to the plugin folder. It must end in
.wgslor.glsl, and it cannot point outside the plugin folder:..and absolute paths are rejected.language.
WGSL(the default) orGLSL.shader_type.
Fragment(the default, an image effect) orCompute.inputs. The named image inputs the node accepts, up to four. Defaults to a single input called
content.
The [capabilities] section
A plugin declares here which powers beyond plain computation it intends to use. The declaration is checked when the plugin loads, and it is what a reader of your manifest goes by.
[capabilities]
gpu = true
state = true
filesystem = true
network = true
plugin_host = true
gpu. Use the graphics card directly for heavy compute.
state. Remember data between cooks, as per-node memory.
filesystem. Read files from disk.
network. Open network connections.
plugin_host. Load other plugins.
Every flag defaults to off, and a misspelled flag name makes the manifest fail to load rather than granting nothing in silence.
Declare only the capabilities you actually use. A plugin that asks for nothing loads in any project. A plugin that asks for anything loads only in a trusted one.
This block is a declaration, not a sandbox. In a Restricted project, which is every project until you trust its path, a native or Rust plugin that requests any capability is refused outright and does not load at all. In a trusted project the flags are advisory: there is no extension registry behind them yet and no path restriction anywhere, so a plugin's own code reaches the disk and the network whatever it declared. Read the block before installing something; do not rely on it to hold the plugin back. See Trust & Permissions and Capabilities & trust.
A complete example
A small shader plugin, start to finish:
[plugin]
name = "Fast Noise"
version = "0.1.0"
api_version = "2.0.0"
[plugin.shader]
[[shader]]
id = "custom.fast_noise"
display_name = "Fast Noise"
description = "Animated value noise"
category = "Generate"
file = "noise.wgsl"
inputs = ["content"]
No [capabilities] section means no special permissions, so this one loads in any project without a trust prompt.