Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Support natural language search in explore in CLI

Abierto
#424 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
35/100
Tipo de issue
Nueva funcionalidad
Claridad
Bien especificado
Estado de actividad
Estancado
Stack tecnológico
typescript
Área
api, cli, testing

Línea de trabajo

Empieza leyendo src/app.ts y los patrones existentes de comandos, cliente de API, formateador, URL y pruebas referenciados en el plan. Implementa después los archivos search-agent y la ruta indicados, y ejecuta los tres comandos de prueba de búsqueda especificados, el typecheck y el lint; se considera terminado cuando estén cubiertas las estrategias documentadas, los modos de salida, la generación de URL y los flujos de API simulados.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Plan: sentry search — Natural Language Search via Seer AI

Summary

Add a sentry search command that translates natural language queries into structured Sentry queries using Seer AI, executes the query, and displays results. Also add --ask flags to existing list commands (issue list, log list, trace list) that delegate to the same NL translation.

User Experience

# Top-level NL search
sentry search "show me slow database queries from the last hour"
sentry search "error rate by endpoint in production" --strategy logs
sentry search "p95 latency for /api/users" --web
sentry search "which transactions have the most errors" --json
sentry ask "unresolved issues affecting 100+ users"   # alias

# NL on existing commands (future phase)
sentry issue list --ask "unresolved errors affecting users"
sentry log list --ask "error logs from payment service"

Architecture

User NL query → Search Agent API → Translated structured query
                                      ├─ Execute via Events API → Render table
                                      ├─ --web → Build Explore URL → Open browser
                                      └─ --json → Output structured results
Strategy → Dataset Mapping
Strategy Dataset Explore Tab Default Fields
traces (default) spans /explore/traces/ span.op, span.description, span.duration, timestamp
logs logs /explore/logs/ timestamp, severity, message, trace
issues N/A (issues endpoint) /issues/ title, events, users, lastSeen
errors spans /explore/traces/ span.op, error type, timestamp
API Flow
  1. Translate: POST /organizations/{org}/search-agent/translate/ (synchronous)

    • Input: { natural_language_query, project_ids[], strategy }
    • Output: { responses: [{ query, group_by, sort, stats_period, mode, visualization }] }
    • Fallback: If 403 → try async start/ + poll state/{run_id}/
  2. Execute: GET /organizations/{org}/events/?dataset=X&field[]=...&query=...

    • Map translated query fields to events API parameters
    • Dynamic field discovery from meta.fields in response
  3. Render: Dynamic table built from response metadata

    • Column types (string, number, date, duration) → automatic alignment + formatting
    • JSON mode: raw response data with --fields filtering

Files to Create

src/types/search-agent.ts — Zod schemas + types
// Schemas for:
// - SearchStrategy enum: "Traces" | "Logs" | "Issues" | "Errors"
// - NLQueryResponse: { query, group_by[], sort, stats_period, mode, visualization[] }
// - NLTranslateResult: { responses[], unsupported_reason? }
// - SearchAgentSession: { run_id, status, current_step, completed_steps, final_response }
// - ExploreResult: { data: Record<string, unknown>[], meta: { fields: Record<string, string> } }
src/lib/api/search-agent.ts — Search Agent API functions
// translateNLQuery(orgSlug, projectIds, query, strategy) → NLTranslateResult
//   POST /organizations/{org}/search-agent/translate/
//   Uses apiRequestToRegion (not in @sentry/api SDK)

// startSearchAgent(orgSlug, projectIds, query, strategy) → { run_id }
//   POST /organizations/{org}/search-agent/start/

// getSearchAgentState(orgSlug, runId) → SearchAgentSession
//   GET /organizations/{org}/search-agent/state/{runId}/

// queryExplore(orgSlug, params) → ExploreResult
//   GET /organizations/{org}/events/?dataset=X&field[]=...
//   Generic events query execution (any dataset)
src/lib/formatters/explore.ts — Dynamic table formatter
// formatExploreTable(result: ExploreResult) → string
//   Builds Column<> definitions dynamically from meta.fields
//   Uses existing formatTable/renderTextTable infrastructure
//   Type-aware alignment (numbers right, strings left)
//   Type-aware value formatting (dates, durations, percentages)

