Skip to content

refactor: convert Tier 2-3 commands to return-based output and consola#394

Merged
BYK merged 4 commits intomainfrom
feat/streaming-output
Mar 11, 2026
Merged

refactor: convert Tier 2-3 commands to return-based output and consola#394
BYK merged 4 commits intomainfrom
feat/streaming-output

Conversation

@BYK
Copy link
Member

@BYK BYK commented Mar 11, 2026

Summary

Continues the output convergence from #382, converting Tier 2-3 commands away from direct stdout.write/stderr.write to either return-based OutputConfig<T> or consola logging.

Changes

Return-based output (OutputConfig<T> with { data, hint? } returns):

  • project/view, log/view — pure formatter functions, structured return values
  • org/list, trace/list — return structured data with human formatters
  • New jsonTransform property on OutputConfig<T> for custom JSON envelopes (used by trace/list for { data, hasMore, nextCursor? } shape)
  • buildListCommand widened to accept OutputConfig alongside "json"

Consola logging (replaces stdout.write/stderr.write):

  • auth/login, auth/logout, auth/statuslogger.withTag("auth.*")
  • cli/feedback, cli/setup, cli/fix, cli/upgradelogger.withTag("cli.*")
  • api.ts — removed stderr: Writer parameter from 4 helper functions

Tests: All updated to spy on process.stderr.write (consola output target) instead of mock context stdout/stderr. 26 files changed.

Not converted (intentional)

  • auth/token — designed for pipe capture (sentry auth token | pbcopy)
  • interactive-login.ts — deeply coupled Writer threading, deferred to separate PR
  • Streaming list commands (issue/list, project/list, log/list) — next PR

@github-actions
Copy link
Contributor

github-actions bot commented Mar 11, 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 ✨

Init

  • Enforce canonical feature display order by betegon in #388
  • Accept multiple delimiter formats for --features flag by betegon in #386
  • Add git safety checks before wizard modifies files by betegon in #379
  • Add experimental warning before wizard runs by betegon in #378
  • Add init command for guided Sentry project setup by betegon in #283

Other

  • (issue-list) Redesign table to match Sentry web UI by BYK in #372
  • Add --dry-run flag to mutating commands by BYK in #387
  • Return-based output with OutputConfig on buildCommand by BYK in #380
  • Add --fields flag for context-window-friendly JSON output by BYK in #373
  • Magic @ selectors (@latest, @most_frequent) for issue commands by BYK in #371
  • Input hardening against agent hallucinations by BYK in #370
  • Add response caching for read-only API calls by BYK in #330

Bug Fixes 🐛

Init

  • Remove implementation detail from help text by betegon in #385
  • Truncate uncommitted file list to first 5 entries by MathurAditya724 in #381

Other

  • (api) Convert --data to query params for GET requests by BYK in #383
  • (docs) Remove double borders and fix column alignment on landing page tables by betegon in #369
  • Add trace ID validation to trace view + UUID dash-stripping by BYK in #375

Internal Changes 🔧

Init

  • Remove --force flag by betegon in #377
  • Remove dead determine-pm step label by betegon in #374

Other

  • Convert Tier 2-3 commands to return-based output and consola by BYK in #394
  • Convert remaining Tier 1 commands to return-based output by BYK in #382
  • Converge Tier 1 commands to writeOutput helper by BYK in #376

Other

  • Minify JSON on read and pretty-print on write in init local ops by MathurAditya724 in #396

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 11, 2026

Codecov Results 📊

104 passed | Total: 104 | 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 99.66%. Project has 901 uncovered lines.
✅ Project coverage is 95.5%. Comparing base (base) to head (head).

Files with missing lines (3)
File Patch % Lines
view.ts 94.03% ⚠️ 12 Missing
output.ts 98.53% ⚠️ 1 Missing
list-command.ts 99.35% ⚠️ 1 Missing
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    95.50%    95.50%        —%
==========================================
  Files          142       142         —
  Lines        20021     20019        -2
  Branches         0         0         —
==========================================
+ Hits         19121     19118        -3
- Misses         900       901        +1
- Partials         0         0         —

Generated by Codecov Action

@BYK BYK marked this pull request as ready for review March 11, 2026 17:32
@BYK BYK force-pushed the feat/streaming-output branch from 8cd4b67 to a9e837a Compare March 11, 2026 17:41
@BYK BYK force-pushed the feat/streaming-output branch from a9e837a to 8dcba68 Compare March 11, 2026 17:49
@BYK BYK force-pushed the feat/streaming-output branch from 8dcba68 to f7f8b0c Compare March 11, 2026 17:57
Copy link
Member Author

@BYK BYK left a comment

Choose a reason for hiding this comment

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

Addressing review comments

@BYK BYK force-pushed the feat/streaming-output branch from f7f8b0c to e861376 Compare March 11, 2026 18:00
Convert remaining non-streaming commands away from direct stdout/stderr
writes, continuing the output convergence started in #382.

Return-based output (OutputConfig<T>):
- project/view, log/view: pure formatter functions, return { data, hint }
- org/list, trace/list: return structured data with human formatters
- Add jsonTransform to OutputConfig for custom JSON envelopes (trace/list)
- Widen buildListCommand to accept OutputConfig alongside "json"

Consola logging:
- auth/login, logout, status: logger.withTag("auth.*"), log.info/success/warn
- cli/feedback, setup, fix, upgrade: logger.withTag("cli.*")
- api.ts: remove stderr: Writer param from 4 helper functions

Infrastructure:
- OutputConfig<T> gains jsonTransform property for envelope wrapping
- ListCommandFunction type allows unknown returns

All tests updated to spy on process.stderr.write (consola target) instead
of mock context stdout/stderr. 26 files changed across src and test.
@BYK BYK force-pushed the feat/streaming-output branch from e861376 to 2e690a8 Compare March 11, 2026 18:07
…ace' test

