Skip to content

Commit b22cbd3

Browse files
committed
Fix empty success output and TTY-aware terminal styling
Stop fabricating {"data":{"ok":true}} for empty API responses; emit null on the JSON path and silence on the human TTY path instead. Gate chalk styling on the relevant stream isTTY so ANSI codes do not leak into piped stderr/stdout.
1 parent 34fcf3c commit b22cbd3

3 files changed

Lines changed: 23 additions & 11 deletions

File tree

src/run.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ describe('runOperation', () => {
198198

199199
expect(fetchMock).toHaveBeenCalledOnce();
200200
expect(fetchMock.mock.calls[0][1]).toMatchObject({ method: 'DELETE' });
201+
expect(logSpy).toHaveBeenCalledWith('null');
201202
});
202203

203204
it('passes --dry-run through to the server when supported', async () => {

src/run.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ export function deleteGateDecision(options: {
4141
return options.isTTY ? 'confirm' : 'block';
4242
}
4343

44-
const SYNTHETIC_OK = { data: { ok: true } };
45-
4644
async function ensureDeleteAllowed(
4745
operation: CliOperation,
4846
flags: Record<string, FlagValue>,
@@ -105,21 +103,27 @@ export async function runOperation(
105103
);
106104
}
107105

108-
const payload = parsed ?? SYNTHETIC_OK;
109106
const isTTY = Boolean(process.stdout.isTTY);
110107
const useJson = shouldUseJsonOutput({
111108
jsonFlag: isFlagEnabled(flags.json),
112109
isTTY,
113110
});
114111

112+
if (parsed === null) {
113+
if (useJson) {
114+
console.log(isTTY ? JSON.stringify(null, null, 2) : 'null');
115+
}
116+
return;
117+
}
118+
115119
// When piped or non-interactive (the path agents and scripts take), emit
116120
// compact JSON to avoid spending tokens on indentation. Pretty-print only
117121
// when a human asked for JSON at a real terminal.
118122
let output: string;
119123
if (useJson) {
120-
output = isTTY ? JSON.stringify(payload, null, 2) : JSON.stringify(payload);
124+
output = isTTY ? JSON.stringify(parsed, null, 2) : JSON.stringify(parsed);
121125
} else {
122-
output = formatSuccessOutput(payload, operation);
126+
output = formatSuccessOutput(parsed, operation);
123127
}
124128

125129
console.log(output);

src/terminal.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
import chalk from 'chalk';
22

3+
function ttyAware(
4+
isEnabled: () => boolean,
5+
style: (text: string) => string,
6+
): (text: string) => string {
7+
return (text: string) => (isEnabled() ? style(text) : text);
8+
}
9+
310
export const terminal = {
4-
command: chalk.cyan,
5-
dim: chalk.dim,
6-
error: chalk.red,
7-
heading: chalk.bold,
8-
success: chalk.green,
9-
warning: chalk.yellow,
11+
command: ttyAware(() => Boolean(process.stdout.isTTY), chalk.cyan),
12+
dim: ttyAware(() => Boolean(process.stdout.isTTY), chalk.dim),
13+
error: ttyAware(() => Boolean(process.stderr.isTTY), chalk.red),
14+
heading: ttyAware(() => Boolean(process.stdout.isTTY), chalk.bold),
15+
success: ttyAware(() => Boolean(process.stdout.isTTY), chalk.green),
16+
warning: ttyAware(() => Boolean(process.stdout.isTTY), chalk.yellow),
1017
};

0 commit comments

Comments
 (0)