@better-webhook/cli 0.3.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,287 +5,594 @@
5
5
  [![License](https://img.shields.io/github/license/endalk200/better-webhook?style=for-the-badge)](https://opensource.org/licenses/MIT)
6
6
  [![Node.js](https://img.shields.io/node/v/@better-webhook/cli?style=for-the-badge&logo=node.js)](https://nodejs.org/)
7
7
 
8
- A powerful CLI tool for webhook development, testing, and management. Capture incoming webhooks, replay them, generate reusable templates, and manage webhook definitions locally.
8
+ A modern CLI tool for webhook development, testing, and debugging. Capture incoming webhooks, replay them against your local server, manage reusable templates, and generate provider-specific signatures automatically.
9
9
 
10
10
  ## Features
11
11
 
12
- **Webhook Management** - Store and execute webhook definitions locally
13
- 🎣 **Live Capture** - Capture incoming webhooks with a local server
14
- 🔄 **Replay** - Replay captured webhooks to any endpoint
15
- 📋 **Templates** - Generate reusable templates from captured requests
16
- 📥 **Download** - Access curated webhook templates from the community
17
- 🎯 **Override** - Override URLs, methods, and headers on the fly
12
+ - 🎣 **Capture** Start a local server to capture incoming webhooks from any provider
13
+ - 🔄 **Replay** Replay captured webhooks to any endpoint with full header preservation
14
+ - 📋 **Templates** Download and run curated webhook templates from the community
15
+ - 🔐 **Signatures** Automatic signature generation for Stripe, GitHub, Shopify, Slack, and more
16
+ - 🌐 **WebSocket** — Real-time capture notifications via WebSocket for dashboard integration
17
+ - 🎯 **Provider Detection** Automatically identifies webhook providers from headers
18
+
19
+ ## Supported Providers
20
+
21
+ | Provider | Signature Algorithm | Auto-Detection |
22
+ | ------------ | ------------------------------- | -------------- |
23
+ | Stripe | HMAC-SHA256 (`t={ts},v1={sig}`) | ✅ |
24
+ | GitHub | HMAC-SHA256 (`sha256={sig}`) | ✅ |
25
+ | Shopify | HMAC-SHA256 (Base64) | ✅ |
26
+ | Slack | HMAC-SHA256 (`v0={sig}`) | ✅ |
27
+ | Twilio | HMAC-SHA1 (Base64) | ✅ |
28
+ | SendGrid | HMAC-SHA256 (Base64) | ✅ |
29
+ | Linear | HMAC-SHA256 (Hex) | ✅ |
30
+ | Clerk (Svix) | HMAC-SHA256 (`v1,{sig}`) | ✅ |
31
+ | Discord | Ed25519 | ✅ |
32
+ | Custom | — | — |
18
33
 
19
34
  ## Installation
20
35
 
21
- ### NPM/YARN/PNPM
22
-
23
36
  ```bash
24
- # Install globally
37
+ # NPM
25
38
  npm install -g @better-webhook/cli
26
- # or use with npx
27
- npx @better-webhook/cli --help
28
39
 
29
- # With yarn
40
+ # Yarn
30
41
  yarn global add @better-webhook/cli
31
42
 
32
- # With pnpm
43
+ # PNPM
33
44
  pnpm add -g @better-webhook/cli
45
+
46
+ # Or use with npx (no installation required)
47
+ npx @better-webhook/cli --help
34
48
  ```
35
49
 
36
50
  ### Verify Installation
37
51
 
38
52
  ```bash
39
- better-webhook --help
53
+ better-webhook --version
54
+ # 2.0.0
40
55
  ```
41
56
 
42
57
  ## Quick Start
43
58
 
44
- ### 1. Manage Webhook Definitions
59
+ ### 1. Capture Webhooks
45
60
 
46
- ```bash
47
- # List available webhook definitions
48
- better-webhook webhooks list
61
+ Start a local server to capture incoming webhooks:
49
62
 
50
- # Download community templates
51
- better-webhook webhooks download stripe-invoice.payment_succeeded
52
- better-webhook webhooks download --all
63
+ ```bash
64
+ # Start capture server on default port 3001
65
+ better-webhook capture
53
66
 
54
- # Run a webhook
55
- better-webhook webhooks run stripe-invoice
56
- better-webhook webhooks run mywebhook --url https://example.com/hook --method POST
67
+ # Use a custom port
68
+ better-webhook capture --port 4000
57
69
  ```
58
70
 
59
- ### 2. Capture Live Webhooks
71
+ Point your webhook provider (Stripe, GitHub, etc.) to `http://localhost:3001` or use a tunneling service like ngrok.
60
72
 
61
- ```bash
62
- # Start capture server (default port 3001)
63
- better-webhook capture
64
- better-webhook capture --port 3000
73
+ ### 2. View & Manage Captures
65
74
 
75
+ ```bash
66
76
  # List captured webhooks
67
- better-webhook capture list
68
- better-webhook capture list --limit 20
77
+ better-webhook captures list
69
78
 
70
- # Generate template from capture
71
- better-webhook capture template abc123 my-template-name
79
+ # Show detailed information about a capture
80
+ better-webhook captures show abc123
81
+
82
+ # Search captures
83
+ better-webhook captures search "github"
84
+
85
+ # Delete a capture
86
+ better-webhook captures delete abc123
72
87
  ```
73
88
 
74
89
  ### 3. Replay Webhooks
75
90
 
91
+ Replay a captured webhook to your local development server:
92
+
76
93
  ```bash
77
- # Replay captured webhook to any endpoint
78
- better-webhook replay abc123 https://example.com/webhook
79
- better-webhook replay abc123 https://test.com/hook --method PUT
94
+ # Interactive mode (select capture and enter URL)
95
+ better-webhook replay
96
+
97
+ # Direct replay
98
+ better-webhook replay abc123 http://localhost:3000/api/webhooks/github
80
99
  ```
81
100
 
82
- ## Commands
101
+ ### 4. Use Templates
102
+
103
+ Download and run curated webhook templates:
104
+
105
+ ```bash
106
+ # List available templates
107
+ better-webhook templates list
83
108
 
84
- ### `better-webhook webhooks`
109
+ # Download a template
110
+ better-webhook templates download github-push
85
111
 
86
- Manage and execute webhook definitions stored in `.webhooks/` directory.
112
+ # Run a template against your endpoint
113
+ better-webhook run github-push --url http://localhost:3000/webhooks/github
114
+ ```
115
+
116
+ ---
87
117
 
88
- | Command | Description | Options |
89
- | -------------------------- | ---------------------------------- | ------------------- |
90
- | `webhooks list` | List available webhook definitions | - |
91
- | `webhooks run <name>` | Execute a webhook definition | `--url`, `--method` |
92
- | `webhooks download [name]` | Download community templates | `--all`, `--force` |
118
+ ## Commands Reference
93
119
 
94
120
  ### `better-webhook capture`
95
121
 
96
- Capture, list, and generate templates from live webhook requests.
122
+ Start a server to capture incoming webhooks. All captured webhooks are saved to `~/.better-webhook/captures/`.
97
123
 
98
- | Command | Description | Options |
99
- | ------------------------------ | ------------------------------ | ----------------------- |
100
- | `capture` | Start webhook capture server | `--port` |
101
- | `capture list` | List captured webhook requests | `--limit` |
102
- | `capture template <id> [name]` | Generate template from capture | `--url`, `--output-dir` |
124
+ ```bash
125
+ better-webhook capture [options]
126
+ ```
103
127
 
104
- ### `better-webhook replay`
128
+ | Option | Description | Default |
129
+ | ------------------- | ----------------- | --------- |
130
+ | `-p, --port <port>` | Port to listen on | `3001` |
131
+ | `-h, --host <host>` | Host to bind to | `0.0.0.0` |
105
132
 
106
- Replay captured webhooks to any endpoint.
133
+ **Features:**
107
134
 
108
- | Command | Description | Options |
109
- | -------------------------------- | ----------------------- | ---------------------- |
110
- | `replay <captureId> <targetUrl>` | Replay captured webhook | `--method`, `--header` |
135
+ - Automatically detects webhook provider from headers
136
+ - Saves full request including headers, body, query params
137
+ - WebSocket server for real-time notifications
138
+ - Returns capture ID in response for easy reference
111
139
 
112
- ## Webhook Definition Format
140
+ **Example:**
113
141
 
114
- Webhook definitions are JSON files that follow this schema:
142
+ ```bash
143
+ better-webhook capture --port 4000 --host localhost
144
+ ```
115
145
 
116
- ```json
117
- {
118
- "url": "https://api.example.com/webhook",
119
- "method": "POST",
120
- "headers": [
121
- { "key": "Authorization", "value": "Bearer token123" },
122
- { "key": "Content-Type", "value": "application/json" }
123
- ],
124
- "body": {
125
- "event": "user.created",
126
- "data": {
127
- "id": "12345",
128
- "email": "user@example.com"
129
- }
130
- }
131
- }
146
+ ---
147
+
148
+ ### `better-webhook captures` (alias: `c`)
149
+
150
+ Manage captured webhooks.
151
+
152
+ #### `captures list` (alias: `ls`)
153
+
154
+ List captured webhooks, sorted by most recent first.
155
+
156
+ ```bash
157
+ better-webhook captures list [options]
132
158
  ```
133
159
 
134
- ### Schema Fields
160
+ | Option | Description | Default |
161
+ | --------------------------- | ----------------------------------------- | ------- |
162
+ | `-l, --limit <limit>` | Maximum captures to show | `20` |
163
+ | `-p, --provider <provider>` | Filter by provider (stripe, github, etc.) | — |
135
164
 
136
- | Field | Type | Required | Description |
137
- | --------- | ------ | -------- | --------------------------- |
138
- | `url` | string | ✅ | Target webhook URL |
139
- | `method` | string | ❌ | HTTP method (default: POST) |
140
- | `headers` | array | ❌ | Array of header objects |
141
- | `body` | any | ❌ | Request payload |
165
+ #### `captures show <captureId>`
142
166
 
143
- ## Directory Structure
167
+ Show detailed information about a specific capture.
144
168
 
169
+ ```bash
170
+ better-webhook captures show <captureId> [options]
145
171
  ```
146
- your-project/
147
- ├── .webhooks/ # Webhook definitions
148
- │ ├── stripe-payment.json
149
- │ ├── user-signup.json
150
- │ └── order-complete.json
151
- └── .webhook-captures/ # Captured requests (auto-created)
152
- ├── 2024-01-15T10-30-00_abc123.json
153
- └── 2024-01-15T11-00-00_def456.json
172
+
173
+ | Option | Description |
174
+ | ------------ | ---------------------- |
175
+ | `-b, --body` | Show full body content |
176
+
177
+ **Arguments:**
178
+
179
+ - `<captureId>` — Full or partial capture ID
180
+
181
+ #### `captures search <query>`
182
+
183
+ Search captures by ID, path, method, provider, or filename.
184
+
185
+ ```bash
186
+ better-webhook captures search <query>
154
187
  ```
155
188
 
156
- ## Use Cases
189
+ #### `captures delete` (alias: `rm`)
157
190
 
158
- ### Development & Testing
191
+ Delete a specific captured webhook.
159
192
 
160
193
  ```bash
161
- # Test your webhook endpoint during development
162
- better-webhook webhooks run test-payload --url http://localhost:3000/webhook
194
+ better-webhook captures delete <captureId> [options]
195
+ ```
163
196
 
164
- # Capture webhooks from external services
165
- better-webhook capture --port 4000
166
- # Point your webhook provider to http://localhost:4000
197
+ | Option | Description |
198
+ | ------------- | ------------------------ |
199
+ | `-f, --force` | Skip confirmation prompt |
200
+
201
+ #### `captures clean` (alias: `remove-all`)
202
+
203
+ Remove all captured webhooks.
204
+
205
+ ```bash
206
+ better-webhook captures clean [options]
207
+ ```
208
+
209
+ | Option | Description |
210
+ | ------------- | ------------------------ |
211
+ | `-f, --force` | Skip confirmation prompt |
212
+
213
+ ---
167
214
 
168
- # Replay captured requests for debugging
169
- better-webhook replay abc123 http://localhost:3000/debug
215
+ ### `better-webhook templates` (alias: `t`)
216
+
217
+ Manage webhook templates. Templates are fetched from the [better-webhook repository](https://github.com/endalk200/better-webhook/tree/main/templates).
218
+
219
+ #### `templates list` (alias: `ls`)
220
+
221
+ List available remote templates from the repository.
222
+
223
+ ```bash
224
+ better-webhook templates list [options]
170
225
  ```
171
226
 
172
- ### CI/CD & Automation
227
+ | Option | Description |
228
+ | --------------------------- | -------------------------------------- |
229
+ | `-p, --provider <provider>` | Filter by provider |
230
+ | `-r, --refresh` | Force refresh the template index cache |
231
+
232
+ #### `templates download` (alias: `get`)
233
+
234
+ Download a template to local storage (`~/.better-webhook/templates/`).
173
235
 
174
236
  ```bash
175
- # Test webhook endpoints in your pipeline
176
- better-webhook webhooks run deployment-success --url $PROD_WEBHOOK_URL
237
+ better-webhook templates download [templateId] [options]
238
+ ```
239
+
240
+ | Option | Description |
241
+ | ----------- | -------------------------------- |
242
+ | `-a, --all` | Download all available templates |
243
+
244
+ If no `templateId` is provided, shows an interactive selection menu.
245
+
246
+ #### `templates local`
247
+
248
+ List downloaded local templates.
177
249
 
178
- # Capture and replay for integration testing
179
- better-webhook capture --port 8080 &
180
- run_integration_tests
181
- better-webhook capture list
182
- better-webhook replay latest-capture $TEST_ENDPOINT
250
+ ```bash
251
+ better-webhook templates local [options]
252
+ ```
253
+
254
+ | Option | Description |
255
+ | --------------------------- | ------------------ |
256
+ | `-p, --provider <provider>` | Filter by provider |
257
+
258
+ #### `templates search <query>`
259
+
260
+ Search templates by name, provider, or event type.
261
+
262
+ ```bash
263
+ better-webhook templates search <query>
183
264
  ```
184
265
 
185
- ### API Integration
266
+ #### `templates cache`
267
+
268
+ Manage the template index cache.
269
+
270
+ ```bash
271
+ better-webhook templates cache [options]
272
+ ```
273
+
274
+ | Option | Description |
275
+ | ------------- | ------------------------ |
276
+ | `-c, --clear` | Clear the template cache |
277
+
278
+ #### `templates clean` (alias: `remove-all`)
279
+
280
+ Remove all downloaded templates.
186
281
 
187
282
  ```bash
188
- # Download and customize templates for popular services
189
- better-webhook webhooks download stripe-invoice.payment_succeeded
190
- better-webhook webhooks run stripe-invoice --url https://myapp.com/stripe
283
+ better-webhook templates clean [options]
284
+ ```
285
+
286
+ | Option | Description |
287
+ | ------------- | ------------------------ |
288
+ | `-f, --force` | Skip confirmation prompt |
289
+
290
+ ---
291
+
292
+ ### `better-webhook run`
293
+
294
+ Run a webhook template against a target URL. Automatically generates provider-specific signatures when a secret is provided.
191
295
 
192
- # Generate templates from real webhook data
193
- better-webhook capture template abc123 stripe-custom-template
296
+ ```bash
297
+ better-webhook run [templateId] [options]
194
298
  ```
195
299
 
196
- ## Examples
300
+ | Option | Description | Required |
301
+ | ----------------------- | ------------------------------------------ | -------- |
302
+ | `-u, --url <url>` | Target URL to send the webhook to | ✅ |
303
+ | `-s, --secret <secret>` | Secret for signature generation | — |
304
+ | `-H, --header <header>` | Add custom header (format: `key:value`) | — |
305
+ | `-v, --verbose` | Show detailed request/response information | — |
306
+
307
+ **Arguments:**
308
+
309
+ - `[templateId]` — Template ID to run (interactive selection if omitted)
197
310
 
198
- ### Stripe Payment Webhook
311
+ **Signature Generation:**
312
+
313
+ When you provide a secret (`--secret`), the CLI automatically generates the correct signature header based on the template's provider. You can also use environment variables (see [Environment Variables](#environment-variables)).
314
+
315
+ **Example:**
316
+
317
+ ```bash
318
+ # Run with inline secret
319
+ better-webhook run github-push \
320
+ --url http://localhost:3000/api/webhooks/github \
321
+ --secret "your-webhook-secret"
322
+
323
+ # Run with custom headers
324
+ better-webhook run github-push \
325
+ --url http://localhost:3000/api/webhooks/github \
326
+ --secret "$GITHUB_WEBHOOK_SECRET" \
327
+ --header "X-Custom-Header:value" \
328
+ --verbose
329
+ ```
330
+
331
+ ---
332
+
333
+ ### `better-webhook replay`
334
+
335
+ Replay a captured webhook to a target URL. Preserves original headers (except connection-related ones) and allows overrides.
336
+
337
+ ```bash
338
+ better-webhook replay [captureId] [targetUrl] [options]
339
+ ```
340
+
341
+ | Option | Description |
342
+ | ----------------------- | -------------------------------------------- |
343
+ | `-m, --method <method>` | Override HTTP method |
344
+ | `-H, --header <header>` | Add or override header (format: `key:value`) |
345
+ | `-v, --verbose` | Show detailed request/response information |
346
+
347
+ **Arguments:**
348
+
349
+ - `[captureId]` — Capture ID to replay (interactive selection if omitted)
350
+ - `[targetUrl]` — Target URL (prompts if omitted, defaults to original path on localhost:3000)
351
+
352
+ **Example:**
353
+
354
+ ```bash
355
+ # Interactive mode
356
+ better-webhook replay
357
+
358
+ # Direct replay with options
359
+ better-webhook replay abc123 http://localhost:3000/webhooks \
360
+ --method POST \
361
+ --header "X-Debug:true" \
362
+ --verbose
363
+ ```
364
+
365
+ ---
366
+
367
+ ## Environment Variables
368
+
369
+ The CLI automatically reads webhook secrets from environment variables based on the provider:
370
+
371
+ | Provider | Environment Variable |
372
+ | -------- | ------------------------- |
373
+ | Stripe | `STRIPE_WEBHOOK_SECRET` |
374
+ | GitHub | `GITHUB_WEBHOOK_SECRET` |
375
+ | Shopify | `SHOPIFY_WEBHOOK_SECRET` |
376
+ | Twilio | `TWILIO_WEBHOOK_SECRET` |
377
+ | Slack | `SLACK_WEBHOOK_SECRET` |
378
+ | Linear | `LINEAR_WEBHOOK_SECRET` |
379
+ | Clerk | `CLERK_WEBHOOK_SECRET` |
380
+ | SendGrid | `SENDGRID_WEBHOOK_SECRET` |
381
+ | Discord | `DISCORD_WEBHOOK_SECRET` |
382
+ | Custom | `WEBHOOK_SECRET` |
383
+
384
+ **Usage:**
385
+
386
+ ```bash
387
+ export GITHUB_WEBHOOK_SECRET="your-secret-here"
388
+ better-webhook run github-push --url http://localhost:3000/webhooks/github
389
+ # Secret is automatically used for signature generation
390
+ ```
391
+
392
+ ---
393
+
394
+ ## Storage Locations
395
+
396
+ All CLI data is stored in `~/.better-webhook/`:
397
+
398
+ ```
399
+ ~/.better-webhook/
400
+ ├── captures/ # Captured webhook requests
401
+ │ ├── 2024-01-15_10-30-00_abc12345.json
402
+ │ └── 2024-01-15_11-00-00_def67890.json
403
+ ├── templates/ # Downloaded templates
404
+ │ ├── github/
405
+ │ │ ├── github-push.json
406
+ │ │ └── github-pull_request.json
407
+ │ └── stripe/
408
+ │ └── stripe-invoice.json
409
+ └── templates-cache.json # Template index cache (1 hour TTL)
410
+ ```
411
+
412
+ ---
413
+
414
+ ## Webhook Template Format
415
+
416
+ Templates follow this JSON schema:
199
417
 
200
418
  ```json
201
419
  {
202
- "url": "https://api.myapp.com/webhooks/stripe",
420
+ "url": "https://api.example.com/webhook",
203
421
  "method": "POST",
204
422
  "headers": [
205
- { "key": "Stripe-Signature", "value": "t=1234567890,v1=signature" }
423
+ { "key": "Content-Type", "value": "application/json" },
424
+ { "key": "X-Custom-Header", "value": "custom-value" }
206
425
  ],
207
426
  "body": {
208
- "id": "evt_1234567890",
209
- "object": "event",
210
- "type": "payment_intent.succeeded",
427
+ "event": "user.created",
211
428
  "data": {
212
- "object": {
213
- "id": "pi_1234567890",
214
- "amount": 2000,
215
- "currency": "usd",
216
- "status": "succeeded"
217
- }
429
+ "id": "12345",
430
+ "email": "user@example.com"
218
431
  }
219
- }
432
+ },
433
+ "provider": "custom",
434
+ "event": "user.created",
435
+ "description": "Triggered when a new user is created"
220
436
  }
221
437
  ```
222
438
 
223
- ### GitHub Webhook
439
+ | Field | Type | Required | Description |
440
+ | ------------- | ------ | -------- | --------------------------------------------------- |
441
+ | `url` | string | — | Default target URL (can be overridden with `--url`) |
442
+ | `method` | string | — | HTTP method (default: `POST`) |
443
+ | `headers` | array | — | Array of `{ key, value }` header objects |
444
+ | `body` | any | — | Request payload (object or string) |
445
+ | `provider` | string | — | Provider name for signature generation |
446
+ | `event` | string | — | Event type identifier |
447
+ | `description` | string | — | Human-readable description |
448
+
449
+ ---
450
+
451
+ ## Captured Webhook Format
452
+
453
+ Captured webhooks are stored with full request details:
224
454
 
225
455
  ```json
226
456
  {
227
- "url": "https://api.myapp.com/webhooks/github",
457
+ "id": "550e8400-e29b-41d4-a716-446655440000",
458
+ "timestamp": "2024-01-15T10:30:00.000Z",
228
459
  "method": "POST",
229
- "headers": [
230
- { "key": "X-GitHub-Event", "value": "push" },
231
- { "key": "X-Hub-Signature-256", "value": "sha256=signature" }
232
- ],
233
- "body": {
234
- "ref": "refs/heads/main",
235
- "commits": [
236
- {
237
- "id": "abc123",
238
- "message": "Update README",
239
- "author": {
240
- "name": "Developer",
241
- "email": "dev@example.com"
242
- }
243
- }
244
- ]
245
- }
460
+ "url": "/webhooks/github?action=opened",
461
+ "path": "/webhooks/github",
462
+ "headers": {
463
+ "content-type": "application/json",
464
+ "x-github-event": "push",
465
+ "x-hub-signature-256": "sha256=..."
466
+ },
467
+ "body": { "...parsed JSON..." },
468
+ "rawBody": "{...original string...}",
469
+ "query": { "action": "opened" },
470
+ "provider": "github",
471
+ "contentType": "application/json",
472
+ "contentLength": 1234
246
473
  }
247
474
  ```
248
475
 
249
- ## Error Handling
476
+ ---
250
477
 
251
- The CLI provides detailed error messages and uses appropriate exit codes:
478
+ ## Use Cases
479
+
480
+ ### Local Development
252
481
 
253
- - **0**: Success
254
- - **1**: General error (network, validation, file not found)
482
+ Test your webhook endpoints during development:
255
483
 
256
484
  ```bash
257
- # Validation errors show detailed field information
258
- better-webhook webhooks run invalid-webhook
259
- # Error: Webhook validation failed:
260
- # - url: Required field missing
261
- # - method: Invalid HTTP method "INVALID"
485
+ # Terminal 1: Start your app
486
+ npm run dev
487
+
488
+ # Terminal 2: Capture webhooks
489
+ better-webhook capture --port 4000
262
490
 
263
- # Network errors are clearly reported
264
- better-webhook webhooks run test --url https://invalid-domain.nonexistent
265
- # Error: Request failed: getaddrinfo ENOTFOUND invalid-domain.nonexistent
491
+ # Configure your webhook provider to send to http://localhost:4000
492
+ # (use ngrok for external providers: ngrok http 4000)
493
+
494
+ # Terminal 3: Replay captured webhooks to your app
495
+ better-webhook replay abc123 http://localhost:3000/api/webhooks
266
496
  ```
267
497
 
268
- ## Configuration
498
+ ### Debugging Webhook Issues
269
499
 
270
- ### Environment Variables
500
+ ```bash
501
+ # Capture the problematic webhook
502
+ better-webhook capture
271
503
 
272
- | Variable | Description | Default |
273
- | -------------- | --------------------------------- | ------------------- |
274
- | `WEBHOOKS_DIR` | Directory for webhook definitions | `.webhooks` |
275
- | `CAPTURES_DIR` | Directory for captured webhooks | `.webhook-captures` |
504
+ # Inspect the full request
505
+ better-webhook captures show abc123 --body
276
506
 
277
- ### Global Options
507
+ # Replay to your local server with verbose output
508
+ better-webhook replay abc123 http://localhost:3000/webhooks --verbose
509
+ ```
278
510
 
279
- | Flag | Description |
280
- | ----------- | ------------------------ |
281
- | `--help` | Show help information |
282
- | `--version` | Show version information |
511
+ ### Testing Signature Verification
283
512
 
284
- ## Contributing
513
+ ```bash
514
+ # Run a template with your production secret
515
+ better-webhook run stripe-invoice.payment_succeeded \
516
+ --url http://localhost:3000/api/webhooks/stripe \
517
+ --secret "whsec_your_stripe_secret" \
518
+ --verbose
519
+ ```
285
520
 
286
- We welcome contributions! Please see our [Contributing Guide](https://github.com/endalk200/better-webhook/blob/main/CONTRIBUTING.md) for details.
521
+ ### CI/CD Integration
522
+
523
+ ```bash
524
+ # Test webhook endpoints in your pipeline
525
+ better-webhook templates download github-push
526
+ better-webhook run github-push \
527
+ --url "$TEST_ENDPOINT" \
528
+ --secret "$GITHUB_WEBHOOK_SECRET"
529
+
530
+ # Check exit code
531
+ if [ $? -eq 0 ]; then
532
+ echo "Webhook test passed"
533
+ fi
534
+ ```
535
+
536
+ ---
537
+
538
+ ## WebSocket API
539
+
540
+ The capture server exposes a WebSocket endpoint on the same port for real-time notifications:
541
+
542
+ ```javascript
543
+ const ws = new WebSocket("ws://localhost:3001");
544
+
545
+ ws.onmessage = (event) => {
546
+ const message = JSON.parse(event.data);
547
+
548
+ switch (message.type) {
549
+ case "capture":
550
+ console.log("New capture:", message.payload.capture);
551
+ break;
552
+ case "captures_updated":
553
+ console.log("Captures list:", message.payload.captures);
554
+ break;
555
+ }
556
+ };
557
+ ```
558
+
559
+ **Message Types:**
287
560
 
288
- ### Development Setup
561
+ | Type | Description | Payload |
562
+ | ------------------ | --------------------------- | --------------------- |
563
+ | `capture` | New webhook captured | `{ file, capture }` |
564
+ | `captures_updated` | Initial state on connection | `{ captures, count }` |
565
+
566
+ ---
567
+
568
+ ## Error Handling
569
+
570
+ The CLI uses standard exit codes:
571
+
572
+ | Code | Description |
573
+ | ---- | ------------------------------------------------- |
574
+ | `0` | Success |
575
+ | `1` | Error (validation, network, file not found, etc.) |
576
+
577
+ Detailed error messages are displayed in the terminal:
578
+
579
+ ```bash
580
+ better-webhook run nonexistent-template --url http://localhost:3000
581
+ # ❌ Template not found: nonexistent-template
582
+ # Download it with: better-webhook templates download nonexistent-template
583
+
584
+ better-webhook capture --port 99999
585
+ # Invalid port number
586
+
587
+ better-webhook replay abc123 invalid-url
588
+ # Please enter a valid URL
589
+ ```
590
+
591
+ ---
592
+
593
+ ## Development
594
+
595
+ ### Building from Source
289
596
 
290
597
  ```bash
291
598
  git clone https://github.com/endalk200/better-webhook.git
@@ -294,15 +601,22 @@ pnpm install
294
601
  pnpm --filter @better-webhook/cli build
295
602
  ```
296
603
 
297
- ### Running Tests
604
+ ### Running Locally
298
605
 
299
606
  ```bash
300
- pnpm --filter @better-webhook/cli test
607
+ cd apps/webhook-cli
608
+ pnpm start -- capture --port 3001
301
609
  ```
302
610
 
611
+ ---
612
+
613
+ ## Contributing
614
+
615
+ We welcome contributions! Please see our [Contributing Guide](https://github.com/endalk200/better-webhook/blob/main/CONTRIBUTING.md) for details.
616
+
303
617
  ## Changelog
304
618
 
305
- See [CHANGELOG.md](https://github.com/endalk200/better-webhook/blob/main/apps/webhook-cli/CHANGELOG.md) for version history.
619
+ See [CHANGELOG.md](./CHANGELOG.md) for version history.
306
620
 
307
621
  ## License
308
622
 
@@ -313,8 +627,3 @@ MIT © [Endalk](https://github.com/endalk200)
313
627
  - 🐛 [Report bugs](https://github.com/endalk200/better-webhook/issues)
314
628
  - 💡 [Request features](https://github.com/endalk200/better-webhook/issues)
315
629
  - 📖 [Documentation](https://github.com/endalk200/better-webhook#readme)
316
-
317
- ---
318
-
319
- Made with ❤️ by [Endalk](https://github.com/endalk200)
320
-