feat(replay): Add first-class replay querying and inspection#904
Merged
Conversation
Contributor
|
Contributor
Codecov Results 📊✅ 6660 passed | Total: 6660 | Pass Rate: 100% | Execution Time: 0ms 📊 Comparison with Base Branch
All tests are passing successfully. ✅ Patch coverage is 86.17%. Project has 13505 uncovered lines. Files with missing lines (11)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
+ Coverage 76.07% 76.63% +0.56%
==========================================
Files 296 303 +7
Lines 55764 57782 +2018
Branches 0 0 —
==========================================
+ Hits 42421 44277 +1856
- Misses 13343 13505 +162
- Partials 0 0 —Generated by Codecov Action |
Contributor
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 7c4c29b. Configure here.
Add first-class replay commands so users can query replay data directly instead of only\nseeing replay links hanging off issue and event output.\n\nWire the org replay list and detail APIs into a typed client, add replay\nschemas and command output, and surface replay-native hints from event\nview. Regenerate the replay command docs and skill references.\n\nCo-Authored-By: OpenAI Codex <noreply@openai.com>
Align the new replay route with the repo's completion, fragment, and\nformatting expectations so CI can validate it cleanly.\n\nAdd the missing replay command fragment, keep the completion metadata in\nsync with the replay default view route, refactor replay view to satisfy\nlint rules, and regenerate the replay skill reference from the updated\nexamples.\n\nCo-Authored-By: OpenAI Codex <noreply@openai.com>
Accept replay URLs in replay view and harden the replay API layer for archived and mixed-shape payloads. This keeps replay lookup aligned with the existing Sentry URL parsing flow instead of forcing users back to raw IDs. Expose related replays more consistently from events and issues so replay data is easier to discover and chain into replay view from the CLI. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Collapse the replay runtime and output schemas onto shared shape builders so the replay type layer stays readable and consistent as the command surface grows. Add a typed replay event context and remove the ad hoc replay context cast so replay linkage stays explicit in the shared event model. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Add replay-backed explore queries and enrich replay view with recording activity, related issues, and related traces. This gives replay data a fuller command-line workflow instead of stopping at list metadata or web links. Tighten replay sort and field handling to the backend contract, and validate explicit project scoping when users target a replay through org/project syntax. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Make replay field projection request the right backend fields and harden archived replay normalization for nullable releases payloads. Clean up the replay list table headers while extending replay-explore coverage so these regressions stay caught locally. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Extract the replay environment filter parsing into a shared replay helper so replay list and replay explore stay in sync without duplicated flag logic. Keep the cleanup replay-scoped by reusing the existing replay utility module instead of adding a broader command helper layer. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Handle archived replay views that no longer carry project IDs so explicit project scope does not reject valid archived replays. Extract the shared replay duration bucketing into a replay utility to keep list and view formatting aligned. Also preserve undefined event hints when replay-related hint parts are absent so replay-adjacent event output does not emit an empty hint line. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Compare replay explore fields against the replay default field set when building pagination hints so explicit default replay fields do not produce redundant -F flags. Also resolve replay-related issues with an event.id search query instead of a bare event ID so related issue pivots use a structured issue search. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Tighten small replay follow-up details from the latest Bugbot pass by separating the replay hint helper from the usage JSDoc, sorting replay tags explicitly by key, and dropping a redundant replay count_screens type check in explore. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Normalize replay request fields through an explicit helper so replay explore keeps requesting canonical API fields for aliases like url. Anchor replay activity offsets to replay.started_at so the rendered timeline matches the actual session start instead of the first extracted event. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Stop advertising replay detail-only fields through replay explore and separate replay sort handling from event query sorting. This keeps replay field validation aligned with the list API contract and makes replay pagination context use the same validated sort that listReplays receives. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Keep replay convenience columns like url, screen, and release as first-class CLI fields instead of treating them as canonical aliases. This preserves the scalar explore output while making replay request-field normalization explicit and less confusing. Add focused coverage for convenience-field request roots and the default replay explore field set so the bugbot regression stays closed. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Reject replay-shaped URLs that do not contain a 32-character hex replay ID instead of falling back to generic organization parsing. This keeps malformed replay links from surfacing confusing downstream validation errors. Add parser coverage for malformed replay paths on org-scoped and subdomain SaaS URLs. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Reject malformed replay-shaped URLs during Sentry URL parsing instead of falling back to generic organization matches. Also treat -started_at as the replay dataset's default sort when building explore pagination hints so default navigation output stays compact. Keep the parser under the repo's complexity limit by extracting the subdomain tail-path matcher, and add focused replay URL and explore hint coverage. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Let replay listing pages fall back to org-scoped URL parsing while still rejecting malformed replay detail URLs. This keeps replay URL lookup strict for view commands without breaking org extraction from replay listing links on both /organizations and subdomain URL shapes. Use a status-based replay path matcher so the parser can distinguish listing, detail, invalid, and absent replay paths without duplicating replay prefix checks. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Derive replay list hint rendering from LIST_PERIOD_FLAG.default so pagination commands cannot drift from the actual flag default. This keeps replay list behavior aligned with the shared list-command contract even if the default period changes later. Add focused coverage for next-page hints so the shared default period stays omitted unless the user explicitly overrides it. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Wrap the new replay listing URL expectation the way Ultracite expects so the replay follow-up commits stay green in CI. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Normalize org/replay shorthand IDs before replay view uses them so dashed replay IDs keep working through the CLI shorthand forms. Make replay-backed explore queries and replay list requests pass the same explicit filters and field sets the command layer already knows about. That keeps replay target scoping consistent across list and explore and makes the replay API usage less implicit. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Normalize replay IDs as soon as they are parsed from replay URLs so all replay entry paths use the same canonical lowercase ID. Keep the replay list field contract aligned with the schema by requesting ota_updates in the default replay list field set. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Make replay view fail fast when users pass more than the supported target and replay ID positional arguments instead of silently dropping trailing args. Normalize swapped replay IDs before returning them from positional parsing so every replay view entry path stays consistent. Co-Authored-By: OpenAI Codex <noreply@openai.com>
…ilities - Delete src/lib/replay-duration.ts: move formatDurationCompact, formatDurationVerbose, and formatDurationCompactMs to src/lib/formatters/time-utils.ts where other duration helpers live. - Delete src/lib/replay-id.ts: add tryNormalizeHexId to hex-id.ts (non-throwing variant), move getReplayIdFromEvent and collectReplayIds to replay-search.ts (replay domain logic). - Replace local formatRelativeOffset in replay/view.ts with the shared formatDurationCompactMs from time-utils.ts. - Fix event/view.ts replayHint reference to undefined 'event' variable introduced during merge conflict resolution (use fetchedEvents[0]).
- Extract replay formatting logic from replay/view.ts (950 lines) into a dedicated src/lib/formatters/replay.ts module, bringing view.ts down to ~425 lines focused on argument parsing and API orchestration. - Replace this.stderr.write() with structured logger (consola) per repo conventions. Add diagnostic logging to silent catch blocks. - Document normalizeReplayProjectId coercion and empty-string project slug in org-wide issue search. - Add explanatory comment for parseSingleArg's org/hex-id special case.
- Fix explore replay query double-filtering: skip buildProjectQuery for replays dataset since the replay API uses projectSlugs param. - Merge consecutive JSDoc blocks in event/view.ts (tools only pick up the last block when two JSDoc comments are adjacent).
…Config Replace 7 scattered `dataset === "replays"` branches in the explore command's func body with a single resolveDatasetConfig() function that returns a DatasetConfig with sort, query, and fetch properties. The func body now reads linearly: resolve target → build fields → resolve dataset config → paginate → fetch → yield output. All replay- specific logic (field validation, sort resolution, query building, API dispatch) is centralized in one place.
BYK
added a commit
that referenced
this pull request
May 2, 2026
) ## Summary Adds automated enforcement and documentation for patterns that fell through existing checks during PR #904 review. ## Changes ### Automated Enforcement - **New GritQL rule** (`no-stderr-write-in-commands.grit`): Bans `stderr.write()` in `src/commands/**`. Complements the existing `no-stdout-write-in-commands.grit` rule. Commands should use `logger.withTag()` for warnings and `log.debug()` for diagnostics. - **Fix existing violation** in `issue/merge.ts`: The `--into` preference warning now uses `log.warn()` instead of `this.stderr.write()`. ### Documentation (AGENTS.md) Four new sections addressing gaps identified during PR #904 review: 1. **Catch Block Logging** — Prohibits silent `catch` blocks in production code. Every catch must re-throw, log with `log.debug()`/`log.warn()`, or include a fallback with logging. 2. **Command File Structure** — Commands should focus on arg parsing, API orchestration, and output dispatch. Extract formatting into `src/lib/formatters/<domain>.ts` when files exceed ~400 lines. 3. **Adding New Utility Files** — Lookup table of existing shared modules to check before creating new utility files (duration formatting, hex ID validation, pagination, etc.). Prevents accidental duplication. 4. **Project Filtering in API Calls** — Documents that different API endpoints use different project filtering mechanisms (`buildProjectQuery` vs `projectSlugs` vs `project` parameter). Prevents double-filtering bugs.
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.

