hookdeck-cli 1.0.4 → 1.2.0-beta.1

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.
Files changed (3) hide show
  1. package/README.md +674 -77
  2. package/bin/hookdeck +0 -0
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -14,7 +14,8 @@ Hookdeck for development is completely free, and we monetize the platform with o
14
14
 
15
15
  For a complete reference, see the [CLI reference](https://hookdeck.com/docs/cli?ref=github-hookdeck-cli).
16
16
 
17
- https://github.com/user-attachments/assets/5fca7842-9c41-411c-8cd6-2f32f84fa907
17
+ https://github.com/user-attachments/assets/7a333c5b-e4cb-45bb-8570-29fafd137bd2
18
+
18
19
 
19
20
  ## Installation
20
21
 
@@ -28,6 +29,12 @@ Hookdeck CLI is distributed as an NPM package:
28
29
  npm install hookdeck-cli -g
29
30
  ```
30
31
 
32
+ To install a beta (pre-release) version:
33
+
34
+ ```sh
35
+ npm install hookdeck-cli@beta -g
36
+ ```
37
+
31
38
  ### macOS
32
39
 
33
40
  Hookdeck CLI is available on macOS via [Homebrew](https://brew.sh/):
@@ -36,6 +43,12 @@ Hookdeck CLI is available on macOS via [Homebrew](https://brew.sh/):
36
43
  brew install hookdeck/hookdeck/hookdeck
37
44
  ```
38
45
 
46
+ To install a beta (pre-release) version:
47
+
48
+ ```sh
49
+ brew install hookdeck/hookdeck/hookdeck-beta
50
+ ```
51
+
39
52
  ### Windows
40
53
 
41
54
  Hookdeck CLI is available on Windows via the [Scoop](https://scoop.sh/) package manager:
@@ -45,6 +58,12 @@ scoop bucket add hookdeck https://github.com/hookdeck/scoop-hookdeck-cli.git
45
58
  scoop install hookdeck
46
59
  ```
47
60
 
61
+ To install a beta (pre-release) version:
62
+
63
+ ```sh
64
+ scoop install hookdeck-beta
65
+ ```
66
+
48
67
  ### Linux Or without package managers
49
68
 
50
69
  To install the Hookdeck CLI on Linux without a package manager:
@@ -53,6 +72,8 @@ To install the Hookdeck CLI on Linux without a package manager:
53
72
  2. Unzip the file: tar -xvf hookdeck_X.X.X_linux_amd64.tar.gz
54
73
  3. Run the executable: ./hookdeck
55
74
 
75
+ For beta (pre-release) versions, download the `.deb` or `.rpm` packages from the [GitHub releases page](https://github.com/hookdeck/hookdeck-cli/releases) (look for releases marked as "Pre-release").
76
+
56
77
  ### Docker
57
78
 
58
79
  The CLI is also available as a Docker image: [`hookdeck/hookdeck-cli`](https://hub.docker.com/r/hookdeck/hookdeck-cli).
@@ -62,6 +83,14 @@ docker run --rm -it hookdeck/hookdeck-cli version
62
83
  hookdeck version x.y.z (beta)
63
84
  ```
64
85
 
86
+ To use a specific version (including beta releases), specify the version tag:
87
+
88
+ ```sh
89
+ docker run --rm -it hookdeck/hookdeck-cli:v1.2.3-beta.1 version
90
+ ```
91
+
92
+ Note: Beta releases do not update the `latest` tag. Only stable releases update `latest`.
93
+
65
94
  If you want to login to your Hookdeck account with the CLI and persist
66
95
  credentials, you can bind mount the `~/.config/hookdeck` directory:
67
96
 
@@ -99,6 +128,7 @@ hookdeck login
99
128
  ```
100
129
 
101
130
  If you are in an environment without a browser (e.g., a TTY-only terminal), you can use the `--interactive` (or `-i`) flag to log in by pasting your API key:
131
+
102
132
  ```sh
103
133
  hookdeck login --interactive
104
134
  ```
@@ -110,17 +140,52 @@ hookdeck login --interactive
110
140
  Start a session to forward your events to an HTTP server.
111
141
 
112
142
  ```sh
113
- hookdeck listen <port-or-URL> <source-alias?> <connection-query?> [--path?]
143
+ hookdeck listen <port-or-URL> <source-alias?> <connection-query?> [flags]
144
+
145
+ Flags:
146
+ --path string Sets the path to which events are forwarded (e.g., /webhooks or /api/stripe)
147
+ --output string Output mode: interactive (full UI), compact (simple logs), quiet (only fatal errors) (default "interactive")
148
+ --max-connections int Maximum concurrent connections to local endpoint (default: 50, increase for high-volume testing)
149
+ --filter-body string Filter events by request body using Hookdeck filter syntax (JSON)
150
+ --filter-headers string Filter events by request headers using Hookdeck filter syntax (JSON)
151
+ --filter-query string Filter events by query parameters using Hookdeck filter syntax (JSON)
152
+ --filter-path string Filter events by request path using Hookdeck filter syntax (JSON)
114
153
  ```
115
154
 
116
155
  Hookdeck works by routing events received for a given `source` (i.e., Shopify, Github, etc.) to its defined `destination` by connecting them with a `connection` to a `destination`. The CLI allows you to receive events for any given connection and forward them to your localhost at the specified port or any valid URL.
117
156
 
118
157
  Each `source` is assigned an Event URL, which you can use to receive events. When starting with a fresh account, the CLI will prompt you to create your first source. Each CLI process can listen to one source at a time.
119
158
 
120
- Contrary to ngrok, **Hookdeck does not allow to append a path to your event URL**. Instead, the routing is done within Hookdeck configuration. This means you will also be prompted to specify your `destination` path, and you can have as many as you want per `source`.
121
-
122
159
  > The `port-or-URL` param is mandatory, events will be forwarded to http://localhost:$PORT/$DESTINATION_PATH when inputing a valid port or your provided URL.
123
160
 
161
+ #### Interactive Mode
162
+
163
+ The default interactive mode uses a full-screen TUI (Terminal User Interface) with an alternative screen buffer, meaning your terminal history is preserved when you exit. The interface includes:
164
+
165
+ - **Connection Header**: Shows your sources, webhook URLs, and connection routing
166
+ - Auto-collapses when the first event arrives to save space
167
+ - Toggle with `i` to expand/collapse connection details
168
+ - **Event List**: Scrollable history of all received events (up to 1000 events)
169
+ - Auto-scrolls to show latest events as they arrive
170
+ - Manual navigation pauses auto-scrolling
171
+ - **Status Bar**: Shows event details and available keyboard shortcuts
172
+ - **Event Details View**: Full request/response inspection with headers and body
173
+
174
+ #### Interactive Keyboard Shortcuts
175
+
176
+ While in interactive mode, you can use the following keyboard shortcuts:
177
+
178
+ - `↑` / `↓` or `k` / `j` - Navigate between events (select different events)
179
+ - `i` - Toggle connection information (expand/collapse connection details)
180
+ - `r` - Retry the selected event
181
+ - `o` - Open the selected event in the Hookdeck dashboard
182
+ - `d` - Show detailed request/response information for the selected event (press `d` or `ESC` to close)
183
+ - When details view is open: `↑` / `↓` scroll through content, `PgUp` / `PgDown` for page navigation
184
+ - `q` - Quit the application (terminal state is restored)
185
+ - `Ctrl+C` - Also quits the application
186
+
187
+ The selected event is indicated by a `>` character at the beginning of the line. All actions (retry, open, details) work on the currently selected event, not just the latest one. These shortcuts are displayed in the status bar at the bottom of the screen.
188
+
124
189
  #### Listen to all your connections for a given source
125
190
 
126
191
  The second param, `source-alias` is used to select a specific source to listen on. By default, the CLI will start listening on all eligible connections for that source.
@@ -128,18 +193,24 @@ The second param, `source-alias` is used to select a specific source to listen o
128
193
  ```sh
129
194
  $ hookdeck listen 3000 shopify
130
195
 
131
- 👉 Inspect and replay events: https://dashboard.hookdeck.com/cli/events
196
+ ●── HOOKDECK CLI ──●
197
+
198
+ Listening on 1 source • 2 connections • [i] Collapse
132
199
 
133
200
  Shopify Source
134
- 🔌 Event URL: https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHnOH
201
+ │ Requests to https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHnOH
202
+ ├─ Forwards to → http://localhost:3000/webhooks/shopify/inventory (Inventory Service)
203
+ └─ Forwards to → http://localhost:3000/webhooks/shopify/orders (Orders Service)
135
204
 
136
- Connections
137
- Inventory Service forwarding to /webhooks/shopify/inventory
138
- Orders Service forwarding to /webhooks/shopify/orders
205
+ 💡 Open dashboard to inspect, retry & bookmark events: https://dashboard.hookdeck.com/events/cli?team_id=...
139
206
 
207
+ Events • [↑↓] Navigate ──────────────────────────────────────────────────────────
140
208
 
141
- Getting ready...
209
+ 2025-10-12 14:32:15 [200] POST http://localhost:3000/webhooks/shopify/orders (23ms) → https://dashboard.hookdeck.com/events/evt_...
210
+ > 2025-10-12 14:32:18 [200] POST http://localhost:3000/webhooks/shopify/inventory (45ms) → https://dashboard.hookdeck.com/events/evt_...
142
211
 
212
+ ───────────────────────────────────────────────────────────────────────────────
213
+ > ✓ Last event succeeded with status 200 | [r] Retry • [o] Open in dashboard • [d] Show data
143
214
  ```
144
215
 
145
216
  #### Listen to multiple sources
@@ -149,20 +220,32 @@ Orders Service forwarding to /webhooks/shopify/orders
149
220
  ```sh
150
221
  $ hookdeck listen 3000 '*'
151
222
 
152
- 👉 Inspect and replay events: https://dashboard.hookdeck.com/cli/events
223
+ ●── HOOKDECK CLI ──●
224
+
225
+ Listening on 3 sources • 3 connections • [i] Collapse
226
+
227
+ stripe
228
+ │ Requests to → https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHn01
229
+ └─ Forwards to → http://localhost:3000/webhooks/stripe (cli-stripe)
153
230
 
154
- Sources
155
- 🔌 stripe URL: https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHn01
156
- 🔌 shopify URL: https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHn02
157
- 🔌 twilio URL: https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHn03
231
+ shopify
232
+ │ Requests to https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHn02
233
+ └─ Forwards to → http://localhost:3000/webhooks/shopify (cli-shopify)
158
234
 
159
- Connections
160
- stripe -> cli-stripe forwarding to /webhooks/stripe
161
- shopify -> cli-shopify forwarding to /webhooks/shopify
162
- twilio -> cli-twilio forwarding to /webhooks/twilio
235
+ twilio
236
+ │ Requests to https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHn03
237
+ └─ Forwards to http://localhost:3000/webhooks/twilio (cli-twilio)
163
238
 
164
- Getting ready...
239
+ 💡 Open dashboard to inspect, retry & bookmark events: https://dashboard.hookdeck.com/events/cli?team_id=...
165
240
 
241
+ Events • [↑↓] Navigate ──────────────────────────────────────────────────────────
242
+
243
+ 2025-10-12 14:35:21 [200] POST http://localhost:3000/webhooks/stripe (12ms) → https://dashboard.hookdeck.com/events/evt_...
244
+ 2025-10-12 14:35:44 [200] POST http://localhost:3000/webhooks/shopify (31ms) → https://dashboard.hookdeck.com/events/evt_...
245
+ > 2025-10-12 14:35:52 [200] POST http://localhost:3000/webhooks/twilio (18ms) → https://dashboard.hookdeck.com/events/evt_...
246
+
247
+ ───────────────────────────────────────────────────────────────────────────────
248
+ > ✓ Last event succeeded with status 200 | [r] Retry • [o] Open in dashboard • [d] Show data
166
249
  ```
167
250
 
168
251
  #### Listen to a subset of connections
@@ -172,17 +255,22 @@ The 3rd param, `connection-query` specifies which connection with a CLI destinat
172
255
  ```sh
173
256
  $ hookdeck listen 3000 shopify orders
174
257
 
175
- 👉 Inspect and replay events: https://dashboard.hookdeck.com/cli/events
258
+ ●── HOOKDECK CLI ──●
259
+
260
+ Listening on 1 source • 1 connection • [i] Collapse
176
261
 
177
262
  Shopify Source
178
- 🔌 Event URL: https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHnOH
263
+ │ Requests to https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHnOH
264
+ └─ Forwards to → http://localhost:3000/webhooks/shopify/orders (Orders Service)
179
265
 
180
- Connections
181
- Orders Service forwarding to /webhooks/shopify/orders
266
+ 💡 Open dashboard to inspect, retry & bookmark events: https://dashboard.hookdeck.com/events/cli?team_id=...
182
267
 
268
+ Events • [↑↓] Navigate ──────────────────────────────────────────────────────────
183
269
 
184
- Getting ready...
270
+ > 2025-10-12 14:38:09 [200] POST http://localhost:3000/webhooks/shopify/orders (27ms) → https://dashboard.hookdeck.com/events/evt_...
185
271
 
272
+ ───────────────────────────────────────────────────────────────────────────────
273
+ > ✓ Last event succeeded with status 200 | [r] Retry • [o] Open in dashboard • [d] Show data
186
274
  ```
187
275
 
188
276
  #### Changing the path events are forwarded to
@@ -192,19 +280,104 @@ The `--path` flag sets the path to which events are forwarded.
192
280
  ```sh
193
281
  $ hookdeck listen 3000 shopify orders --path /events/shopify/orders
194
282
 
195
- 👉 Inspect and replay events: https://dashboard.hookdeck.com/cli/events
283
+ ●── HOOKDECK CLI ──●
284
+
285
+ Listening on 1 source • 1 connection • [i] Collapse
196
286
 
197
287
  Shopify Source
198
- 🔌 Event URL: https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHnOH
288
+ │ Requests to https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHnOH
289
+ └─ Forwards to → http://localhost:3000/events/shopify/orders (Orders Service)
290
+
291
+ 💡 Open dashboard to inspect, retry & bookmark events: https://dashboard.hookdeck.com/events/cli?team_id=...
292
+
293
+ Events • [↑↓] Navigate ──────────────────────────────────────────────────────────
199
294
 
200
- Connections
201
- Orders Service forwarding to /events/shopify/orders
295
+ > 2025-10-12 14:40:23 [200] POST http://localhost:3000/events/shopify/orders (19ms) → https://dashboard.hookdeck.com/events/evt_...
202
296
 
297
+ ───────────────────────────────────────────────────────────────────────────────
298
+ > ✓ Last event succeeded with status 200 | [r] Retry • [o] Open in dashboard • [d] Show data
299
+ ```
300
+
301
+ #### Controlling output verbosity
302
+
303
+ The `--output` flag controls how events are displayed. This is useful for reducing resource usage in high-throughput scenarios or when running in the background.
304
+
305
+ **Available modes:**
306
+
307
+ - `interactive` (default) - Full-screen TUI with alternative screen buffer, event history, navigation, and keyboard shortcuts. Your terminal history is preserved and restored when you exit.
308
+ - `compact` - Simple one-line logs for all events without interactive features. Events are appended to your terminal history.
309
+ - `quiet` - Only displays fatal connection errors (network failures, timeouts), not HTTP errors
310
+
311
+ All modes display connection information at startup and a connection status message.
203
312
 
204
- ⣾ Getting ready...
313
+ **Examples:**
205
314
 
315
+ ```sh
316
+ # Default - full interactive UI with keyboard shortcuts
317
+ $ hookdeck listen 3000 shopify
318
+
319
+ # Simple logging mode - prints all events as one-line logs
320
+ $ hookdeck listen 3000 shopify --output compact
321
+
322
+ # Quiet mode - only shows fatal connection errors
323
+ $ hookdeck listen 3000 shopify --output quiet
206
324
  ```
207
325
 
326
+ **Compact mode output:**
327
+
328
+ ```
329
+ Listening on
330
+ shopify
331
+ └─ Forwards to → http://localhost:3000
332
+
333
+ Connected. Waiting for events...
334
+
335
+ 2025-10-08 15:56:53 [200] POST http://localhost:3000 (45ms) → https://...
336
+ 2025-10-08 15:56:54 [422] POST http://localhost:3000 (12ms) → https://...
337
+ ```
338
+
339
+ **Quiet mode output:**
340
+
341
+ ```
342
+ Listening on
343
+ shopify
344
+ └─ Forwards to → http://localhost:3000
345
+
346
+ Connected. Waiting for events...
347
+
348
+ 2025-10-08 15:56:53 [ERROR] Failed to POST: connection refused
349
+ ```
350
+
351
+ > Note: In `quiet` mode, only fatal errors are shown (connection failures, network unreachable, timeouts). HTTP error responses (4xx, 5xx) are not displayed as they are valid HTTP responses.
352
+
353
+ #### Filtering events
354
+
355
+ The CLI supports filtering events using Hookdeck's filter syntax. Filters allow you to receive only events that match specific conditions, reducing noise and focusing on the events you care about during development.
356
+
357
+ **Filter flags:**
358
+
359
+ - `--filter-body` - Filter events by request body content (JSON)
360
+ - `--filter-headers` - Filter events by request headers (JSON)
361
+ - `--filter-query` - Filter events by query parameters (JSON)
362
+ - `--filter-path` - Filter events by request path (JSON)
363
+
364
+ All filter flags accept JSON using [Hookdeck's filter syntax](https://hookdeck.com/docs/filters). You can use exact matches or operators like `$exist`, `$gte`, `$lte`, `$in`, etc.
365
+
366
+ **Examples:**
367
+
368
+ ```sh
369
+ # Filter events by body content (only events with matching data)
370
+ hookdeck listen 3000 github --filter-body '{"action": "opened"}'
371
+
372
+ # Filter events with multiple conditions
373
+ hookdeck listen 3000 stripe --filter-body '{"type": "charge.succeeded"}' --filter-headers '{"x-stripe-signature": {"$exist": true}}'
374
+
375
+ # Filter using operators
376
+ hookdeck listen 3000 api --filter-body '{"amount": {"$gte": 100}}'
377
+ ```
378
+
379
+ When filters are active, the CLI will display a warning message indicating which filters are applied. Only events matching all specified filter conditions will be forwarded to your local server.
380
+
208
381
  #### Viewing and interacting with your events
209
382
 
210
383
  Event logs for your CLI can be found at [https://dashboard.hookdeck.com/cli/events](https://dashboard.hookdeck.com/cli/events?ref=github-hookdeck-cli). Events can be replayed or saved at any time.
@@ -226,6 +399,7 @@ For local development scenarios, you can instruct the `listen` command to bypass
226
399
  **This is dangerous and should only be used in trusted local development environments for destinations you control.**
227
400
 
228
401
  Example of skipping SSL validation for an HTTPS destination:
402
+
229
403
  ```sh
230
404
  hookdeck listen --insecure https://<your-ssl-url-or-url:port>/ <source-alias?> <connection-query?>
231
405
  ```
@@ -256,17 +430,43 @@ Done! The Hookdeck CLI is configured in project MyProject
256
430
 
257
431
  $ hookdeck listen 3000 shopify orders
258
432
 
259
- 👉 Inspect and replay events: https://dashboard.hookdeck.com/cli/events
433
+ ●── HOOKDECK CLI ──●
434
+
435
+ Listening on 1 source • 1 connection • [i] Collapse
260
436
 
261
437
  Shopify Source
262
- 🔌 Event URL: https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHnOH
438
+ │ Requests to https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHnOH
439
+ └─ Forwards to → http://localhost:3000/webhooks/shopify/orders (Orders Service)
440
+
441
+ 💡 Open dashboard to inspect, retry & bookmark events: https://dashboard.hookdeck.com/events/cli?team_id=...
442
+
443
+ Events • [↑↓] Navigate ──────────────────────────────────────────────────────────
263
444
 
264
- Connections
265
- Inventory Service forwarding to /webhooks/shopify/inventory
445
+ > 2025-10-12 14:42:55 [200] POST http://localhost:3000/webhooks/shopify/orders (34ms) → https://dashboard.hookdeck.com/events/evt_...
266
446
 
447
+ ───────────────────────────────────────────────────────────────────────────────
448
+ > ✓ Last event succeeded with status 200 | [r] Retry • [o] Open in dashboard • [d] Show data
449
+ ```
450
+
451
+ ### Manage connections
267
452
 
268
- Getting ready...
453
+ Create and manage webhook connections between sources and destinations with inline resource creation, authentication, processing rules, and lifecycle management. For detailed examples with authentication, filters, retry rules, and rate limiting, see the complete [connection management](#manage-connections) section below.
269
454
 
455
+ ```sh
456
+ hookdeck connection [command]
457
+
458
+ # Available commands
459
+ hookdeck connection list # List all connections
460
+ hookdeck connection get # Get connection details
461
+ hookdeck connection create # Create a new connection
462
+ hookdeck connection upsert # Create or update a connection (idempotent)
463
+ hookdeck connection delete # Delete a connection
464
+ hookdeck connection enable # Enable a connection
465
+ hookdeck connection disable # Disable a connection
466
+ hookdeck connection pause # Pause a connection
467
+ hookdeck connection unpause # Unpause a connection
468
+ hookdeck connection archive # Archive a connection
469
+ hookdeck connection unarchive # Unarchive a connection
270
470
  ```
271
471
 
272
472
  ### Manage active project
@@ -296,42 +496,303 @@ hookdeck project use [<organization_name> [<project_name>]]
296
496
 
297
497
  **Behavior:**
298
498
 
299
- - **`hookdeck project use`** (no arguments):
300
- An interactive prompt will guide you through selecting your organization and then the project within that organization.
301
- ```sh
302
- $ hookdeck project use
303
- Use the arrow keys to navigate: ↓ ↑ → ←
304
- ? Select Organization:
305
- My Org
306
- Another Org
307
- ...
308
- ? Select Project (Another Org):
309
- Project X
310
- Project Y
311
- Selecting project Project Y
312
- Successfully set active project to: [Another Org] Project Y
313
- ```
314
-
315
- - **`hookdeck project use <organization_name>`** (one argument):
316
- Filters projects by the specified `<organization_name>`.
317
- - If multiple projects exist under that organization, you'll be prompted to choose one.
318
- - If only one project exists, it will be selected automatically.
319
- ```sh
320
- $ hookdeck project use "My Org"
321
- # (If multiple projects, prompts to select. If one, auto-selects)
322
- Successfully set active project to: [My Org] Default Project
323
- ```
324
-
325
- - **`hookdeck project use <organization_name> <project_name>`** (two arguments):
326
- Directly selects the project `<project_name>` under the organization `<organization_name>`.
327
- ```sh
328
- $ hookdeck project use "My Corp" "API Staging"
329
- Successfully set active project to: [My Corp] API Staging
330
- ```
499
+ - **`hookdeck project use`** (no arguments):
500
+ An interactive prompt will guide you through selecting your organization and then the project within that organization.
501
+
502
+ ```sh
503
+ $ hookdeck project use
504
+ Use the arrow keys to navigate: ↓ ↑ → ←
505
+ ? Select Organization:
506
+ My Org
507
+ ▸ Another Org
508
+ ...
509
+ ? Select Project (Another Org):
510
+ Project X
511
+ Project Y
512
+ Selecting project Project Y
513
+ Successfully set active project to: [Another Org] Project Y
514
+ ```
515
+
516
+ - **`hookdeck project use <organization_name>`** (one argument):
517
+ Filters projects by the specified `<organization_name>`.
518
+
519
+ - If multiple projects exist under that organization, you'll be prompted to choose one.
520
+ - If only one project exists, it will be selected automatically.
521
+
522
+ ```sh
523
+ $ hookdeck project use "My Org"
524
+ # (If multiple projects, prompts to select. If one, auto-selects)
525
+ Successfully set active project to: [My Org] Default Project
526
+ ```
527
+
528
+ - **`hookdeck project use <organization_name> <project_name>`** (two arguments):
529
+ Directly selects the project `<project_name>` under the organization `<organization_name>`.
530
+ ```sh
531
+ $ hookdeck project use "My Corp" "API Staging"
532
+ Successfully set active project to: [My Corp] API Staging
533
+ ```
331
534
 
332
535
  Upon successful selection, you will generally see a confirmation message like:
333
536
  `Successfully set active project to: [<organization_name>] <project_name>`
334
537
 
538
+ ### Manage connections
539
+
540
+ Connections link sources to destinations and define how events are processed. You can create connections, including source/destination definitions, configure authentication, add processing rules (retry, filter, transform, delay, deduplicate), and manage their lifecycle.
541
+
542
+ #### Create a connection
543
+
544
+ Create a new connection between a source and destination. You can create the source and destination inline or reference existing resources:
545
+
546
+ ```sh
547
+ # Basic connection with inline source and destination
548
+ $ hookdeck connection create \
549
+ --source-name "github-repo" \
550
+ --source-type GITHUB \
551
+ --destination-name "ci-system" \
552
+ --destination-type HTTP \
553
+ --destination-url "https://api.example.com/webhooks"
554
+
555
+ ✔ Connection created successfully
556
+ Connection: github-repo-to-ci-system (conn_abc123)
557
+ Source: github-repo (src_xyz789)
558
+ Source URL: https://hkdk.events/src_xyz789
559
+ Destination: ci-system (dst_def456)
560
+
561
+ # Using existing source and destination
562
+ $ hookdeck connection create \
563
+ --source "existing-source-name" \
564
+ --destination "existing-dest-name" \
565
+ --name "new-connection" \
566
+ --description "Connects existing resources"
567
+ ```
568
+
569
+ #### Add source authentication
570
+
571
+ Verify webhooks from providers like Stripe, GitHub, or Shopify by adding source authentication:
572
+
573
+ ```sh
574
+ # Stripe webhook signature verification
575
+ $ hookdeck connection create \
576
+ --source-name "stripe-prod" \
577
+ --source-type STRIPE \
578
+ --source-webhook-secret "whsec_abc123xyz" \
579
+ --destination-name "payment-api" \
580
+ --destination-type HTTP \
581
+ --destination-url "https://api.example.com/webhooks/stripe"
582
+
583
+ # GitHub webhook signature verification
584
+ $ hookdeck connection create \
585
+ --source-name "github-webhooks" \
586
+ --source-type GITHUB \
587
+ --source-webhook-secret "ghp_secret123" \
588
+ --destination-name "ci-system" \
589
+ --destination-type HTTP \
590
+ --destination-url "https://ci.example.com/webhook"
591
+ ```
592
+
593
+ #### Add destination authentication
594
+
595
+ Secure your destination endpoint with bearer tokens, API keys, or basic authentication:
596
+
597
+ ```sh
598
+ # Destination with bearer token
599
+ $ hookdeck connection create \
600
+ --source-name "webhook-source" \
601
+ --source-type HTTP \
602
+ --destination-name "secure-api" \
603
+ --destination-type HTTP \
604
+ --destination-url "https://api.example.com/webhooks" \
605
+ --destination-bearer-token "bearer_token_xyz"
606
+
607
+ # Destination with API key
608
+ $ hookdeck connection create \
609
+ --source-name "webhook-source" \
610
+ --source-type HTTP \
611
+ --destination-name "api-endpoint" \
612
+ --destination-type HTTP \
613
+ --destination-url "https://api.example.com/webhooks" \
614
+ --destination-api-key "your_api_key"
615
+
616
+ # Destination with custom headers
617
+ $ hookdeck connection create \
618
+ --source-name "webhook-source" \
619
+ --source-type HTTP \
620
+ --destination-name "custom-api" \
621
+ --destination-type HTTP \
622
+ --destination-url "https://api.example.com/webhooks"
623
+ ```
624
+
625
+ #### Configure retry rules
626
+
627
+ Add automatic retry logic with exponential or linear backoff:
628
+
629
+ ```sh
630
+ # Exponential backoff retry strategy
631
+ $ hookdeck connection create \
632
+ --source-name "payment-webhooks" \
633
+ --source-type STRIPE \
634
+ --destination-name "payment-api" \
635
+ --destination-type HTTP \
636
+ --destination-url "https://api.example.com/payments" \
637
+ --rule-retry-strategy exponential \
638
+ --rule-retry-count 5 \
639
+ --rule-retry-interval 60000
640
+ ```
641
+
642
+ #### Add event filters
643
+
644
+ Filter events based on request body, headers, path, or query parameters:
645
+
646
+ ```sh
647
+ # Filter by event type in body
648
+ $ hookdeck connection create \
649
+ --source-name "events" \
650
+ --source-type HTTP \
651
+ --destination-name "processor" \
652
+ --destination-type HTTP \
653
+ --destination-url "https://api.example.com/process" \
654
+ --rule-filter-body '{"event_type":"payment.succeeded"}'
655
+
656
+ # Combined filtering
657
+ $ hookdeck connection create \
658
+ --source-name "shopify-webhooks" \
659
+ --source-type SHOPIFY \
660
+ --destination-name "order-processor" \
661
+ --destination-type HTTP \
662
+ --destination-url "https://api.example.com/orders" \
663
+ --rule-filter-body '{"type":"order"}' \
664
+ --rule-retry-strategy exponential \
665
+ --rule-retry-count 3
666
+ ```
667
+
668
+ #### Configure rate limiting
669
+
670
+ Control the rate of event delivery to your destination:
671
+
672
+ ```sh
673
+ # Limit to 100 requests per minute
674
+ $ hookdeck connection create \
675
+ --source-name "high-volume-source" \
676
+ --source-type HTTP \
677
+ --destination-name "rate-limited-api" \
678
+ --destination-type HTTP \
679
+ --destination-url "https://api.example.com/endpoint" \
680
+ --destination-rate-limit 100 \
681
+ --destination-rate-limit-period minute
682
+ ```
683
+
684
+ #### Upsert connections
685
+
686
+ Create or update connections idempotently based on connection name - perfect for CI/CD and infrastructure-as-code workflows:
687
+
688
+ ```sh
689
+ # Create if doesn't exist, update if it does
690
+ $ hookdeck connection upsert my-connection \
691
+ --source-name "stripe-prod" \
692
+ --source-type STRIPE \
693
+ --destination-name "api-prod" \
694
+ --destination-type HTTP \
695
+ --destination-url "https://api.example.com"
696
+
697
+ # Partial update of existing connection
698
+ $ hookdeck connection upsert my-connection \
699
+ --description "Updated description" \
700
+ --rule-retry-count 5
701
+
702
+ # Preview changes without applying (dry-run)
703
+ $ hookdeck connection upsert my-connection \
704
+ --description "New description" \
705
+ --dry-run
706
+
707
+ -- Dry Run: UPDATE --
708
+ Connection 'my-connection' (conn_123) will be updated with the following changes:
709
+ - Description: "New description"
710
+ ```
711
+
712
+ #### List and filter connections
713
+
714
+ View all connections with flexible filtering options:
715
+
716
+ ```sh
717
+ # List all connections
718
+ $ hookdeck connection list
719
+
720
+ # Filter by source or destination
721
+ $ hookdeck connection list --source src_abc123
722
+ $ hookdeck connection list --destination dest_xyz789
723
+
724
+ # Filter by name pattern
725
+ $ hookdeck connection list --name "production-*"
726
+
727
+ # Include disabled or paused connections
728
+ $ hookdeck connection list --disabled
729
+ $ hookdeck connection list --paused
730
+
731
+ # Output as JSON
732
+ $ hookdeck connection list --output json
733
+ ```
734
+
735
+ #### Get connection details
736
+
737
+ View detailed information about a specific connection:
738
+
739
+ ```sh
740
+ # Get by ID
741
+ $ hookdeck connection get conn_123abc
742
+
743
+ # Get by name
744
+ $ hookdeck connection get "my-connection"
745
+
746
+ # Get as JSON
747
+ $ hookdeck connection get conn_123abc --output json
748
+ ```
749
+
750
+ #### Connection lifecycle management
751
+
752
+ Control connection state and event processing behavior:
753
+
754
+ ```sh
755
+ # Disable a connection (stops receiving events entirely)
756
+ $ hookdeck connection disable conn_123abc
757
+
758
+ # Enable a disabled connection
759
+ $ hookdeck connection enable conn_123abc
760
+
761
+ # Pause a connection (queues events without forwarding)
762
+ $ hookdeck connection pause conn_123abc
763
+
764
+ # Resume a paused connection
765
+ $ hookdeck connection unpause conn_123abc
766
+
767
+ # Archive a connection (hide from main lists)
768
+ $ hookdeck connection archive conn_123abc
769
+
770
+ # Restore an archived connection
771
+ $ hookdeck connection unarchive conn_123abc
772
+ ```
773
+
774
+ **State differences:**
775
+ - **Disabled**: Connection stops receiving events entirely
776
+ - **Paused**: Connection queues events but doesn't forward them (useful during maintenance)
777
+ - **Archived**: Connection is hidden from main lists but can be restored
778
+
779
+ #### Delete a connection
780
+
781
+ Delete a connection permanently:
782
+
783
+ ```sh
784
+ # Delete with confirmation prompt
785
+ $ hookdeck connection delete conn_123abc
786
+
787
+ # Delete by name
788
+ $ hookdeck connection delete "my-connection"
789
+
790
+ # Skip confirmation
791
+ $ hookdeck connection delete conn_123abc --force
792
+ ```
793
+
794
+ For complete flag documentation and all examples, see the [CLI reference](https://hookdeck.com/docs/cli?ref=github-hookdeck-cli).
795
+
335
796
  ## Configuration files
336
797
 
337
798
  The Hookdeck CLI uses configuration files to store the your keys, project settings, profiles, and other configurations.
@@ -340,9 +801,9 @@ The Hookdeck CLI uses configuration files to store the your keys, project settin
340
801
 
341
802
  The CLI will look for the configuration file in the following order:
342
803
 
343
- 1. The `--config` flag, which allows you to specify a custom configuration file name and path per command.
344
- 2. The local directory `.hookdeck/config.toml`.
345
- 3. The default global configuration file location.
804
+ 1. The `--config` flag, which allows you to specify a custom configuration file name and path per command.
805
+ 2. The local directory `.hookdeck/config.toml`.
806
+ 3. The default global configuration file location.
346
807
 
347
808
  ### Default configuration Location
348
809
 
@@ -415,13 +876,13 @@ hookdeck listen 3030 webhooks -p prod
415
876
 
416
877
  The following flags can be used with any command:
417
878
 
418
- * `--api-key`: Your API key to use for the command.
419
- * `--color`: Turn on/off color output (on, off, auto).
420
- * `--config`: Path to a specific configuration file.
421
- * `--device-name`: A unique name for your device.
422
- * `--insecure`: Allow invalid TLS certificates.
423
- * `--log-level`: Set the logging level (debug, info, warn, error).
424
- * `--profile` or `-p`: Use a specific configuration profile.
879
+ - `--api-key`: Your API key to use for the command.
880
+ - `--color`: Turn on/off color output (on, off, auto).
881
+ - `--config`: Path to a specific configuration file.
882
+ - `--device-name`: A unique name for your device.
883
+ - `--insecure`: Allow invalid TLS certificates.
884
+ - `--log-level`: Set the logging level (debug, info, warn, error).
885
+ - `--profile` or `-p`: Use a specific configuration profile.
425
886
 
426
887
  There are also some hidden flags that are mainly used for development and debugging:
427
888
 
@@ -430,6 +891,24 @@ There are also some hidden flags that are mainly used for development and debugg
430
891
  * `--console-base`: Sets the web console base URL.
431
892
  * `--ws-base`: Sets the Websocket base URL.
432
893
 
894
+ ## Troubleshooting
895
+
896
+ ### Homebrew: Binary Already Exists Error
897
+
898
+ If you previously installed Hookdeck via the Homebrew formula and are upgrading to the cask version, you may see:
899
+
900
+ ```
901
+ Warning: It seems there is already a Binary at '/opt/homebrew/bin/hookdeck'
902
+ from formula hookdeck; skipping link.
903
+ ```
904
+
905
+ To resolve this, uninstall the old formula version first, then install the cask:
906
+
907
+ ```sh
908
+ brew uninstall hookdeck
909
+ brew install --cask hookdeck/hookdeck/hookdeck
910
+ ```
911
+
433
912
 
434
913
  ## Developing
435
914
 
@@ -451,6 +930,40 @@ Then run the locally generated `hookdeck-cli` binary:
451
930
  ./hookdeck-cli
452
931
  ```
453
932
 
933
+ ## Testing
934
+
935
+ ### Running Acceptance Tests
936
+
937
+ The Hookdeck CLI includes comprehensive acceptance tests written in Go. These tests verify end-to-end functionality by executing the CLI and validating outputs.
938
+
939
+ **Local testing:**
940
+
941
+ ```bash
942
+ # Run all acceptance tests
943
+ go test ./test/acceptance/... -v
944
+
945
+ # Run specific test
946
+ go test ./test/acceptance/... -v -run TestCLIBasics
947
+
948
+ # Skip acceptance tests (short mode)
949
+ go test ./test/acceptance/... -short
950
+ ```
951
+
952
+ **Environment setup:**
953
+
954
+ For local testing, create a `.env` file in `test/acceptance/`:
955
+
956
+ ```bash
957
+ # test/acceptance/.env
958
+ HOOKDECK_CLI_TESTING_API_KEY=your_api_key_here
959
+ ```
960
+
961
+ **CI/CD:**
962
+
963
+ In CI environments, set the `HOOKDECK_CLI_TESTING_API_KEY` environment variable directly in your workflow configuration or repository secrets.
964
+
965
+ For detailed testing documentation and troubleshooting, see [`test/acceptance/README.md`](test/acceptance/README.md).
966
+
454
967
  ### Testing against a local API
455
968
 
456
969
  When testing against a non-production Hookdeck API, you can use the
@@ -471,6 +984,90 @@ docker run --rm -it \
471
984
  http://host.docker.internal:1234
472
985
  ```
473
986
 
987
+ ## Releasing
988
+
989
+ This section describes the branching strategy and release process for the Hookdeck CLI.
990
+
991
+ ### Branching Strategy
992
+
993
+ The project uses two primary branches:
994
+
995
+ - **`main`** - The stable, production-ready branch. All production releases are created from this branch.
996
+ - **`next`** - The beta/pre-release branch. All new features are merged here first for testing before being promoted to `main`.
997
+
998
+ ### Beta Releases
999
+
1000
+ Beta releases allow you to publish pre-release versions for testing without blocking the `main` branch or affecting stable releases.
1001
+
1002
+ **Process:**
1003
+
1004
+ 1. Ensure all desired features are merged into the `next` branch
1005
+ 2. Pull the latest changes locally:
1006
+ ```sh
1007
+ git checkout next
1008
+ git pull origin next
1009
+ ```
1010
+ 3. Create and push a beta tag with a pre-release identifier:
1011
+ ```sh
1012
+ git tag v1.2.3-beta.0
1013
+ git push origin v1.2.3-beta.0
1014
+ ```
1015
+ 4. The GitHub Actions workflow will automatically:
1016
+ - Build binaries for all platforms (macOS, Linux, Windows)
1017
+ - Create a GitHub pre-release (marked as "Pre-release")
1018
+ - Publish to NPM with the `beta` tag
1019
+ - Create beta packages:
1020
+ - Homebrew: `hookdeck-beta` formula
1021
+ - Scoop: `hookdeck-beta` package
1022
+ - Docker: Tagged with the version (e.g., `v1.2.3-beta.0`), but not `latest`
1023
+
1024
+ **Installing beta releases:**
1025
+
1026
+ ```sh
1027
+ # NPM
1028
+ npm install hookdeck-cli@beta -g
1029
+
1030
+ # Homebrew
1031
+ brew install hookdeck/hookdeck/hookdeck-beta
1032
+
1033
+ # Scoop
1034
+ scoop install hookdeck-beta
1035
+
1036
+ # Docker
1037
+ docker run hookdeck/hookdeck-cli:v1.2.3-beta.0 version
1038
+ ```
1039
+
1040
+ ### Production Releases
1041
+
1042
+ Production releases are created from the `main` branch using GitHub's release interface.
1043
+
1044
+ **Process:**
1045
+
1046
+ 1. Merge the `next` branch into `main`:
1047
+ ```sh
1048
+ git checkout main
1049
+ git pull origin main
1050
+ git merge next
1051
+ git push origin main
1052
+ ```
1053
+ 2. Go to the [GitHub Releases page](https://github.com/hookdeck/hookdeck-cli/releases)
1054
+ 3. Click "Draft a new release"
1055
+ 4. Create a new tag with a stable version (e.g., `v1.3.0`)
1056
+ 5. Target the `main` branch
1057
+ 6. Generate release notes or write them manually
1058
+ 7. Publish the release
1059
+
1060
+ The GitHub Actions workflow will automatically:
1061
+ - Build binaries for all platforms
1062
+ - Create a stable GitHub release
1063
+ - Publish to NPM with the `latest` tag
1064
+ - Update package managers:
1065
+ - Homebrew: `hookdeck` formula
1066
+ - Scoop: `hookdeck` package
1067
+ - Docker: Updates both the version tag and `latest`
1068
+
1069
+ **Note:** Only stable releases (without pre-release identifiers) will update the `latest` tags across all distribution channels.
1070
+
474
1071
  ## License
475
1072
 
476
1073
  Copyright (c) Hookdeck. All rights reserved.
package/bin/hookdeck CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hookdeck-cli",
3
- "version": "1.0.4",
3
+ "version": "1.2.0-beta.1",
4
4
  "description": "Hookdeck CLI",
5
5
  "repository": {
6
6
  "type": "git",