One JSON file per action, stored in the project’s actions folder. Edit them through the action editor (tree → action, or New action in the menu) — md² never shows raw JSON, but this is what ends up on disk.
{
"id": "implement",
"label": "Implement",
"description": "Implement this feature",
"type": "agent",
"prompt": "Read and implement the feature described in {{card-file}}",
"needsWorkTree": true,
"appliesTo": { "kind": "card", "type": "feature" },
"onBefore": ["prep-to-implement"],
"onAfter": ["complete-card"]
}
| Field | Required | Meaning |
|---|---|---|
id |
yes | Stable identifier. Links and run requests use it, so renaming the label never breaks a chain. Must be unique, also after normalization (My Action and my_action collide). |
label |
yes | Text shown on buttons and menu entries. |
description |
yes | Shown in the action popup. |
type |
yes | agent or command. |
prompt |
agent only | Markdown prompt. Not allowed on command actions. |
command |
command only | Command line. Not allowed on agent actions. |
userInput |
no | { "type": "version" } asks once before a run starts. Optional prompt changes the dialog question. Both action types support it; linked actions share the answer. |
icon |
no | Icon shown by entry points. |
appliesTo |
no | Filters deciding where the action appears. See below. |
output |
no | { "kind": "diagram" } makes the action create a diagram. Requires appliesTo.kind to be diagram. |
onBefore |
no | Ordered list of action ids to run first. |
on |
no | Ordered list of { "condition": "<regex>", "actionId": "<id>" } rules matched against this action’s output. |
onAfter |
no | Ordered list of action ids to run afterwards. |
onState |
no | Card state that triggers this action when a card enters it. |
needsWorkTree |
no | When true, the action requires a card with a valid worktree assignment and runs there. |
trackFileChanges |
no | Agent actions only. Records the files the run touched. |
streaming |
no | Agent actions only. true keeps one live provider session across turns. |
autoFinish |
no | Agent actions only, requires streaming. { "state": "<card state>" } finishes when a card reaches that state. Diagram-output actions can use { "when": "diagram-created" } to finish when the diagram is created. |
agent |
no | Agent profile override. Required when model is set. |
model |
no | Model override. Requires agent. |
thinkingLevel |
no | none, low, medium, high, or max. Requires agent and model. |
phrases |
no | Named snippets (title + text) offered as quick buttons while running the action. |
Unknown fields are rejected at load time rather than silently ignored.
The version answer is free-form text containing at least one non-whitespace character. Interactive runs ask before any linked action executes. Unattended runs require a supplied value. The latest confirmed value is saved in project configuration, prefilled next time, and offered as an editable release name; completing a release does not clear it.
appliesToAn object of context filters. Every configured filter must match for the action to appear.
| Filter | Matches |
|---|---|
kind |
Context type: card, diagram, file, folder, merge-conflict, or project. Agent actions with merge-conflict appear in the merge conflict dialog; see Worktrees. |
type |
Card type, for example feature, bug. |
state |
Card status. |
file |
File the context points at. |
folder |
Folder the context points at. |
worktree |
Worktree assignment on the card. |
worktreeError |
Worktree problem reported for the card. |
No appliesTo means the action is available in every supported context.
"appliesTo": { "kind": "card", "state": "ready for implementation" }
Use appliesTo.kind: "diagram" and output.kind: "diagram" for an action that creates a diagram. Set appliesTo.type to root for a project-level diagram or child for a diagram opened from a selected item. In the action editor, choose Diagram as the output kind. The generated diagram is JSON at the path supplied by {{diagram-file}}; agent prompts also receive the configured diagram footer. Streaming agent actions can finish automatically with autoFinish: { "when": "diagram-created" }.
{
"id": "project-architecture",
"label": "Project architecture",
"description": "Generate an architecture diagram for this project",
"type": "agent",
"prompt": "Describe the main components and their connections.",
"appliesTo": { "kind": "diagram", "type": "root" },
"output": { "kind": "diagram" }
}
See Diagrams for the editing workflow and Placeholders for diagram-specific placeholders.
Definitions are validated when they load and again before they are saved. md² refuses to run or store an action that fails, and shows the error on the offending field. Rejected cases include:
id, label, description, or type;prompt on a command action, command on an agent action;streaming, autoFinish, or trackFileChanges on a command action;autoFinish without streaming, or an autoFinish.state that is not a configured column;diagram-created auto-finish trigger without diagram output;model without agent, thinkingLevel without both;on condition;onBefore, on, or onAfter;onBefore, on, or onAfter;after, before, runIn, text, or type cmd.Two actions exist without a file:
| Id | What it does |
|---|---|
md2.custom-prompt |
Sends whatever you type to the agent. Streaming. Always available in supported contexts. |
md2.convert-remarkable-images-to-text |
Transcribes imported images and appends the text to the card. |
They cannot be edited or deleted, and project actions may not reuse their ids.
See also: Placeholders, Running actions, Agent setup, Cookbook.