The test asserted result.not.toContain('[') on raw formatLogRow()
output, but ANSI escape codes contain '[' characters. This caused a
false failure. The adjacent 'handles missing severity' test correctly
used stripAnsi() — this aligns the two tests.
- org/list: show both truncation notice and tip hint when results are
  truncated (was either-or due to else-if)
- cli/setup: rename local quiet-aware `log` to `emit` and module-level
  `cmdLog` to `log` to match the naming convention used by all other
  commands (avoids shadowing confusion)
- trace/list: keep empty-page next-page command inline in hint text
  instead of splitting it across main output and de-emphasized footer
@BYK
Copy link
Member Author

BYK commented Mar 11, 2026

All three BugBot LOW findings addressed in 1e6cfd4:

  1. org/list truncated hint: Changed from else if to a hints[] array joined with newline — both the truncation notice and the tip footer are now shown when the list is truncated.

  2. cli/setup log shadowing: Renamed module-level cmdLog to log (matching every other command) and renamed the local quiet-aware function from log to emit across all 5 helper function signatures and 22 call sites.

  3. trace/list empty-page hint: Moved the next-page command back inline with the empty-page message in the hint field, so it reads: "No traces on this page. Try the next page: sentry trace list --cursor last"

Copy link

@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.

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

Restore hasMore check in formatTraceListHuman so the primary message
says 'No traces on this page.' when more pages exist, consistent with
the hint that suggests the next-page command. Previously, the formatter
always said 'No traces found.' which contradicted the hint.
@BYK BYK merged commit 332e871 into main Mar 11, 2026
22 checks passed
@BYK BYK deleted the feat/streaming-output branch March 11, 2026 19:28
BYK added a commit that referenced this pull request Mar 12, 2026
…wn rendering (#398)

## Summary

Migrate 5 commands from imperative `log.info`/`log.success`/`log.warn`
output to the structured `CommandOutput<T>` return pattern with
dedicated markdown formatters. This is a continuation of the output
convergence work from PR #394.

### Commands migrated

| Command | Data Type | Key Change |
|---------|-----------|------------|
| `auth status` | `AuthStatusData` | Multi-section display (source,
user, token, defaults, verification) → `mdKvTable` + `colorTag` |
| `auth logout` | `LogoutResult` | Not-authenticated / env-token cases
now throw typed errors instead of `log.warn` |
| `cli feedback` | `FeedbackResult` | Telemetry-disabled case throws
`ConfigError` with suggestion |
| `cli fix` | `FixResult` / `FixIssue` | 20+ diagnostic log calls →
structured issues array. Uses `OutputError` for failures (renders data
then exits 1) |
| `cli upgrade` | `UpgradeResult` | Discriminated `ResolveResult` union.
Progress messages kept on stderr; final result returned as data |

### Pattern

Every migrated command follows the same structure:

```ts
// 1. Define data type
export type FooResult = { ... };

// 2. Add output config to buildCommand
output: { json: true, human: formatFooResult },

// 3. Return data from func()
return { data: result };
```

Human formatters in `src/lib/formatters/human.ts` use the shared
markdown helpers (`mdKvTable`, `colorTag`, `safeCodeSpan`,
`renderMarkdown`) for consistent terminal rendering. All commands now
automatically support `--json` and `--fields`.

### What's NOT in this PR

- **`auth login`** — Has an interactive OAuth path that needs raw
`stdout`/`stderr` Writers. Deferred to `buildStreamingCommand()`.
- **List commands** (`issue list`, `project list`, etc.) — Need
streaming infrastructure.
- **`api` command** — Intentionally raw (direct API proxy).
- **Progress `log.info` calls** in `cli/upgrade` — These are transient
status messages on stderr, which is the correct place for them.

### Commands now on return-based `CommandOutput` (19 total)

`api`, `auth/refresh`, `auth/whoami`, `auth/status`, `auth/logout`,
`auth/token`, `cli/feedback`, `cli/fix`, `cli/upgrade`, `issue/explain`,
`issue/plan`, `issue/view`, `event/view`, `log/view`, `trace/view`,
`org/view`, `project/view`, `project/create`, `team/create`

### Test results

917 pass, 0 fail, 30 test files.

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
BYK added a commit that referenced this pull request Mar 12, 2026
…410)

## Summary

Migrate `log/list` non-streaming paths from direct stdout writes to the
return-based `CommandOutput<T>` pattern used by all other list commands.

### Changes

- **New `LogListResult` type**: `{ logs, hint?, traceId? }` — data
structure for non-follow log operations
- **`executeSingleFetch`**: Returns `LogListResult` instead of writing
to stdout
- **`executeTraceSingleFetch`**: Returns `LogListResult` (replaces
`displayTraceLogs` call)
- **`formatLogListHuman`**: Renders logs as formatted table with
trace-ID column awareness
- **`jsonTransformLogList`**: Applies per-element field filtering for
`--fields` flag
- **Output config**: Changed from `"json"` to full
`OutputConfig<LogListResult>`
- **`func()` return type**: `CommandOutput<LogListResult> | void` —
non-follow returns data, follow returns void

### Not changed

- `executeFollowMode`, `FollowConfig`, `writeLogs` — streaming
infrastructure stays as-is (will be migrated with
`buildStreamingCommand`)

### Part of

Phase 6b of the output convergence effort. All list commands now return
data structures for non-streaming paths:
- ✅ org/list, trace/list (PR #394)
- ✅ team/list, repo/list, project/list, issue/list (PR #404)
- ✅ **log/list non-follow (this PR)**
- 🔜 log/list --follow, auth/login (Phase 6c: `buildStreamingCommand`)
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