Conversation
Contributor
Semver Impact of This PR🟡 Minor (new features) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨Dashboard
Init
Other
Bug Fixes 🐛Dashboard
Event
Other
Documentation 📚
Internal Changes 🔧Coverage
Event
Other
🤖 This preview updates automatically when you update the PR. |
Contributor
|
Contributor
Codecov Results 📊✅ 126 passed | Total: 126 | Pass Rate: 100% | Execution Time: 0ms 📊 Comparison with Base Branch
✨ No test changes detected All tests are passing successfully. ✅ Patch coverage is 100.00%. Project has 1275 uncovered lines. Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
+ Coverage 95.52% 95.60% +0.08%
==========================================
Files 194 201 +7
Lines 28620 28983 +363
Branches 0 0 —
==========================================
+ Hits 27339 27708 +369
- Misses 1281 1275 -6
- Partials 0 0 —Generated by Codecov Action |
a763436 to
9dab485
Compare
e7272ba to
b649fa1
Compare
Add a variadic `sentry()` function that runs CLI commands in-process
and returns parsed JSON objects (or raw text). This enables AI coding
agents, build tools, and other JS/TS consumers to use the CLI without
spawning a subprocess.
```typescript
import sentry from "sentry";
const issues = await sentry("issue", "list", "-l", "5");
const orgs = await sentry("org", "list", { token: "sntrys_..." });
```
Options: `token` (auth override), `text` (human output), `cwd` (working dir).
Errors throw `SentryError` with `.exitCode` and `.stderr`.
- **Env registry** (`src/lib/env.ts`): `getEnv()`/`setEnv()` replaces all
direct `process.env` reads (~14 files ported). Library mode creates an
isolated env copy — consumer's `process.env` is never mutated.
- **Zero-copy return**: `renderCommandOutput` duck-types a `captureObject`
method on the Writer to hand back the in-memory object directly, avoiding
the `JSON.stringify` → buffer → `JSON.parse` round-trip.
- **Single npm bundle**: esbuild entry point changes from `src/bin.ts` to
`src/index.ts`. A tiny `dist/bin.cjs` wrapper (~200 bytes) calls
`require("./index.cjs")._cli()`. npm package size stays flat.
- **Library-safe telemetry**: `initSentry({ libraryMode: true })` strips
all global-polluting integrations (process listeners, HTTP trace headers,
Function.prototype wrapping). Manual `client.flush()` replaces beforeExit.
- **CLI extraction**: `src/bin.ts` logic moved to `src/cli.ts` (exported
functions, no top-level execution). `bin.ts` becomes a thin bun compile
entry point.
- **`SENTRY_OUTPUT_FORMAT=json`**: New env var in `command.ts` forces JSON
mode without `--json` flag — how the library gets JSON by default.
- Replace process.exit() in OutputError handler with throw + Stricli intercept in app.ts (BugBot: kills host process in library mode) - Wrap withTelemetry in try/catch in sentry() to convert all internal errors (AuthError, OutputError, etc.) to SentryError (Seer + BugBot) - Set process.exitCode=1 in bin wrapper catch handler (BugBot)
Add createSentrySDK() that provides typed methods with named parameters,
bypassing Stricli's string dispatch layer entirely:
const sdk = createSentrySDK({ token: "sntrys_..." });
const issues = await sdk.issues.list({ org: "acme", project: "frontend" });
const org = await sdk.organizations.get("acme");
Architecture:
- sdk-invoke.ts resolves Commands from the route tree (cached) and calls
handler functions directly with pre-built flag objects — no string
parsing, no route scanning overhead.
- generate-sdk.ts walks the route tree at build time via introspection,
extracts flag definitions, and generates typed parameter interfaces +
method implementations in sdk.generated.ts.
- 7 namespaces: organizations, projects, issues, events, traces, spans,
teams with list/get methods.
Ref: #566 tracks schema registration on OutputConfig for auto-generated
return types (currently uses a manual type map in the codegen script).
…eful payload In library mode (sentry() and SDK), OutputError carries data that was already captured via captureObject before the re-throw. Previously, the catch blocks in index.ts and sdk-invoke.ts would convert ALL thrown errors to SentryError, losing the captured data. Now both catch blocks check capturedResult before error conversion. If data was captured (e.g., OutputError rendered a 404 response body), it is returned to the caller instead of throwing. This follows the 'HTTP 404 body' pattern — the data is useful even when the operation technically 'failed'. The check is on capturedResult !== undefined rather than instanceof OutputError, making it future-proof for any error that captures data before throwing.
Replace hand-written SentrySDK type in bundle.ts TYPE_DECLARATIONS with types extracted from src/sdk.generated.ts at bundle time. This ensures the .d.cts file stays in sync with the generated SDK automatically. The previous hand-written type was missing many parameters (platform, cursor, sort, period, query, spans) and used Promise<unknown> instead of the actual return types from the generated methods. The extraction: 1. Collects all exported param type blocks (XxxParams) verbatim 2. Parses createSDKMethods return shape into SentrySDK type 3. Transforms method implementations into type signatures 4. Strips invoke call bodies, preserves JSDoc comments
17 e2e tests that verify the bundled output works as a library: - Bundle structure (no shebang, no warning suppression in library) - Export shape (sentry, createSentrySDK, SentryError, SentryOptions) - Variadic API (version, env isolation, error wrapping) - Typed SDK (namespace methods, auth error handling) - Type declarations (.d.cts content) All tests run the bundled dist/index.cjs via Node.js subprocesses to verify real npm package behavior.
The node:sqlite import in node-polyfills.ts was eagerly evaluated at bundle load time, causing ERR_UNKNOWN_BUILTIN_MODULE on Node.js versions without node:sqlite support. Now the import is deferred to the NodeDatabasePolyfill constructor — only loaded when a database is actually opened, not when the library is require()d.
Rework the typed SDK to auto-discover ALL commands from the Stricli route tree with zero manual config: - generate-sdk.ts walks the entire route tree recursively, discovers 44 commands, generates typed methods using CLI route names as-is (sdk.org.list, sdk.dashboard.widget.add) - Return types derived from __jsonSchema (PR #582) via extractSchemaFields() — commands with schemas get typed returns, others default to unknown - Positional params derived from introspection placeholder strings - createSentrySDK() is now the single public API (default export) - sdk.run() escape hatch replaces the standalone sentry() function - SentryError/SentryOptions extracted to sdk-types.ts to break circular deps between index.ts and sdk-invoke.ts
Contributor
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
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
Exposes the Sentry CLI as a JavaScript/TypeScript library with a typed SDK that auto-generates methods for every CLI command.
44 commands auto-discovered from the route tree. Zero manual config.
API
createSentrySDK(options?)is the single entry point (default export).tokenstringSENTRY_AUTH_TOKEN/SENTRY_TOKEN)textbooleanfalsecwdstringprocess.cwd()Command.loader()invocationsdk.run(...args)escape hatch routes through Stricli for commands not yet typed or interactive workflowsSentryErrorwith.exitCodeand.stderrArchitecture
Auto-generated SDK (
script/generate-sdk.ts)Build-time codegen walks the route tree via Stricli introspection:
org.list,issue.explain,dashboard.widget.add__jsonSchema(feat(output): add Zod schema registration to OutputConfig for self-documenting JSON fields #582) → typed return types from Zod schemasDirect command invocation (
src/lib/sdk-invoke.ts)buildInvoker()resolves commands from the route tree (cached), callsCommand.loader()directly with pre-built flag objects.buildRunner()provides thesdk.run()escape hatch via Stricli'srun().Env registry (
src/lib/env.ts)getEnv()/setEnv()replaces all directprocess.envreads (~14 files). Library mode creates an isolated env copy — consumer'sprocess.envis never mutated.CLI extraction (
src/cli.ts)CLI runner extracted from
bin.ts. Both the npm bin wrapper and library share the same internals.Single npm bundle
esbuild entry:
src/index.ts→dist/index.cjs. Tinydist/bin.cjswrapper (~200 bytes) for CLI. Package size stays flat.Zero-copy return
captureObjectduck-type on Writer hands back in-memory objects directly.Library-safe telemetry
initSentry({ libraryMode: true })strips global-polluting integrations.Lazy
node:sqlitePolyfill defers
node:sqliteimport to first DB access, sorequire("sentry")doesn't crash.Tests
test/lib/env.test.ts— env registry (5 tests)test/lib/index.test.ts—createSentrySDK+sdk.run()(7 tests)test/lib/sdk.test.ts— typed SDK methods + namespaces (7 tests)test/e2e/library.test.ts— bundled library via Node.js subprocesses (17 tests)Documentation
docs/src/content/docs/library-usage.mdRelated