Files
gbrain/test/jobs-watch-mode.test.ts
T
488f89e0dc v0.42.15.0 fix: decouple CLI primary output from process.stdout.isTTY (#1784) (#1806)
* 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>
2026-06-03 07:09:20 -07:00

45 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 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 });
});
});