Add first-class replay querying and inspection to the CLI so Session Replay can be listed, searched, and inspected without falling back to
issue view,event view, or rawsentry apicalls. Replay now has dedicated commands, replay-awareexplorequeries, and richer CLI-native pivots into related issues and traces.Replay Commands
replay listandreplay viewnow use typed replay APIs and schemas, accept canonical and legacy replay URLs, honor explicit project scope, and normalize archived or mixed-shape payload quirks so replay output stays stable across old rows.Before, replay access was mostly indirect:
After, replay has first-class CLI entry points:
Replay Search and Inspection
explore --dataset replaysnow routes through the replay index with replay-native field mapping, sort validation, and environment filters.replay viewalso goes beyond top-level metadata by fetching recording segments for a compact Activity section and resolving related issues and traces from replay-linked IDs.Issue and Event Handoff
event viewresolves replay IDs from replay tags and replay context, andissue viewcalls the replay-count endpoint to expose deduplicated related replay IDs in both human and JSON output. That keeps replay as a chainable CLI workflow instead of a dead-end web link.Shared Utility Consolidation
Duration formatting (
formatDurationCompact,formatDurationVerbose,formatDurationCompactMs) consolidated intosrc/lib/formatters/time-utils.ts. Replay ID normalization (tryNormalizeHexId) moved tosrc/lib/hex-id.ts. Replay-specific domain helpers (getReplayIdFromEvent,collectReplayIds) moved tosrc/lib/replay-search.ts. Replay formatting logic extracted intosrc/lib/formatters/replay.ts. Theexplorecommand's replay dataset branching centralized into aresolveDatasetConfigstrategy to eliminate scatteredif (dataset === "replays")checks from the main function body.