Skip to content
Merged
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@
"Bash(pnpm -w run lint:*)",
"Bash(pnpm -w run lint:fix)",
"Bash(pnpm lint:*)",
"Bash(pnpm biome lint:*)",
"Bash(biome lint:*)",
"Bash(pnpm oxlint:*)",
"Bash(oxlint:*)",
"Bash(pnpx wrangler:*)",
"Bash(pnpx wrangler versions upload:*)",
"Bash(pnpx wrangler delete:*)",
Expand Down
6 changes: 5 additions & 1 deletion .oxfmtrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
"sortPackageJson": false,
"ignorePatterns": [
"apps/cli-docs/**",
"packages/cli/**",
"packages/cli/plugins/**",
"packages/cli/README.md",
"packages/cli/DEVELOPMENT.md",
"packages/cli/CHANGELOG.md",
"packages/cli/AGENTS.md",
"packages/mcp-server-mocks/src/fixtures/**",
"**/worker-configuration.d.ts",
"**/tsconfig*.json"
Expand Down
84 changes: 83 additions & 1 deletion .oxlintrc.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["eslint", "typescript", "unicorn", "oxc", "jsx-a11y"],
"jsPlugins": ["./packages/cli/lint-rules/cli-oxlint-plugin.js"],
"categories": {
"correctness": "error"
},
"ignorePatterns": [
"apps/cli-docs/**",
"packages/cli/**",
"**/worker-configuration.d.ts",
"**/tsconfig*.json",
"packages/mcp-server-mocks/src/fixtures/**"
Expand All @@ -21,6 +21,88 @@
"rules": {
"jsx-a11y/no-static-element-interactions": "off"
}
},
{
"files": [
"packages/cli/src/**/*.{ts,tsx}",
"packages/cli/test/**/*.{ts,tsx}"
],
"rules": {
"sentry-cli/no-silent-catch": "error",
"sentry-cli/no-stdout-write-in-commands": "error",
"sentry-cli/no-process-stdout-in-commands": "error",
"sentry-cli/no-stderr-write-in-commands": "error",
"sentry-cli/no-raw-metadata-queries": "error",
"sentry-cli/no-manual-transactions": "error",
"sentry-cli/no-inline-touch-cache": "error",
"sentry-cli/no-args-join-in-release": "error",
"sentry-cli/no-direct-target-resolution": "error",
"sentry-cli/no-generic-is-record": "error",
"sentry-cli/prefer-paginate-helper": "error",
"sentry-cli/no-namespace-import": "error",
"no-restricted-imports": [
"error",
{
"paths": [
{
"name": "@stricli/core",
"importNames": ["buildCommand", "buildRouteMap"],
"message": "Import the CLI command and route-map wrappers instead; they provide telemetry and standard aliases."
}
]
}
],
"no-bitwise": "error",
"max-params": ["error", 5],
"sentry-cli/no-skipped-tests": "error"
}
},
{
"files": ["packages/cli/src/**/*.{ts,tsx}"],
"rules": {
"typescript/no-explicit-any": "error",
"typescript/no-non-null-assertion": "error"
}
},
{
"files": [
"packages/cli/src/lib/command.ts",
"packages/cli/src/lib/route-map.ts"
],
"rules": {
"no-restricted-imports": "off"
}
},
{
"files": ["packages/cli/src/commands/**/*.{ts,tsx}"],
"rules": {
"no-restricted-imports": [
"error",
{
"paths": [
{
"name": "@stricli/core",
"importNames": ["buildCommand", "buildRouteMap"],
"message": "Import the CLI command and route-map wrappers instead; they provide telemetry and standard aliases."
},
{
"name": "chalk",
"message": "Use colorTag() from formatters/markdown.js so plain output works."
}
]
}
]
}
},
{
"files": [
"packages/cli/src/lib/build/zip-writer.ts",
"packages/cli/src/lib/build/index.ts",
"packages/cli/test/lib/build/zip-writer.test.ts"
],
"rules": {
"no-bitwise": "off"
}
}
]
}
2 changes: 1 addition & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"recommendations": ["oxc.oxc-vscode", "biomejs.biome"],
"recommendations": ["oxc.oxc-vscode"],
"unwantedRecommendations": []
}
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 @@ -137,7 +137,7 @@ pnpm run test -- --coverage

## Code Style

