Skip to content

Commit 1b12b53

Browse files
committed
fix: address review findings from BugBot and Seer
1. formatTraceLogs: add trailing newline to JSON output (log.ts) 2. output.ts: fix orphaned JSDoc — move writeFooter docs to writeFooter, leave formatFooter with its own one-liner 3. jsonTransformLogOutput: return [] for empty single-fetch, undefined only for empty follow-mode batches (log/list.ts) 4. finalize: remove extra trailing newline after formatFooter (log/list.ts) 5. command.ts: move writeFinalization to finally block so streaming table footer is written even on mid-stream errors 6. trial/start.ts: check isatty(2) instead of isatty(1) since prompts display on stderr after migration
1 parent ac92ad7 commit 1b12b53

File tree

5 files changed

+18
-15
lines changed

5 files changed

+18
-15
lines changed

src/commands/log/list.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ function createLogRenderer(): HumanRenderer<LogListResult> {
462462

463463
// Append hint (count, pagination, empty-state message)
464464
if (hint) {
465-
text += `${text ? "\n" : ""}${formatFooter(hint)}\n`;
465+
text += `${text ? "\n" : ""}${formatFooter(hint)}`;
466466
}
467467

468468
return text;
@@ -485,7 +485,9 @@ function jsonTransformLogOutput(
485485
fields && fields.length > 0 ? filterFields(log, fields) : log;
486486

487487
if (result.logs.length === 0) {
488-
return;
488+
// Follow mode: suppress empty batches (no JSONL output)
489+
// Single-fetch: return empty array for valid JSON
490+
return result.jsonl ? undefined : [];
489491
}
490492

491493
const mapped = result.logs.map(applyFields);

src/commands/trial/start.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,8 @@ async function promptOpenBillingUrl(url: string): Promise<boolean> {
191191
const qr = await generateQRCode(url);
192192
log.log(qr);
193193

194-
// Prompt to open browser if interactive TTY
195-
if (isatty(0) && isatty(1)) {
194+
// Prompt to open browser if interactive TTY (stdin for input, stderr for display)
195+
if (isatty(0) && isatty(2)) {
196196
const confirmed = await log.prompt("Open in browser?", {
197197
type: "confirm",
198198
initial: true,

src/lib/command.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ export function buildCommand<
462462
// Iterate the generator using manual .next() instead of for-await-of
463463
// so we can capture the return value (done: true result). The return
464464
// value carries the final `hint` — for-await-of discards it.
465+
let hint: string | undefined;
465466
try {
466467
const generator = originalFunc.call(
467468
this,
@@ -474,12 +475,15 @@ export function buildCommand<
474475
result = await generator.next();
475476
}
476477

477-
// Finalize: let the renderer close streaming state (e.g., table
478-
// footer), or fall back to the default writeFooter for the hint.
479478
const returned = result.value as CommandReturn | undefined;
480-
writeFinalization(stdout, returned?.hint, cleanFlags.json, renderer);
479+
hint = returned?.hint;
481480
} catch (err) {
482481
handleOutputError(err);
482+
} finally {
483+
// Always finalize: close streaming state (e.g., table footer)
484+
// even if the generator threw. Without this, a mid-stream error
485+
// leaves partial output (e.g., table without bottom border).
486+
writeFinalization(stdout, hint, cleanFlags.json, renderer);
483487
}
484488
};
485489

src/lib/formatters/log.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ export function formatTraceLogs(options: FormatTraceLogsOptions): string {
349349

350350
if (asJson) {
351351
const reversed = [...logs].reverse();
352-
return formatJson(fields ? filterFields(reversed, fields) : reversed);
352+
return `${formatJson(fields ? filterFields(reversed, fields) : reversed)}\n`;
353353
}
354354

355355
if (logs.length === 0) {

src/lib/formatters/output.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -419,18 +419,15 @@ export function writeOutput<T>(
419419
}
420420
}
421421

422-
/**
423-
* Write a formatted footer hint to stdout.
424-
* Adds empty line separator and applies muted styling.
425-
*
426-
* @param stdout - Writer to output to
427-
* @param text - Footer text to display
428-
*/
429422
/** Format footer text (muted, with surrounding newlines). */
430423
export function formatFooter(text: string): string {
431424
return `\n${muted(text)}\n`;
432425
}
433426

427+
/**
428+
* Write a formatted footer hint to stdout.
429+
* Adds empty line separator and applies muted styling.
430+
*/
434431
export function writeFooter(stdout: Writer, text: string): void {
435432
stdout.write(formatFooter(text));
436433
}

0 commit comments

Comments
 (0)