mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-27 22:15:33 +00:00
* feat(eval): cycle-default — single source of truth for TTY/non-TTY cycle count (#1784) * fix(jobs): decouple 'jobs watch' format (--json) from loop (--follow); non-TTY prints one human snapshot (#1784) * fix(reindex): human cost-refusal unless --json; spend guardrail unchanged (#1784) * fix(eval): annotate non-interactive cycle/budget defaults; runner core TTY-agnostic (#1784) * chore: bump version and changelog (v0.42.15.0) Decouple CLI primary output from process.stdout.isTTY (#1784): human by default, JSON only with --json; jobs watch non-TTY one-shots; eval banners annotate non-interactive defaults; reindex-code refusal is human unless --json. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: CLAUDE.md Key Files notes for v0.42.15.0 isTTY-output decoupling (#1784) Annotate jobs.ts (jobs watch format/loop split + resolveWatchMode + the new cycle-default.ts), reindex-code.ts (human cost-refusal), and eval-cross-modal.ts (cycle/budget banner annotations). Regenerate llms-full.txt. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
45 lines
2.1 KiB
TypeScript
45 lines
2.1 KiB
TypeScript
/**
|
||
* v0.42.15.0 (#1784) — jobs-watch format × loop matrix.
|
||
*
|
||
* Pins resolveWatchMode so the TTY-gating contract can't regress. The bug this
|
||
* guards: TTY + --json used to loop forever (follow defaulted to isTTY); the
|
||
* documented matrix says --json one-shots unless --follow. Caught by codex in
|
||
* the pre-landing review; the e2e missed it (non-TTY only).
|
||
*/
|
||
import { describe, test, expect } from 'bun:test';
|
||
import { resolveWatchMode } from '../src/commands/jobs-watch.ts';
|
||
|
||
describe('resolveWatchMode — format × loop matrix', () => {
|
||
test('TTY, no flags → live dashboard (json off, follow on, ansi on)', () => {
|
||
expect(resolveWatchMode({}, true)).toEqual({ json: false, follow: true, useAnsiDashboard: true });
|
||
});
|
||
|
||
test('non-TTY, no flags → one human snapshot (the bug fix: not JSON, one-shot)', () => {
|
||
expect(resolveWatchMode({}, false)).toEqual({ json: false, follow: false, useAnsiDashboard: false });
|
||
});
|
||
|
||
test('TTY + --json → ONE JSON snapshot, NOT a forever loop (codex finding)', () => {
|
||
expect(resolveWatchMode({ json: true }, true)).toEqual({ json: true, follow: false, useAnsiDashboard: false });
|
||
});
|
||
|
||
test('non-TTY + --json → one JSON snapshot', () => {
|
||
expect(resolveWatchMode({ json: true }, false)).toEqual({ json: true, follow: false, useAnsiDashboard: false });
|
||
});
|
||
|
||
test('TTY + --follow → live dashboard loops', () => {
|
||
expect(resolveWatchMode({ follow: true }, true)).toEqual({ json: false, follow: true, useAnsiDashboard: true });
|
||
});
|
||
|
||
test('non-TTY + --follow → plain human stream (loops, no ansi)', () => {
|
||
expect(resolveWatchMode({ follow: true }, false)).toEqual({ json: false, follow: true, useAnsiDashboard: false });
|
||
});
|
||
|
||
test('--json --follow → JSONL stream, never the ansi dashboard', () => {
|
||
expect(resolveWatchMode({ json: true, follow: true }, true)).toEqual({ json: true, follow: true, useAnsiDashboard: false });
|
||
});
|
||
|
||
test('explicit --follow false on a TTY → one-shot (override wins)', () => {
|
||
expect(resolveWatchMode({ follow: false }, true)).toEqual({ json: false, follow: false, useAnsiDashboard: false });
|
||
});
|
||
});
|