// formatTranslatedQuery(query: NLQueryResponse) → string
//   Human-readable display of the translated query parameters
src/commands/search/index.ts — Route map
// Route with 'search' as default command (single-command route)
// Subcommands can be added later if needed
src/commands/search/search.ts — Main command
// Positional: natural language query string (required)
// Flags:
//   --strategy / -s: "traces" | "logs" | "issues" | "errors" (default: "traces")
//   --web / -w: Open results in browser instead of displaying
//   --limit / -l: Max results (default: 25, max: 100)
//   --json: Machine-readable output
//   --fields: Filter JSON output fields
//   --translate-only: Show translated query without executing (for learning Sentry syntax)
//
// Flow:
// 1. Resolve org + project (DSN auto-detect, explicit org/, env vars)
// 2. Fetch project ID(s) via fetchProjectId()
// 3. Call translateNLQuery() wrapped in withProgress() spinner
// 4. If unsupported_reason → show error with suggestion
// 5. If --translate-only → show translated query + Explore URL
// 6. If --web → buildExploreUrl() + open browser
// 7. Otherwise → execute query via queryExplore() → render dynamic table
// 8. Show Explore URL as hint for all modes
src/lib/sentry-urls.ts — Add buildExploreUrl()
// buildExploreUrl(orgSlug, options: {
//   strategy: string,
//   query?: string,
//   groupBy?: string[],
//   sort?: string,
//   statsPeriod?: string,
//   mode?: string,
//   visualize?: object[],
// }) → string
//
// Maps strategy to path: traces→/explore/traces/, logs→/explore/logs/, issues→/issues/
// Encodes all query parameters matching the Explore page URL format

Files to Modify

src/app.ts
  • Import searchRoute from ./commands/search/index.js
  • Import searchCommand from ./commands/search/search.js
  • Add to routes: search: searchRoute, ask: searchCommand
  • Add to PLURAL_TO_SINGULAR: (none needed — ask is already a leaf command)
src/lib/api-client.ts (barrel)
  • Re-export from ./api/search-agent.js
src/types/index.ts
  • Re-export search-agent types

NL Query → Events API Translation Logic

The search-agent returns:

{
  "query": "span.op:db span.duration:>1s",
  "group_by": ["transaction"],
  "sort": "-count()",
  "stats_period": "24h",
  "mode": "aggregates",
  "visualization": [{"chart_type": 1, "y_axes": ["count()"]}]
}

This maps to events API as:

dataset=spans
field[]=transaction         (from group_by)
field[]=count()             (from visualization y_axes + sort)
query=span.op:db span.duration:>1s
sort=-count()
statsPeriod=24h
per_page=25

Field derivation rules:

  • Aggregate mode: field[] = group_by + unique aggregate functions from visualization[].y_axes and sort
  • Samples mode: field[] = strategy-specific defaults (span.op, span.description, span.duration, timestamp, etc.) since the NL response doesn't explicitly list sample columns
  • For Issues strategy: Don't use events API — use the existing listIssues functions with the translated query

Test Files to Create

test/lib/api/search-agent.test.ts
  • Mock API responses for translate, start, state endpoints
  • Test field derivation from NL response → events API params
  • Test error handling (403 feature flag, 500 Seer unavailable)
test/commands/search/search.test.ts
  • Test full command flow with mocked API
  • Test --translate-only output formatting
  • Test --web opens browser with correct URL
  • Test --json output structure
  • Test strategy → dataset mapping
  • Test dynamic table rendering from explore results
test/lib/formatters/explore.test.ts
  • Test dynamic column generation from meta.fields
  • Test value formatting for each field type
  • Test translated query display formatting

Phase 2 (Future): --ask on Existing Commands

Add --ask flag to issue list, log list, trace list:

  • When --ask is provided with a value, translate the NL query first
  • Replace --query with the translated query string
  • Keep the rest of the command's normal flow
  • This is additive and can be done after the main search command ships

Verification

Manual Testing
# Requires auth + Seer access
bun run --env-file=.env.local src/bin.ts search "show me slow database queries"
bun run --env-file=.env.local src/bin.ts search "errors in production last 24h" --strategy errors
bun run --env-file=.env.local src/bin.ts search "p95 latency by endpoint" --json
bun run --env-file=.env.local src/bin.ts search "log errors from auth service" --strategy logs --web
bun run --env-file=.env.local src/bin.ts ask "which issues affect the most users"
bun run --env-file=.env.local src/bin.ts search "slow queries" --translate-only
Automated Testing
bun test test/commands/search/
bun test test/lib/api/search-agent.test.ts
bun test test/lib/formatters/explore.test.ts
bun run typecheck
bun run lint:fix
Lenguaje dominante
TypeScript
Estrellas
121
Forks
14
Merge medio
23 h 54 min
PR fusionados (30 d)
103

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de getsentry/cli

Todos los issues de getsentry/cli

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.