···11+---
22+name: create-lure
33+description: Generate a new .lure file for handling a webhook endpoint. Use when the user wants to add a new webhook handler or lure.
44+---
55+66+Generate a new `.lure` file for handling an incoming webhook.
77+88+## Steps
99+1010+1. **Gather requirements.** If not already provided, ask the user:
1111+ - What webhook source and event is this for?
1212+ - What path should it be mounted at? (e.g. `github/push` → `lures/github/push.lure`)
1313+ - Does the provider sign requests? If so, what method (HMAC?), which header or query parameter carries the signature, and what environment variable holds the secret?
1414+ - What should the LLM do when it receives this webhook?
1515+ - Is there any application-specific config to include?
1616+1717+2. **Write the `.lure` file** to the appropriate path under the `lures/` directory.
1818+1919+## `.lure` file format
2020+2121+A `.lure` file is a Markdown file with YAML frontmatter. The filename without
2222+the `.lure` extension determines the webhook path relative to the configured
2323+base path: `push.lure` handles `<basePath>/push`, and `github/push.lure`
2424+handles `<basePath>/github/push`.
2525+2626+### `verify` (optional)
2727+2828+Specifies how to authenticate incoming webhook requests. Omit if the provider
2929+does not sign requests. Only one strategy may be specified.
3030+3131+HMAC:
3232+3333+```yaml
3434+verify:
3535+ hmac:
3636+ location: header # or "query"
3737+ name: X-Hub-Signature-256 # header or query parameter name
3838+ secret: $ENV_VAR_NAME # must be an environment variable reference
3939+```
4040+4141+### `payload` (optional)
4242+4343+```yaml
4444+payload:
4545+ contentType: json # currently the only supported value
4646+```
4747+4848+### `config` (optional)
4949+5050+An arbitrary object passed as-is to the application callback. Use this for any
5151+application-specific values you want to associate with this lure.
5252+5353+```yaml
5454+config:
5555+ key: value
5656+```
5757+5858+### Template body
5959+6060+Below the frontmatter is an [eta](https://eta.js.org) template. Write it as a
6161+natural language prompt for the LLM that will process the webhook. The
6262+following are available on `it`:
6363+6464+- `it.payload` — the request body (parsed JSON for `contentType: json`)
6565+- `it.headers` — request headers as a `Headers` object (`it.headers.get("X-Foo")`)
6666+- `it.query` — query string as a `URLSearchParams` object (`it.query.get("foo")`)
6767+6868+Use `<%= expression %>` to interpolate values into the prompt.
6969+7070+## Notes
7171+7272+- Secret values must always be environment variable references (`$VAR_NAME`),
7373+ never hardcoded.
7474+- The template body should read naturally as a prompt — write it in the second
7575+ person, as if instructing the LLM receiving it.
7676+- After writing the file, show it to the user for review.
+68
README.md
···7777- `maxAttempts`: How many times to attempt the `callback` before giving up.
7878 Defaults to `1` (no retries). If all attempts fail, the webhook is dropped.
79798080+## Generating lures
8181+8282+Since `.lure` files follow a structured format, they are well-suited to be
8383+generated by an LLM. Copy the prompt below into any LLM conversation, replace
8484+the placeholder at the end with a description of your webhook, and the LLM will
8585+produce a ready-to-use `.lure` file.
8686+8787+````
8888+You are generating a .lure file for the Lure webhook library. A .lure file is
8989+a Markdown file with YAML frontmatter. The filename without the .lure extension
9090+determines the webhook path relative to the configured base path: `push.lure`
9191+handles `<basePath>/push`, and `github/push.lure` handles
9292+`<basePath>/github/push`.
9393+9494+## Frontmatter
9595+9696+### `verify` (optional)
9797+9898+Specifies how to authenticate incoming webhook requests. Omit if the provider
9999+does not sign requests. Only one strategy may be specified.
100100+101101+HMAC:
102102+103103+```yaml
104104+verify:
105105+ hmac:
106106+ location: header # or "query"
107107+ name: X-Hub-Signature-256 # header or query parameter name
108108+ secret: $ENV_VAR_NAME # must be an environment variable reference
109109+```
110110+111111+### `payload` (optional)
112112+113113+```yaml
114114+payload:
115115+ contentType: json # currently the only supported value
116116+```
117117+118118+### `config` (optional)
119119+120120+An arbitrary object passed as-is to the application callback. Use this for any
121121+application-specific values you want to associate with this lure.
122122+123123+```yaml
124124+config:
125125+ key: value
126126+```
127127+128128+## Template body
129129+130130+Below the frontmatter is an eta template (https://eta.js.org). Write it as a
131131+natural language prompt for the LLM that will process the webhook. The
132132+following are available on `it`:
133133+134134+- `it.payload` — the request body (parsed JSON for `contentType: json`)
135135+- `it.headers` — request headers as a Headers object (`it.headers.get("X-Foo")`)
136136+- `it.query` — query string as a URLSearchParams object (`it.query.get("foo")`)
137137+138138+Use `<%= expression %>` to interpolate values into the prompt.
139139+140140+## Task
141141+142142+Generate a .lure file for the following webhook:
143143+144144+[DESCRIBE THE WEBHOOK SOURCE, EVENT TYPE, PAYLOAD SHAPE, VERIFICATION METHOD,
145145+AND WHAT THE LLM RECEIVING THE PROMPT SHOULD DO IN RESPONSE]
146146+````
147147+80148## Lifecycle
8114982150### At Startup