Conversation
`hookdeck listen` now advertises X-Hookdeck-CLI-Capabilities: binary on every websocket connect. Servers that support it send binary bodies as request.data_base64 with body_format: binary; the CLI decodes them and forwards the original bytes with the original Content-Type (multipart boundary included) without parsing multipart. Text attempts and servers that predate data_base64 keep using data_string. - A body that fails to decode fails the attempt immediately instead of waiting for the server timeout. - The TUI summarises binary bodies by size instead of printing them. - Acceptance test TestListenForwardsBinaryBodiesByteExact (listen tag) is gated on HOOKDECK_CLI_TESTING_BINARY_DELIVERY (and HOOKDECK_CLI_TESTING_MULTIPART_BINARY_DELIVERY for multipart) until the server side is deployed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…inary bodies - TestListenForwardsBinaryFilesThatTheAppCanSave: a local app saves each request to disk (raw body by Content-Type, multipart via ParseMultipartForm) and every file must match the original SHA-256 and still decode: PNG, JPEG, PDF, every byte value, and a multipart upload with a PNG and a WAV. - TestListenRetriesBinaryBodyByteExact: the first delivery returns 500, `gateway event retry` redelivers, and attempt 2 carries the same bytes. - TestListenBinaryWithOldAndNewCLIListening: this CLI and one built with no advertised capabilities listen on the same source as separate CLI clients. This CLI gets exact bytes; the other's event fails with CLI_BINARY_UNSUPPORTED, and multipart reaches it as lossy text. The advertised capabilities are now a variable so the test can build a CLI that advertises nothing with -ldflags -X, instead of skipping when no old binary is available. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The mixed-version test now downloads the v3.0.3 release for the current platform, verifies it against a pinned SHA-256, and runs it alongside this CLI. That is the real last release before binary delivery, so the ldflags hook that built a CLI advertising no capabilities is removed and the capabilities header is a constant again. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
leggetter
marked this pull request as ready for review
September 28, 2026 10:57
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
hookdeck listennow forwards binary request bodies (non-UTF-8 payloads, and multipart file uploads) byte-exact.X-Hookdeck-CLI-Capabilities: binaryon every websocket connect.request.data_base64and forwards the original bytes with the originalContent-Type. The CLI does not parse multipart.data_string.Other changes
Tests
End to end (local stack, hookdeck/core#5709):
CLI_BINARY_UNSUPPORTED.Acceptance tests (
test/acceptance/listen_binary_test.go,listentag):Unit:
binary_body_test.go: byte-exact forwarding (raw and multipart), text path unchanged, invalid base64 rejected.client_test.go: the capability header is sent on connect.Size, one-off local run:
/deliverdirectly: local ingestion can't store bodies over 2.5 MB without GCS.Not tested:
🤖 Generated with Claude Code