Skip to content

fix: make piped output human-readable instead of raw CommonMark#462

Merged
BYK merged 6 commits intomainfrom
fix/plain-output-human-readable
Mar 18, 2026
Merged

fix: make piped output human-readable instead of raw CommonMark#462
BYK merged 6 commits intomainfrom
fix/plain-output-human-readable

Conversation

@BYK
Copy link
Copy Markdown
Member

@BYK BYK commented Mar 18, 2026

Problem

When piping sentry output to less or other programs, the output was either:

  1. Raw ANSI escape codes when FORCE_COLOR=1 is set (common in VS Code terminals)
  2. Raw CommonMark syntax (| --- |, **bold**, [link](url)) — unreadable in a pager

Solution

FORCE_COLOR fix

isPlainOutput() now ignores FORCE_COLOR when stdout is piped (not a TTY). Users who want color in pipes can use SENTRY_PLAIN_OUTPUT=0.

Plain output is now human-readable

Instead of raw CommonMark, plain mode now renders structured, readable text:

  • renderMarkdown() — parses markdown → renders with formatting (headings, aligned tables, lists) → strips ANSI
  • formatTable() — uses renderTextTable() with box-drawing borders instead of CommonMark pipe syntax
  • renderInlineMarkdown() — strips markdown syntax (**bold**bold, [text](url)text, \code`code`)
  • terminalLink() — returns plain text (no OSC 8 sequences) when piped
  • Footer/hints — use plainSafeMuted() to skip ANSI when piped

Architecture

isPlainOutput() extracted to src/lib/formatters/plain-detect.ts to avoid circular dependency between markdown.ts and colors.ts. Re-exported from markdown.ts for backward compatibility.

Before / After

Before (piped to less):

| SHORT ID | ISSUE | SEEN | AGE |
| --- | --- | --- | --- |
| [CLI-3B](https://sentry.io/...) | **ContextError: Org required.** |

After:

╭──────────┬───────────────────────────┬───────┬────────╮
│ SHORT ID │ ISSUE                     │ SEEN  │ AGE    │
├──────────┼───────────────────────────┼───────┼────────┤
│ CLI-3B   │ ContextError: Org required│ 3m    │ Feb 6  │
╰──────────┴───────────────────────────┴───────┴────────╯

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 18, 2026

Semver Impact of This PR

🟢 Patch (bug fixes)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

  • (span) Make span list dual-mode and add --period flag by BYK in #461
  • Refactor SKILL.md into modular reference files by BYK in #458

Bug Fixes 🐛

  • (test) Use os.tmpdir() for test temp directories by BYK in #457
  • Make piped output human-readable instead of raw CommonMark by BYK in #462
  • Clean up upgrade output and hide empty table headers by BYK in #459
  • Improve error messages — fix ContextError/ResolutionError misuse by BYK in #456

Internal Changes 🔧

  • (list) Align all list commands to issue list standards by BYK in #453

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 18, 2026

Codecov Results 📊

116 passed | Total: 116 | Pass Rate: 100% | Execution Time: 0ms

📊 Comparison with Base Branch

Metric Change
Total Tests
Passed Tests
Failed Tests
Skipped Tests

✨ No test changes detected

All tests are passing successfully.

✅ Patch coverage is 100.00%. Project has 1130 uncovered lines.
✅ Project coverage is 95.3%. Comparing base (base) to head (head).

Files with missing lines (4)
File Patch % Lines
human.ts 96.35% ⚠️ 46 Missing
markdown.ts 92.16% ⚠️ 25 Missing
trace.ts 93.18% ⚠️ 18 Missing
colors.ts 98.44% ⚠️ 1 Missing
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    95.20%    95.30%     +0.1%
==========================================
  Files          176       177        +1
  Lines        24063     24067        +4
  Branches         0         0         —
==========================================
+ Hits         22907     22937       +30
- Misses        1156      1130       -26
- Partials         0         0         —

Generated by Codecov Action

@BYK BYK marked this pull request as ready for review March 18, 2026 18:43
BYK added 6 commits March 18, 2026 20:09
Two problems are fixed:

1. FORCE_COLOR leaking ANSI to pipes: When FORCE_COLOR=1 is set (common
   in VS Code terminals), ANSI escape codes leaked through to less/cat
   because isPlainOutput() treated FORCE_COLOR as higher priority than
   TTY detection. Now FORCE_COLOR only applies when stdout IS a TTY.
   Users who truly want color in pipes can use SENTRY_PLAIN_OUTPUT=0.

2. Plain mode outputs raw CommonMark: When piped, the CLI produced raw
   markdown syntax (| --- |, **bold**, [link](url), `code`) which is
   unreadable in a pager. Now plain mode:
   - renderMarkdown() parses and renders to structured plain text
     (headings, aligned tables, blockquote indentation) then strips ANSI
   - formatTable() uses renderTextTable() with box-drawing borders
     instead of buildMarkdownTable() with raw CommonMark syntax
   - renderInlineMarkdown() strips markdown syntax via stripMarkdownInline()
   - terminalLink() returns plain text (no OSC 8 sequences) when piped
   - divider() and footer/hint text use plainSafeMuted() to avoid ANSI

Architecture: isPlainOutput() extracted to plain-detect.ts to avoid
circular dependency between markdown.ts and colors.ts. Re-exported from
markdown.ts for backward compatibility.
Address BugBot review: formatLogTable and formatTraceTable were still
using mdRow + mdTableHeader (pipe-delimited markdown) in plain mode
instead of renderTextTable with box-drawing borders. Now consistent
with formatTable.
…uted

- stripMarkdownInline() now unescapes markdown backslash escapes (\|,
  \<, \>, \, \_, \*, \[, \]) so plain output shows literal characters
  instead of escaped ones. Addresses Seer review.
- mdRow() replaces literal | with box-drawing │ after stripping to
  prevent breaking pipe-delimited table format.
- Export plainSafeMuted() from human.ts and reuse in output.ts instead
  of duplicating. Addresses BugBot review.
…ore stripping

- formatTraceTable: pass alignments to renderTextTable in plain mode
  so Duration column is right-aligned consistently. Addresses Seer review.
- stripMarkdownInline: remove _{1,2} regex that could corrupt identifiers
  containing underscores (e.g. payment_service_handler). Backslash-escaped
  underscores (\_) are already handled by the unescape step.
Code spans have higher precedence than emphasis in CommonMark. Process
backtick code spans first so that bold markers inside code spans (e.g.
`**text**`) are preserved as literal asterisks. Addresses BugBot review.
…rip-ANSI

Eliminate the entire stripMarkdownInline() function and its accumulated
edge-case bugs (code span precedence, underscore corruption, backslash
escapes). Instead, reuse the existing marked.lexer() → renderInline()
pipeline for both TTY and plain modes, stripping ANSI from the result
in plain mode — the same approach renderMarkdown() already uses.

Key changes:
- renderInlineMarkdown(): always renders through marked, strips ANSI in
  plain mode instead of calling stripMarkdownInline()
- renderCodespan(): extracted helper; skips padding spaces in plain mode
  so table column widths aren't inflated
- formatTable/formatTraceTable/formatLogTable: merged TTY and plain
  branches into a single renderInlineMarkdown() call
- mdRow(): same — single code path for both modes
- Deleted stripMarkdownInline() entirely
@BYK BYK force-pushed the fix/plain-output-human-readable branch from bc87d07 to f4a7bfd Compare March 18, 2026 20:12
Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

@BYK BYK merged commit f2fead1 into main Mar 18, 2026
22 checks passed
@BYK BYK deleted the fix/plain-output-human-readable branch March 18, 2026 20:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant