Mental model
| Concept | Meaning |
|---|---|
| Button | One reusable action. |
| Drawer | A workflow made of steps. |
| Step | A button, sub-drawer, loop, switch, aggregate, or wait position in the drawer. |
| Input | A value supplied when the drawer is pressed. |
| Output | A step’s parsed JSON stdout, available to later steps. |
| Ref | A ${...} expression that reads from inputs, step outputs, env, or webhook URLs. |
drawer.json under the Buttons drawers directory and records its own run history under pressed/.
Create a drawer
add accepts button names. It also accepts drawer/<name> for sub-drawers, for_each:<button> for loops, and wait:<duration> for time pauses.
Wire data between steps
When a button prints valid JSON to stdout, the drawer parses it and exposes it as the step output.${step.output.field} only work against JSON output.
Auto-connect by schema
If a button declaresoutput_schema, buttons drawer <name> connect A to B can match compatible output fields to downstream args.
Drawer inputs
Any unfilled required button arg can be supplied at drawer press time by name.Step kinds
| Kind | Status | Purpose |
|---|---|---|
button | Live | Press a button. |
drawer | Live | Call another drawer. |
for_each | Live | Iterate nested steps over an array. |
switch | Live | Run the first matching branch. |
aggregate | Live | Collect values from an array. |
wait | Live | Pause by duration or until a timestamp. |
split, merge, transform, batch | Reserved | Present in schema for future executors. |
Sub-drawers
A drawer can call another drawer withdrawer/<name>.
return block in drawer.json so the parent can reference selected values as ${child-build.output.<field>}.
Loops
Usefor_each:<button> for per-item work.
| Field | Purpose |
|---|---|
over | CEL expression that resolves to an array. |
as | Loop variable name, default item. |
parallelism | Max concurrent iterations. 0 or 1 means serial. |
on_item_failure | stop or continue. |
results in input order, so downstream refs stay deterministic even when iterations run concurrently.
Switches
Switch steps run the first case whosewhen expression is truthy. Author them in drawer.json.
steps on a switch act as the default branch.
Aggregates
Aggregate steps collect values from an array, often after afor_each.
{ "values": [...], "count": N }, with values in the same order as the input.
Waits
Use waits to pause between steps.Failure handling
By default, a failing step fails the drawer. Step-levelon_failure can be authored in drawer.json for retry or continue behavior:
on_error to call a separate error-handler drawer after failure. The handler receives drawer, run_id, failed_step, error, and redacted inputs. The failure still remains visible in the original drawer run history.
Webhook-triggered drawers
Webhook triggers currently attach to drawers:${inputs.webhook} inside the drawer:
buttons trigger webhook <target> surface should compile down to this same drawer model. If the target is a button, Buttons can create a hidden one-step drawer wrapper.
Inspect and debug
--summary previews a drawer mutation or press without running it. Use --json when an agent or script needs structured output.
buttons drawer schema prints the embedded JSON Schema for drawer.json. See drawer.json for the full field reference.