Kontrak ini FROZEN: setiap perubahan perilaku terminal wajib update dokumen ini + test peta proteksinya. Versi lengkap (kontrak internal kontributor, peta proteksi per invariant, residual risk yang disengaja) ada di Terminal Contract.
#Satu tampilan interaktif: TUI fullscreen
Sesi interaktif (minicode di TTY mampu) SELALU membuka TUI alternate screen: transkrip ala shell + status bar satu baris + popup komposit di atas transkrip yang tetap terlihat (redup). REPL linier, footer lengket (chrome scroll-region), overlay inline, dan jendela info DIHAPUS — tak ada mode, tak ada flag legacy (--tui usang = no-op). Keluar = buffer utama kembali persis; transkrip sesi tidak di-dump ke scrollback.
Jalur non-interaktif (one-shot prompt, exec, pipe/redirect/CI, TERM=dumb, layar < 10 baris) tetap shell-first: cetak polos, append-only ke scrollback, tanpa alternate screen. Justru jalur inilah yang membuat hasil agen bisa di-pipe, di-grep, dan tinggal di scrollback Anda sendiri.
#Dua stream, dua isi
| Stream | Isi |
|---|---|
| stdout | Output program: teks model (wrapped, fence 2-spasi; pipe-table menjadi grid selaras di TTY), receipt perubahan (› write_file …), artefak perintah. Bersih dari cursor-control saat non-TTY |
| stderr | Progress/diagnostik: ledger tool (› … hijau/merah), reasoning (verbose), warning, error. Boleh transient bila TTY — ditahan saat layar interaktif memegang terminal |
- Warna hanya bila TTY (
stdout.isTTY);NO_COLORmenang;TERM/COLORTERMtidak menyalakan warna di pipe. - Error
✗ pesan actionablesekali per kegagalan (takePendingError) — bukan spam di setiap langkah.
#Primitif tampilan
- Transkrip fullscreen — prompt
minicode ›saat editing + jawaban model + ledger, viewport ikut ekor otomatis; drag mouse membuat selection app-level,Ctrl+Cmenyalin, wheel danPgUp/PgDnmenggulir layar - Status bar satu baris —
✦ 00.00.00 mode model cwd(timerHH.MM.SSdi sebelah sparkle; redup idle, detik putih saat aktif, menit mulai terang di 60 dtk, jam di 1 jam; tanpa bullet separator; konteks rata kanan) - Popup komposit satu kotak —
/model,/provider,/sessions, form, approval; Esc dua-tahap, kursor diparkir - Ledger —
› name targethijau /› name: …merah - Teks model & thinking — mengalir redup (thinking), di-buffer untuk
/expand - Error actionable — sekali per kegagalan
#Arbitrasi transient + hold layar interaktif
Satu-satunya arbitrator transient: src/ui/runtime/statusline.ts (acquireTransientPaint + paintWrite). Painter aktif (garis status turn vs spinner wizard) mutually exclusive; overlap = signal [transient-paint], bukan crash. Foreign stderr writer (non-UI) boleh mentah — arbitrator mengkomitnya sebagai baris permanen bersih.
beginInteractiveScreen() menahan SEMUA painter transient selama layar interaktif memegang terminal (nol byte + baris painter dibersihkan sekali; nested + release idempoten). Pemegangnya: askLine/askSecret/runPicker (raw-mode) dan setiap handle openAltScreen (dilepas di close()). Tanpa ini tick \r\x1b[2K spinner menghapus baris prompt wizard (laporan "macet di Menyiapkan sesi…").
#Invariant I1–I30
Peta lengkap 30 invariant + test proteksinya (mis. tui-app, screen-buffer, tui-popup, transient-arbitration, input-resize, exit-codes, acp) ada di Terminal Contract. Setiap fitur terminal baru tunduk pada invariant itu — mis. tak boleh menulis cursor-control ke stdout non-TTY, tak boleh mengandalkan alternate screen di jalur non-interaktif.
#Aksesibilitas & konsol lawas
MINICODE_ASCII=1 (glyph [OK]/>/.), MINICODE_A11Y=1 (live-region approval polos tanpa ANSI), MINICODE_BELL=0, MINICODE_DROPDOWN=0 (hint inline), MINICODE_MOTION=0 (spark statis, tanpa pulse). Daftar lengkap di Environment Variables.
#Sinyal fatal & pemulihan terminal
Sesi TUI memasang handler SIGTERM/SIGHUP sendiri selama hidup (dilepas saat quit): sinyal = raw mode dimatikan + alt-screen ditutup + exit 128+n (SIGTERM=143, SIGHUP=129) — terminal tidak tertinggal di buffer alt. kill -9 tetap di luar jangkauan (ketik reset; residual kontrak #2).
#Lanjut
- Konsep & Desain — kenapa interaktif pakai alt-screen, non-interaktif shell-first.
- TUI — Slash & Keyboard — interaksi harian di atas kontrak ini.