The project uses [Ultracite](https://github.com/getsentry/ultracite) for linting and formatting:
The project uses Oxlint and Oxfmt for linting and formatting:

```bash
# Check for issues
Expand Down
17 changes: 8 additions & 9 deletions docs/contributing/coding-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,11 @@ Essential patterns and standards for Sentry MCP development.
- 2 spaces, double quotes, semicolons
- Formatter width: 80 characters
- Trailing commas in multiline
- MCP and root files use Oxfmt and Oxlint; CLI files still use their own Biome rules.
- CLI's custom Grit rules and inline suppressions remain active until their
equivalents are available in the new linter.
- VS Code uses Oxc for root and MCP files. Oxfmt ignores `packages/cli/**`;
use `pnpm --filter sentry exec biome format --write <file>` to format a CLI
file and keep CLI's Biome checks in the pre-commit hook.
- Root, MCP, and CLI files use Oxlint and Oxfmt. The CLI-specific rules live in
`packages/cli/lint-rules/cli-oxlint-plugin.js`, with inline Oxlint suppressions
for intentional exceptions.
- VS Code uses the Oxc extension for formatting and linting. Run
`pnpm exec oxfmt --write <file>` to format a file.

### Naming Conventions

Expand Down Expand Up @@ -99,10 +98,10 @@ Key practices:
Before committing:

```bash
pnpm -w run lint # Oxlint and ast-grep checks for MCP and root files
pnpm -w run lint # Oxlint and ast-grep checks for root, MCP, and CLI
pnpm -w run lint:fix # Fix issues
pnpm -w run format # Format MCP and root files with Oxfmt
pnpm --filter sentry run lint # CLI Biome rules
pnpm -w run format # Format with Oxfmt
pnpm --filter sentry run lint # CLI-specific lint and format checks
pnpm tsc --noEmit # Type check
pnpm test # Run tests
pnpm -w run build # Build all
Expand Down
50 changes: 25 additions & 25 deletions docs/specs/search-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

Natural-language event search is exposed as one tool per dataset:

| Tool | Dataset | Seer strategy |
| --- | --- | --- |
| `search_errors` | `errors` | `Errors` |
| `search_logs` | `logs` | `Logs` |
| `search_traces` | `spans` | `Traces` |
| `search_metrics` | `metrics` | `Metrics` |
| `search_profiles` | `profiles` | — |
| `search_replays` | `replays` | — |
| Tool | Dataset | Seer strategy |
| ----------------- | ---------- | ------------- |
| `search_errors` | `errors` | `Errors` |
| `search_logs` | `logs` | `Logs` |
| `search_traces` | `spans` | `Traces` |
| `search_metrics` | `metrics` | `Metrics` |
| `search_profiles` | `profiles` | — |
| `search_replays` | `replays` | — |

All six share one handler (`tools/support/search-events/search.ts`). Each tool
fixes its dataset, so the caller never chooses a `dataset` parameter and the
Expand Down Expand Up @@ -39,12 +39,12 @@ direct MCP surface and is excluded from skill definitions.
// search_errors / search_logs / search_traces / search_metrics / search_profiles
interface DatasetSearchParams {
organizationSlug: string;
query?: string; // Natural language (preferred) or Sentry search syntax
query?: string; // Natural language (preferred) or Sentry search syntax
projectSlug?: string;
fields?: string[];
sort?: string;
period?: string; // e.g. "24h", "7d"
limit?: number; // Default: 10, Max: 100
period?: string; // e.g. "24h", "7d"
limit?: number; // Default: 10, Max: 100
includeExplanation?: boolean;
regionUrl?: string;
}
Expand All @@ -57,24 +57,24 @@ interface DatasetSearchParams {
```typescript
search_errors({
organizationSlug: "my-org",
query: "database timeouts in checkout flow from last hour"
})
query: "database timeouts in checkout flow from last hour",
});

search_traces({
organizationSlug: "my-org",
query: "API calls taking over 5 seconds",
projectSlug: "backend"
})
projectSlug: "backend",
});

search_logs({
organizationSlug: "my-org",
query: "warning logs about memory usage"
})
query: "warning logs about memory usage",
});

search_metrics({
organizationSlug: "my-org",
query: "p95 request duration by transaction this week"
})
query: "p95 request duration by transaction this week",
});
```

## Architecture
Expand Down Expand Up @@ -112,7 +112,7 @@ search_metrics({
The AI produces different query patterns based on the selected dataset:

- **Spans dataset**: Focus on `span.op`, `span.description`, `span.duration`, `transaction`, supports timestamp filters
- **Errors dataset**: Focus on `message`, `level`, `error.type`, `error.handled`, supports timestamp filters
- **Errors dataset**: Focus on `message`, `level`, `error.type`, `error.handled`, supports timestamp filters
- **Logs dataset**: Focus on `message`, `severity`, `severity_number`, **NO timestamp filters** (uses statsPeriod instead)
- **Tracemetrics dataset**: Focus on `metric.name`, `metric.type`, `metric.unit`, `value`, and metric-aware aggregates like `p95(value,http.request.duration,distribution,millisecond)`

Expand Down Expand Up @@ -167,21 +167,21 @@ Requests for a metric over time ("per hour", "per day", "trend", "over time") re
find_errors({
organizationSlug: "sentry",
filename: "checkout.js",
query: "is:unresolved"
})
query: "is:unresolved",
});

// After
search_errors({
organizationSlug: "sentry",
query: "unresolved errors in checkout.js"
})
query: "unresolved errors in checkout.js",
});
```

## Implementation Status

### Completed Features

1. **Custom attributes API integration**:
1. **Custom attributes API integration**:
- ✅ `/organizations/{org}/trace-items/attributes/` for spans/logs/metrics with parallel string/number fetching
- ✅ `/organizations/{org}/tags/` for errors (legacy API)

Expand Down
8 changes: 2 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
},
"scripts": {
"docs:check": "node scripts/check-doc-links.mjs",
"test:ci-projects": "node --test scripts/ci-projects.test.mjs scripts/cli-nightly-version.test.mjs scripts/cloudflare-deployment.test.mjs scripts/deploy-workflow.test.mjs scripts/migrate-cloudflare-token.test.mjs scripts/oxc-config.test.mjs",
"test:ci-projects": "node --test scripts/ci-projects.test.mjs scripts/cli-nightly-version.test.mjs scripts/cloudflare-deployment.test.mjs scripts/deploy-workflow.test.mjs scripts/migrate-cloudflare-token.test.mjs scripts/oxc-config.test.mjs scripts/cli-lint-rules.test.mjs",
"dev": "pnpm --filter '@sentry/mcp-cloudflare...' --if-present run build && dotenv -e .env -e .env.local -- pnpm --parallel --filter @sentry/mcp-cloudflare --filter @sentry/mcp-core --filter @sentry/mcp-server-mocks --if-present run dev",
"dev:stdio": "pnpm --filter '@sentry/mcp-server...' --if-present run build && dotenv -e .env -e .env.local -- pnpm --parallel --filter @sentry/mcp-server --filter @sentry/mcp-core --filter @sentry/mcp-server-mocks --if-present run dev",
"build": "dotenv -e .env -e .env.local -- pnpm -r --filter '!sentry' --filter '!sentry-cli-docs' --if-present run build",
Expand All @@ -33,7 +33,7 @@
"eval": "pnpm --filter '@sentry/mcp-server-evals...' --if-present run build && dotenv -e .env -e .env.local -- pnpm --filter @sentry/mcp-server-evals run eval",
"eval:ci": "pnpm --filter '@sentry/mcp-server-evals...' --if-present run build && CI=true dotenv -e .env -e .env.local -- pnpm --stream -r run eval:ci",
"format": "oxfmt --write",
"lint": "oxlint . && pnpm run lint:ast-grep",
"lint": "oxlint --report-unused-disable-directives . && pnpm run lint:ast-grep",
"lint:ast-grep": "ast-grep scan && ast-grep test --skip-snapshot-tests",
"lint:fix": "oxlint --fix .",
"pre-commit:generated": "node scripts/pre-commit-generated.mjs",
Expand Down Expand Up @@ -71,10 +71,6 @@
"*": [
"oxfmt --write --no-error-on-unmatched-pattern",
"oxlint --fix --no-error-on-unmatched-pattern"
],
"packages/cli/**/*": [
"pnpm --filter sentry exec biome format --write --no-errors-on-unmatched --files-ignore-unknown=true",
"pnpm --filter sentry exec biome lint --fix --no-errors-on-unmatched --files-ignore-unknown=true"
]
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/.cursor/hooks.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"hooks": {
"afterFileEdit": [
{
"command": "npx ultracite fix"
"command": "pnpm --filter sentry run lint:fix"
}
]
}
Expand Down
23 changes: 23 additions & 0 deletions packages/cli/.cursor/rules/oxc.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
description: Oxc formatting and lint rules
globs: "**/*.{ts,tsx,js,jsx,json,jsonc,html,css,md,mdx}"
alwaysApply: false
---

# CLI code standards

Run `pnpm run lint` from `packages/cli` for Oxlint, CLI-specific rules, and
Oxfmt. Run `pnpm run lint:fix` to apply safe fixes and formatting. The root
pre-commit hook uses the same tools for staged files.

- Prefer strict types and `unknown` to `any`; narrow input before use.
- Use `const`, Node `node:*` APIs, and argument arrays for child processes.
- Await promises and handle errors at the right boundary. Never use an async
Promise executor or silently discard a failed operation.
- Keep command output in `CommandOutput` and diagnostics in the tagged logger.
- Avoid top-level browser/Node APIs that break supported runtimes.
- Keep tests isolated, with assertions in `it()`/`test()` and no disabled cases.
- Use `// oxlint-disable-next-line <rule> -- <reason>` only for an intentional
exception. Unused suppressions fail CI; remove them when fixing the code.

The CLI-specific Oxlint rules live in `lint-rules/cli-oxlint-plugin.js`.
Loading
Loading