fix: show human-friendly names in trial list and surface plan trials#412
Merged
fix: show human-friendly names in trial list and surface plan trials#412
Conversation
Contributor
Semver Impact of This PR🟢 Patch (bug fixes) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨Init
Issue List
Other
Bug Fixes 🐛Init
Other
Internal Changes 🔧Init
Other
Other
🤖 This preview updates automatically when you update the PR. |
Three issues fixed: 1. Missing category mappings: API categories like monitorSeats, uptime, and profileDurationUI were not in the TRIAL_NAMES map, so they showed raw camelCase API names in both the NAME and PRODUCT columns. Added mappings for monitors, uptime, and profileDurationUI → profiling. 2. Poor fallback for unknown categories: When an API returns a category not in the map, getTrialDisplayName now uses humanizeCategory() to convert camelCase to title case (e.g., 'fooBar' → 'Foo Bar') and getTrialFriendlyName uses kebab-case (e.g., 'fooBar' → 'foo-bar') instead of showing the raw API string. 3. Plan-level trials not surfaced: Organizations on free/Developer plans with canTrial=true (eligible for a Business plan trial) saw 'No trials found' because the CLI only showed product trials. Now fetches full customer trial info via getCustomerTrialInfo() and synthesizes a 'plan' entry when canTrial or isTrial is true, with a hint linking to the billing page.
The human table now shows one 'TRIAL' column with the display name instead of three redundant columns (NAME, PRODUCT, CATEGORY). The name and category fields are still available in --json output for scripting.
Product trials now show 'Profiling (profiling)' so users know the exact argument for 'sentry trial start <name>'. Plan trial entries skip the parenthetical since they aren't startable via CLI.
When users run 'sentry trial start plan', the CLI: 1. Checks canTrial/isTrial eligibility via the customer API 2. Shows the billing URL and a QR code (for mobile/remote) 3. Prompts to open the browser (if interactive TTY) 4. Returns JSON with url/opened fields in --json mode This fills the gap where plan-level trials have no API endpoint and must be activated through the Sentry billing UI.
Multiple API categories can map to one trial name (e.g., both profileDuration and profileDurationUI → profiling). Without deduplication, the table showed duplicate rows. The deduplicateTrials() function groups by CLI name and keeps the best entry: active > available > expired, with latest end date as tiebreaker.
- Replace → with -> in the TRIAL column to avoid multi-byte rendering issues where the arrow eats into column padding - Show (plan) in parentheses like product trials so users learn the sentry trial start <name> argument - Change hint from billing URL to 'sentry trial start plan'
Pass the usage example with placeholder as the command arg
(e.g., 'sentry trial list <org>') instead of the bare command.
Use default alternatives (DSN detection, SENTRY_ORG env var)
instead of overriding with just the positional syntax.
Before:
Organization is required.
Specify it using:
sentry trial list
Or:
- sentry trial list <org>
After:
Organization is required.
Specify it using:
sentry trial list <org>
Or:
- Run from a directory with a Sentry-configured project
- Set SENTRY_ORG and SENTRY_PROJECT (or SENTRY_DSN) environment variables
- Fix swap detection for "plan" pseudo-trial: `sentry trial start my-org plan` now correctly auto-corrects to `sentry trial start plan my-org` instead of giving a confusing "Unknown trial name" error - Deduplicate getProductTrials to delegate to getCustomerTrialInfo instead of making its own identical API call - Add test for plan argument swap detection
7d1263b to
7655417
Compare
Contributor
Codecov Results 📊✅ 104 passed | Total: 104 | 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 696 uncovered lines. Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
+ Coverage 96.66% 96.69% +0.03%
==========================================
Files 159 159 —
Lines 20855 21011 +156
Branches 0 0 —
==========================================
+ Hits 20158 20315 +157
- Misses 697 696 -1
- Partials 0 0 —Generated by Codecov Action |
- Use `info.canTrial === false` instead of `!info.canTrial` so undefined (API omitted the field) does not incorrectly block plan trial activation - Extract daysRemainingFromDate() shared helper in trials.ts, reuse in both getDaysRemaining() and buildPlanTrialEntry() to eliminate duplicate end-of-day UTC date math
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.
…cy with list.ts Both commands now treat undefined canTrial conservatively: list.ts does not show a plan trial row, start.ts rejects the attempt. This avoids user confusion where "sentry trial start plan" succeeds but "sentry trial list" shows no plan trial option.
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
Improves the
sentry trial listandsentry trial startcommands with human-friendly names, plan trial visibility, deduplication, and better error messages.Changes
Human-friendly trial names
monitorSeats→ "Cron Monitors",uptime→ "Uptime Monitoring"profileDurationUIto existingprofilingmappinghumanizeCategory()fallback that converts unknown camelCase categories to "Title Case"kebabize()fallback for CLI-friendly namesPlan trial surfacing
getCustomerTrialInfo()API function returns plan trial data (canTrial,isTrial,trialEnd,planDetails)trial listwith status "Available" or "Active"Tip: Use 'sentry trial start plan' to start a Business plan trialsentry trial start plancanTrial/isTrialbefore prompting--jsonmodeSimplified table format
Profiling (profiling)--json)Developer -> Business (plan) | ○ Available | —Deduplication
profileDurationandprofileDurationUI, both mapping to CLI name "profiling"deduplicateTrials()groups by CLI name, keeps best entry (active > available > expired, latest endDate wins)Better error messages
ContextErrornow shows usage with placeholder:sentry trial list <org>instead of baresentry trial listSENTRY_ORGenv var) shown instead of being overriddenTest coverage
89 tests passing across 3 files (154 assertions):
test/lib/trials.test.ts— unit tests for name mappings, humanization, kebabizationtest/commands/trial/list.test.ts— plan trial entries, deduplication, table formattingtest/commands/trial/start.test.ts— plan trial flow, eligibility checks, JSON modeRelated