refactor: converge Tier 1 commands to writeOutput helper#376
Merged
Conversation
Contributor
Semver Impact of This PR🟢 Patch (bug fixes) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨
Bug Fixes 🐛
Internal Changes 🔧Init
Other
🤖 This preview updates automatically when you update the PR. |
f5f6ab3 to
c42840e
Compare
Enhance writeOutput with footer and jsonData options, migrate auth/whoami, auth/refresh, and issue/explain to use it. - footer: muted hint after human output, suppressed in JSON mode - jsonData: separate JSON data when shapes diverge from human formatter - 16 new tests in test/lib/formatters/output.test.ts
c42840e to
8127a48
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 898 uncovered lines. Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
+ Coverage 95.45% 95.46% +0.01%
==========================================
Files 141 141 —
Lines 19768 19758 -10
Branches 0 0 —
==========================================
+ Hits 18868 18860 -8
- Misses 900 898 -2
- Partials 0 0 —Generated by Codecov Action |
BYK
added a commit
that referenced
this pull request
Mar 10, 2026
## Summary Phase 3 of the output convergence plan ([Phase 1: #373](#373), [Phase 2: #376](#376)). Commands can now declare an `OutputConfig` on `buildCommand` and return bare data from `func`. The wrapper intercepts the return value and renders automatically — selecting human vs JSON format based on `--json`, applying `--fields` filtering, and writing to stdout. Runtime hints like detection source or next-step footers use `[data, { hint }]` tuples. ### What changed **Core infrastructure** (`src/lib/formatters/output.ts`, `src/lib/command.ts`): - `OutputConfig<T>` — declared on `buildCommand` with `human` formatter - `OutputMeta` — runtime hints (`{ hint?: string }`) returned via tuple - `renderCommandOutput()` — renders data using config + merged runtime context - `buildCommand` `output` field accepts two forms: - `"json"` (string) — flag injection only (`--json`, `--fields`) - `{ json: true, human: fn }` — flag injection + auto-render - Detects bare data vs `[data, meta]` tuple returns; `void`/`Error` returns are ignored - Renamed `detectedFrom` → `hint` throughout the output layer (callers compose full message) **4 Category A commands migrated** to return-based pattern: - `auth/whoami` — `return user` - `auth/refresh` — `return payload` with `formatRefreshResult` in config - `issue/explain` — `return [causes, { hint }]` for next-step footer - `org/view` — `return [org, { hint }]` for detection source, or bare `org` **jsonData eliminated** — single canonical data object for both JSON and human renderers. The `--fields` flag handles field selection for context-window-friendly output. **JSON shapes normalized** for consistent `jq` ergonomics: - `issue/view` — always includes `event: null` instead of omitting the key - `log/view` — always emits array (was single object for single ID) - `project/view` — always emits array (was single object for single project) **Removed** (replaced by simpler pattern): - `OutputResult<T, J>` branded type - `output()` helper function - `isOutputResult()` / `renderOutputResult()` functions - `WriteOutputDivergentOptions<T, J>` type and `jsonData` from all output APIs **Tests**: All assertions updated for new shapes. Zero regressions (260 pre-existing failures on main, same on branch). ### Design decisions - **Two-form output**: `"json"` for flag-only injection (most commands), `OutputConfig` for full auto-render (4 migrated commands). No breaking changes to existing `output: "json"` commands. - **Bare return, not branded wrapper**: Commands return plain data instead of `output(data, opts)`. Simpler, less ceremony, no brand symbol machinery. - **`[data, { hint }]` for runtime context**: Hints depend on execution-time values (resolved issue arg, detection source). Declared at return time, not build time. - **`hint` replaces `detectedFrom` + `footer`**: Single generic field. Callers compose the full text. - **No jsonData**: One data shape for both human and JSON renderers. Use `--fields` to control what appears in JSON output. - **Always-array JSON**: Commands that return data return arrays even for single results, for consistent `jq` pipelines. - **Complex commands deferred**: event/view, trace/view, project/create, issue/plan have `--web`, polling, stderr progress, etc. These need a more advanced pattern (likely `buildStreamingCommand` variant) in follow-up PRs. ### Stats 14 files changed, 756 insertions, 305 deletions
BYK
added a commit
that referenced
this pull request
Mar 10, 2026
Convert event view, issue view, issue plan, project create, and trace
view to the new return-based output pattern where commands return
{data} and the framework handles JSON serialization and human
formatting.
Each command now declares an output config with json: true and a human
formatter function, replacing manual stdout.write + writeJson calls.
Changes:
- event/view: extract buildEventData + formatEventOutput
- issue/view: extract buildIssueData + formatIssueOutput
- issue/plan: extract buildPlanData + formatPlanOutput, remove
outputSolution helper
- project/create: extract formatProjectCreateOutput
- trace/view: extract buildTraceData + formatTraceOutput
Infrastructure:
- Add OutputResult type export from lib/command.ts
- Add writeHuman helper to formatters/output.ts for consistent
newline-terminated human output
- Update tests to match new return signatures
Part of the output convergence plan (PR sequence #373→#376→#380).
BYK
added a commit
that referenced
this pull request
Mar 10, 2026
) ## Summary Convert 5 remaining Tier 1 commands to the return-based `CommandOutput<T>` pattern introduced in #380. Each command now returns `{ data, hint?, footer? }` and declares an `OutputConfig` with `json: true` and a `human` formatter — the framework handles JSON serialization and human-readable rendering. ## Commands converted | Command | Human formatter | Return shape | |---------|----------------|-------------| | `event/view` | `formatEventView()` | `{ data: { event, trace, spanTreeLines }, hint }` | | `issue/view` | `formatIssueView()` | `{ data: { issue, event, trace, spanTreeLines }, footer }` | | `issue/plan` | `formatPlanOutput()` | `{ data: { run_id, status, solution } }` | | `project/create` | `formatProjectCreated()` | `{ data: ProjectCreatedResult }` | | `trace/view` | `formatTraceView()` | `{ data: { summary, spans, spanTreeLines }, footer }` | ## Infrastructure changes - Added `footer?: string` to `CommandOutput<T>` and `RenderContext` - `renderCommandOutput()` now renders footer via `writeFooter()` - `handleReturnValue` in `command.ts` passes `value.footer` through ## What was removed - `writeHumanOutput()` from trace/view (replaced by `formatTraceView`) - `outputSolution()` from issue/plan (replaced by `formatPlanOutput` + `buildPlanData`) - Manual `writeJson`/`writeFooter`/`stdout.write` calls from all 5 commands - `Writer` type imports (no longer needed) ## Test updates - `test/commands/trace/view.func.test.ts`: `writeHumanOutput` tests replaced with `formatTraceView` pure function tests - `test/commands/project/create.test.ts`: `parsed.slug` → `parsed.project.slug` (JSON shape now uses full `ProjectCreatedResult`) Net: **-33 lines** (188 insertions, 221 deletions) Part of the output convergence plan: #373 → #376 → #380 → this PR
5 tasks
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.
Phase 2:
writeOutputconvergenceBuilds on #373 (
output: "json"centralization).Enhance
writeOutputwith two new options and migrate 3 Tier 1 commands to use it.New options on
writeOutputfooter?: string— muted hint after human output, suppressed in JSON mode. Replaces separatewriteFooter()calls.jsonData?: J— separate data object for JSON when the serialized shape differs from the human formatter's input.Commands migrated
auth/whoamijsonDatanarrows user to{id, name, username, email}for JSONauth/refreshformatHumanreplaces 3-branch if/elseissue/explainfooterreplaces separatewriteFooter()callCommands with multi-part output or divergent data assembly (
issue/view,event/view,trace/view,project/create,log/view) are intentionally left as-is — they don't fit the single-formatter pattern.Tests
16 new tests in
test/lib/formatters/output.test.tscover JSON mode, human mode, footer, detectedFrom, and jsonData divergence.