> ## Documentation Index
> Fetch the complete documentation index at: https://docs.buttons.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Hook triggers

> Run a button or drawer when a local event happens.

A hook trigger fires a button when something changes on the local machine. It is one of the three button trigger kinds, and the counterpart to the time-based and inbound-HTTP kinds:

* `cron` — time fires the run (a schedule).
* `webhook` — a remote service POSTs to fire the run.
* `watch` — a local file changes and fires the run. This is the shipped "hook."

All three live on a button's spec and run inside `buttons serve`, which hosts the trigger engine alongside the local REST API.

## Watch a file

```bash theme={null}
buttons trigger add docs-index --watch --path ./docs/CHANGELOG.md
```

`--watch` selects the file-watch kind; `--path` is the single file to watch (required). When that file's size or modification time changes, the button presses.

Pass args that the press should receive each time it fires:

```bash theme={null}
buttons trigger add reindex --watch --path ./data/index.json --arg mode=incremental
```

`--arg KEY=VALUE` is repeatable.

## How watching works

The engine polls the file with `os.Stat` every 500 ms and compares modification time and size. It deliberately does not use fsnotify — polling survives editor rename-on-save and needs no native dependency. The first poll records a baseline and does **not** fire; only a later change triggers the press. Each firing is recorded in run history like a normal press.

Watching is active only while `buttons serve` is running — the same process that serves the REST API also runs the cron/watch trigger engine in-process. Pass `--no-triggers` to serve the API without firing triggers.

```bash theme={null}
buttons serve
```

## Manage triggers

```bash theme={null}
buttons trigger list             # every trigger across all buttons
buttons trigger list <button>    # one button's triggers
buttons trigger rm <button> <trigger-id>
```

`trigger list` shows each trigger's id; `rm` takes the button name and that id. There is no pause/resume — remove and re-add to change a trigger.

## Not yet shipped

Only three trigger kinds exist today: `cron`, `watch`, and `webhook`. There is no `buttons trigger hook ... --enable "<source>"` command, no git-event hooks (`pre-commit`, `post-push`), and no button/drawer lifecycle events (`button:<name>.completed`, `*.failed`). The `--watch` trigger is the way to react to a local file change.

For the other shipped paths:

* Time-based: `buttons trigger add <button> --cron --schedule "0 */6 * * *"`.
* Remote callback into a button: `buttons trigger add <button> --webhook --webhook-path /hooks/x [--token …]`.
* Remote callback into a drawer (n8n-style auth, Cloudflare tunnel): `buttons drawer <name> trigger webhook`, served by `buttons webhook listen`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.