Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/workflows/local.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Local E2E

on:
pull_request:
paths:
- "apps/local/**"
- "packages/cli/src/commands/local/**"
- "packages/cli/test/commands/local/**"
- "packages/cli/test/e2e/local.test.ts"
- "pnpm-lock.yaml"
- ".github/workflows/local.yml"
workflow_dispatch:

permissions:
contents: read

jobs:
local:
name: Local (${{ matrix.os }})
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
binary: sentry-linux-x64
- os: macos-latest
binary: sentry-darwin-arm64
- os: windows-latest
binary: sentry-windows-x64.exe
env:
SENTRY_CLIENT_ID: test-client-id
SENTRY_CLI_NO_TELEMETRY: "1"
FOSSILIZE_SIGN: "n"
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: "22.23.1"
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Viewer integration tests
run: pnpm --filter local test
- name: Bundle the CLI
run: pnpm --filter sentry bundle
- name: NPM daemon E2E
env:
SENTRY_CLI_BINARY: ${{ github.workspace }}/packages/cli/dist/bin.cjs
run: pnpm --filter sentry exec vitest run test/e2e/local.test.ts
- name: Build native CLI
run: pnpm --filter sentry build
- name: Native daemon E2E
env:
SENTRY_CLI_BINARY: ${{ github.workspace }}/packages/cli/dist-bin/${{ matrix.binary }}
run: pnpm --filter sentry exec vitest run test/e2e/local.test.ts
3 changes: 2 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ Toolkit contains the Sentry CLI, the Sentry MCP server, and shared code. Product
```
toolkit/
├── apps/
│ └── cli-docs/ # CLI documentation site and generated command pages
│ ├── cli-docs/ # CLI documentation site and generated command pages
│ └── local/ # Sentry Local browser viewer
├── packages/
│ ├── cli/ # Sentry CLI (see packages/cli/AGENTS.md)
│ ├── toolkit-core/ # Shared CLI/MCP primitives
Expand Down
2 changes: 1 addition & 1 deletion apps/cli-docs/src/content/docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ toolkit/
│ │ │ ├── event/ # list, send, view
│ │ │ ├── feedback/ # list, resolve, spam, unresolve, view
│ │ │ ├── issue/ # archive, events, explain, link, list, merge, plan, resolve, unlink, unresolve, view
│ │ │ ├── local/ # run, serve
│ │ │ ├── local/ # close, create, list, reset, restart, retention, run, serve, start, status, stop, view
│ │ │ ├── log/ # list, view
│ │ │ ├── monitor/ # list, run
│ │ │ ├── org/ # list, view
Expand Down
26 changes: 25 additions & 1 deletion apps/cli-docs/src/fragments/commands/local.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ sentry local --open
sentry local run --open -- npm run dev
```

The `--open` flag requires a loopback `--host` (localhost, 127.0.0.1, or ::1). The UI is read-only — it reads the SSE stream but cannot ingest or clear data. Session data stays in memory for the duration of the server; nothing is sent to sentry.io unless a DSN is configured.
The `--open` flag requires a loopback `--host` (localhost, 127.0.0.1, or ::1). The hosted UI reads the SSE stream without changing retained receiver data. A loopback-served viewer can clear a receiver and reset or close a scoped daemon session. Session data stays in memory for the duration of the server; nothing is sent to sentry.io unless a DSN is configured.

## Endpoints

Expand Down Expand Up @@ -185,3 +185,27 @@ curl -i http://127.0.0.1:3030/api/broken

The final request intentionally returns HTTP 500. The fixture is for local
experimentation only; do not run it with production credentials.

## Daemon-owned sessions

Use `--session <name>` to capture into the shared loopback daemon and retain data
after your foreground command exits. Sessions keep up to 500 envelopes for three
hours after closing and subsequent ingestion. Stopping or restarting the daemon
clears all sessions.

```bash
sentry local run --session web -- npm run dev
sentry local serve --session worker
sentry local session list --json
sentry local event list web --json
sentry local event view web <event-id> --json
sentry local envelope list web --json
sentry local session reset web
sentry local session close web
sentry local daemon status
sentry local daemon stop
```

`local session create <name> --json` returns separate SDK ingest and viewer read
capability URLs. Keep these URLs private. `--clientId <key>` makes retried session
creation idempotent. Use the session ID when multiple sessions share a label.
24 changes: 24 additions & 0 deletions apps/local/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
8 changes: 8 additions & 0 deletions apps/local/.oxlintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["react", "typescript", "oxc"],
"rules": {
"react/rules-of-hooks": "error",
"react/only-export-components": ["warn", { "allowConstantExport": true }]
}
}
21 changes: 21 additions & 0 deletions apps/local/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/index.css",
"baseColor": "zinc",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}
14 changes: 14 additions & 0 deletions apps/local/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en" suppressHydrationWarning>
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="/src/index.css" rel="stylesheet" />
<title>Sentry CLI</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
55 changes: 55 additions & 0 deletions apps/local/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"name": "local",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "oxlint",
"preview": "vite preview",
"test": "vitest run",
"test:integration": "vitest run src/App.integration.test.tsx",
"typecheck": "tsc -b"
},
"engines": {
"node": "^20.19.0 || >=22.12.0"
},
"dependencies": {
"@radix-ui/react-dialog": "^1.1.23",
"@radix-ui/react-slot": "^1.3.3",
"@shikijs/core": "^3.23.0",
"@shikijs/engine-javascript": "^3.23.0",
"@shikijs/langs": "^3.23.0",
"@shikijs/themes": "^3.23.0",
"@tailwindcss/vite": "^4.3.3",
"@uidotdev/usehooks": "^2.4.1",
"@vercel/analytics": "^2.0.1",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"lucide-react": "^1.43.0",
"next-themes": "^0.4.6",
"nuqs": "^2.10.1",
"react": "^19.2.8",
"react-dom": "^19.2.8",
"react-router": "^7.18.3",
"tailwind-merge": "^3.6.0",
"tailwindcss": "^4.3.3",
"tslib": "^2.8.1"
},
"devDependencies": {
"@spotlightjs/spotlight": "^4.11.7",
"@testing-library/react": "^16.3.2",
"@types/node": "^24.13.3",
"@types/react": "^19.2.18",
"@types/react-dom": "^19.2.4",
"@vitejs/plugin-react": "^6.1.0",
"eventsource": "^4.1.0",
"jsdom": "^28.1.0",
"oxlint": "^1.79.0",
"typescript": "catalog:",
"vite": "^8.2.2",
"vitest": "^4.1.9"
}
}
53 changes: 53 additions & 0 deletions apps/local/public/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions apps/local/public/sentry-cli-light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading