Enable LLMs to handle webhooks with plaintext files
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

add create-lure skill and generating lures section to README

+144
+76
.claude/skills/create-lure/SKILL.md
··· 1 + --- 2 + name: create-lure 3 + description: Generate a new .lure file for handling a webhook endpoint. Use when the user wants to add a new webhook handler or lure. 4 + --- 5 + 6 + Generate a new `.lure` file for handling an incoming webhook. 7 + 8 + ## Steps 9 + 10 + 1. **Gather requirements.** If not already provided, ask the user: 11 + - What webhook source and event is this for? 12 + - What path should it be mounted at? (e.g. `github/push` → `lures/github/push.lure`) 13 + - 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? 14 + - What should the LLM do when it receives this webhook? 15 + - Is there any application-specific config to include? 16 + 17 + 2. **Write the `.lure` file** to the appropriate path under the `lures/` directory. 18 + 19 + ## `.lure` file format 20 + 21 + A `.lure` file is a Markdown file with YAML frontmatter. The filename without 22 + the `.lure` extension determines the webhook path relative to the configured 23 + base path: `push.lure` handles `<basePath>/push`, and `github/push.lure` 24 + handles `<basePath>/github/push`. 25 + 26 + ### `verify` (optional) 27 + 28 + Specifies how to authenticate incoming webhook requests. Omit if the provider 29 + does not sign requests. Only one strategy may be specified. 30 + 31 + HMAC: 32 + 33 + ```yaml 34 + verify: 35 + hmac: 36 + location: header # or "query" 37 + name: X-Hub-Signature-256 # header or query parameter name 38 + secret: $ENV_VAR_NAME # must be an environment variable reference 39 + ``` 40 + 41 + ### `payload` (optional) 42 + 43 + ```yaml 44 + payload: 45 + contentType: json # currently the only supported value 46 + ``` 47 + 48 + ### `config` (optional) 49 + 50 + An arbitrary object passed as-is to the application callback. Use this for any 51 + application-specific values you want to associate with this lure. 52 + 53 + ```yaml 54 + config: 55 + key: value 56 + ``` 57 + 58 + ### Template body 59 + 60 + Below the frontmatter is an [eta](https://eta.js.org) template. Write it as a 61 + natural language prompt for the LLM that will process the webhook. The 62 + following are available on `it`: 63 + 64 + - `it.payload` — the request body (parsed JSON for `contentType: json`) 65 + - `it.headers` — request headers as a `Headers` object (`it.headers.get("X-Foo")`) 66 + - `it.query` — query string as a `URLSearchParams` object (`it.query.get("foo")`) 67 + 68 + Use `<%= expression %>` to interpolate values into the prompt. 69 + 70 + ## Notes 71 + 72 + - Secret values must always be environment variable references (`$VAR_NAME`), 73 + never hardcoded. 74 + - The template body should read naturally as a prompt — write it in the second 75 + person, as if instructing the LLM receiving it. 76 + - After writing the file, show it to the user for review.
+68
README.md
··· 77 77 - `maxAttempts`: How many times to attempt the `callback` before giving up. 78 78 Defaults to `1` (no retries). If all attempts fail, the webhook is dropped. 79 79 80 + ## Generating lures 81 + 82 + Since `.lure` files follow a structured format, they are well-suited to be 83 + generated by an LLM. Copy the prompt below into any LLM conversation, replace 84 + the placeholder at the end with a description of your webhook, and the LLM will 85 + produce a ready-to-use `.lure` file. 86 + 87 + ```` 88 + You are generating a .lure file for the Lure webhook library. A .lure file is 89 + a Markdown file with YAML frontmatter. The filename without the .lure extension 90 + determines the webhook path relative to the configured base path: `push.lure` 91 + handles `<basePath>/push`, and `github/push.lure` handles 92 + `<basePath>/github/push`. 93 + 94 + ## Frontmatter 95 + 96 + ### `verify` (optional) 97 + 98 + Specifies how to authenticate incoming webhook requests. Omit if the provider 99 + does not sign requests. Only one strategy may be specified. 100 + 101 + HMAC: 102 + 103 + ```yaml 104 + verify: 105 + hmac: 106 + location: header # or "query" 107 + name: X-Hub-Signature-256 # header or query parameter name 108 + secret: $ENV_VAR_NAME # must be an environment variable reference 109 + ``` 110 + 111 + ### `payload` (optional) 112 + 113 + ```yaml 114 + payload: 115 + contentType: json # currently the only supported value 116 + ``` 117 + 118 + ### `config` (optional) 119 + 120 + An arbitrary object passed as-is to the application callback. Use this for any 121 + application-specific values you want to associate with this lure. 122 + 123 + ```yaml 124 + config: 125 + key: value 126 + ``` 127 + 128 + ## Template body 129 + 130 + Below the frontmatter is an eta template (https://eta.js.org). Write it as a 131 + natural language prompt for the LLM that will process the webhook. The 132 + following are available on `it`: 133 + 134 + - `it.payload` — the request body (parsed JSON for `contentType: json`) 135 + - `it.headers` — request headers as a Headers object (`it.headers.get("X-Foo")`) 136 + - `it.query` — query string as a URLSearchParams object (`it.query.get("foo")`) 137 + 138 + Use `<%= expression %>` to interpolate values into the prompt. 139 + 140 + ## Task 141 + 142 + Generate a .lure file for the following webhook: 143 + 144 + [DESCRIBE THE WEBHOOK SOURCE, EVENT TYPE, PAYLOAD SHAPE, VERIFICATION METHOD, 145 + AND WHAT THE LLM RECEIVING THE PROMPT SHOULD DO IN RESPONSE] 146 + ```` 147 + 80 148 ## Lifecycle 81 149 82 150 ### At Startup