# Authoring Buttonizer Buttons - `.buttonize` Reference (for AI agents) > Self-contained: an agent that reads ONLY this file can create valid, > well-behaved buttons on a user's host. Reflects the app's actual parser > (`ButtonDef` / `ParamDef`) as of 2026-09-13. For a **desktop or Windows** > target, section 8 applies on top of everything else. Deep dives (open only when needed): field reference (English) - https://buttonizer.app/yaml · runnable examples - `examples/` · CLI appendix - `docs/desktop-cli.md` · failure-repair wrapper - `docs/agent-wrapper-pattern.md` · end-user manual - `Manual.md` ## 0. TL;DR A button is a **directory** containing a **`button.yml`** file: ``` ~/.buttonize/buttons///button.yml ``` Create that file under the desktop's `~/.buttonize/buttons/` tree and the paired phone picks it up on its next list refresh (~10 seconds while the app is open). No daemon, no restart. Minimum viable button: ```yaml # ~/.buttonize/buttons/hello/button.yml id: hello title: Hello command: echo "Hello from $(hostname)" updated_at: "2026-09-13T00:00:00Z" ``` Rules that bite (details in the linked sections): | # | Rule | |---|---| | 1 | The directory name MUST equal the `id` value. | | 2 | Bump `updated_at` to the current UTC (`YYYY-MM-DDTHH:MM:SSZ`) on EVERY edit - the desktop records it on save and the phone compares it (§6). | | 3 | Quote every hex color (`color: "#3B82F6"`) - an unquoted `#` starts a YAML comment and silently nulls the field. | | 4 | Every `{{param}}` in `command` needs a matching `params:` entry (§3); a scheduled button needs a `default` for each one (§2.3). | | 5 | `enabled: false` = drawn dimmed and **not run by any path** (manual, scheduled, service start, CLI); the run/start APIs refuse it with HTTP `409`; omit the key for a normal button (§2.2). | | 6 | Never touch the app-managed run records inside a button bundle: `status.json` (last run state), `tail.log` (output tail) and `history/.jsonl` (§1). | | 7 | Commands are NOT always POSIX: a Windows desktop runs them through `cmd /C` (§8). | | 8 | **Defaults are a promise.** Write a default (top-level key or `params[].default`) only when that value is certain to be used in almost every run, or when it was explicitly requested - otherwise omit it and let the run sheet ask (§2.6). | --- ## 1. `~/.buttonize/` layout | Path | Role | Who writes it | |---|---|---| | `buttons/` | All buttons + folders. The desktop owns them; the paired phone reads/writes them over the channel RPC (`list_buttons` / `button_edit_full`). | You and the app | | `buttons//folder.yml` | Folder presentation attrs: `icon`, `order`. Optional — **a directory under `buttons/` is a folder whether or not this file exists**, and empty folders stay visible on the desktop and on every paired phone. Use `folder.yml` only to set an icon or a manual order. | You | | `buttons///button.yml` | One button definition. | You | | `buttons///