Skip to main content
A Drawer is a reusable package. Schema v2 distinguishes an action Drawer, which is pressed as a graph of steps, from a flow Drawer, which defines a proactive board that a platform runtime activates and supervises. Its source of truth is drawer.json.
Project-local drawers use the same shape under .buttons/drawers/<name>/.

Action Drawer example

Schema-v1 action Drawers remain readable, installable, and pressable. New Drawers are written as schema v2.

Flow Drawer example

Flow Drawers describe arbitrary board stages and policy. They do not contain steps and cannot be pressed locally as action Drawers.
Create and edit the definition through the CLI:
Publishing a valid flow Drawer adds a normalized flow-definition.json to the immutable artifact and sends its SHA-256 as registry metadata. Installation rejects the package if that definition does not exactly match drawer.json.

Top-level fields

Step kinds

References

Step args and drawer fields can use ${...} expressions. The expression body is CEL.
Hyphenated step IDs are supported in refs; Buttons rewrites them internally so CEL can parse them.

Inputs

Drawer inputs mirror button args and add secret redaction:
Secret inputs can still flow into a step’s resolved args, but they are redacted from drawer history.

Failure handling

Step-level on_failure controls one step:
Supported actions are stop, continue, and retry. Drawer-level on_error calls another drawer after a failed run. The handler receives drawer, run_id, failed_step, error, and redacted inputs.

Webhook triggers

Webhook triggers are stored in triggers.
Inside the drawer, the request appears as ${inputs.webhook.body}, plus headers, query, method, path, and received_at.

Schema

Print the embedded JSON Schema:
The published copy lives at docs/schemas/drawer.schema.json.