feat(local): add command to run a local Spotlight sidecar#888
Open
MathurAditya724 wants to merge 5 commits intomainfrom
Open
feat(local): add command to run a local Spotlight sidecar#888MathurAditya724 wants to merge 5 commits intomainfrom
MathurAditya724 wants to merge 5 commits intomainfrom
Conversation
Adds 'sentry local', a long-running command that starts a minimal Hono
HTTP server wire-compatible with the Spotlight sidecar protocol. The
server uses @spotlightjs/spotlight/sdk's createSpotlightBuffer +
pushToSpotlightBuffer helpers to ingest envelopes from any Sentry SDK
running in the user's dev stack and tails them to the terminal.
Endpoints exposed:
POST /stream - Spotlight ingest
POST /api/{projectId}/envelope/ - Sentry SDK ingest path
GET /stream - SSE feed for the Spotlight overlay
GET /health - liveness check
Why a thin in-tree server instead of spawning npx @spotlightjs/spotlight:
the SDK helpers give us decompression + lazy parsing for free while
keeping the surface focused on a CLI-friendly tail UX, and bundling
through esbuild keeps the published binary self-contained per the
no-runtime-dependencies rule.
The command runs without auth (it's a local dev tool) and shuts down
gracefully on SIGINT/SIGTERM, force-closing keep-alive connections so
SSE subscribers don't block exit.
Contributor
|
Contributor
Codecov Results 📊✅ 6343 passed | Total: 6343 | Pass Rate: 100% | Execution Time: 0ms 📊 Comparison with Base Branch
✨ No test changes detected All tests are passing successfully. ❌ Patch coverage is 25.10%. Project has 13230 uncovered lines. Files with missing lines (1)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
- Coverage 76.03% 75.80% -0.23%
==========================================
Files 294 295 +1
Lines 54404 54659 +255
Branches 0 0 —
==========================================
+ Hits 41362 41429 +67
- Misses 13042 13230 +188
- Partials 0 0 —Generated by Codecov Action |
Replace the minimal 'timestamp • type' one-liner with rich formatted output that shows actual event content: error type/message with stack location, transaction name/op/duration/span count, and log messages with attributes. Uses the CLI's own color system since Spotlight's humanFormatters aren't publicly exported from the package.
Adds a repeatable --filter flag that accepts error, transaction, or log. When set, only matching envelope items are rendered in the tail output; non-matching items are silently dropped. No filter = show everything. Usage: sentry local -f error # errors only sentry local -f error -f log # errors and logs sentry local -f transaction # transactions only
Three fixes based on audit against Spotlight's reference implementation: 1. Signal handling: process.once -> process.on so the 'second signal = force exit' code path is reachable (process.once unregisters after the first signal, making the shuttingDown check dead code). 2. SSE format: match the Spotlight protocol so the overlay UI works. - event name is the content type (not 'envelope') - id field is the Spotlight-assigned envelope UUID - data is the parsed envelope JSON (not base64-encoded raw bytes) - Last-Event-ID reconnection is now supported 3. Browser SDK: detect sendBeacon() payloads (Content-Type: text/plain with sentry_client query param) and override to the canonical application/x-sentry-envelope, matching Spotlight's workaround.
The --open flag opened the raw SSE endpoint in a browser, which just shows streaming text — not useful without the Spotlight overlay UI. Removed it and updated the fragment docs to document the new pretty-print tail output and --filter flag instead.
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.
Summary
Adds
sentry local, a long-running command that starts a minimal Hono HTTP server wire-compatible with the Spotlight sidecar protocol. It uses@spotlightjs/spotlight/sdk'screateSpotlightBufferandpushToSpotlightBufferhelpers to ingest envelopes from any Sentry SDK running in the user's dev stack and tails them to the terminal.This gives users a one-command path to "Sentry for development" without leaving the CLI: errors, traces, and logs from their dev stack stream straight into their shell, and the SSE endpoint stays compatible with the Spotlight overlay for richer rendering.
What's new
src/commands/local.ts— new command. Flags:--port/-p(default8969),--host/-H(defaultlocalhost),--open/-o,--quiet/-q. Runs without auth.src/app.ts— wireslocalinto the top-level route map.package.json— adds@spotlightjs/spotlight,hono, and@hono/node-serveras devDependencies (per the no-runtime-deps rule; everything is bundled at build time).docs/src/fragments/commands/local.md— hand-written examples + endpoint table.Endpoints exposed
POST/streamPOST/api/{projectId}/envelope/GET/streamGET/healthWhy a thin in-tree server instead of spawning
npx @spotlightjs/spotlightThe SDK helpers give us decompression (gzip/deflate/br) + lazy envelope parsing for free, while keeping the command's surface focused on a CLI-friendly tail UX. Bundling through esbuild also keeps the published binary self-contained per the no-runtime-dependencies rule — users don't need a separate npx install or a network connection on first run.
Testing
bun run typecheckbun x ultracite check(only the pre-existing unrelatedmarkdown.tswarning)bun run check:deps/check:fragments/check:errors/check:docs-sectionsbun test --timeout 15000 --isolate --parallel test/lib test/commands test/types— 6343 pass / 0 failSENTRY_CLIENT_ID=test bun run script/bundle.ts— bundle builds cleanly/stream, observed204 No Contentand the tail lineHH:MM:SS.sss • eventappear; SIGTERM shut down gracefully. Same flow against the bundlednode dist/bin.cjs.Out of scope
setupSpotlight()from the upstream package can serve it but pulls in MCP / @sentry/node / a much larger dependency tree; this PR sticks to the small Hono server to keep the CLI lean.