RFE: public isatty(fd: int): bool binding
Filer: repoman v0.1.1 implementation
Reef version: 0.5.18
Date: 2026-05-03
Severity: Low — blocks one polish item; clean workaround possible by importing whole tty module if its internal C conflicts are fixed
Summary
Common need: detect whether a given file descriptor (typically STDOUT/STDERR) is a terminal, to switch between interactive and non-interactive output modes. Today there is no user-callable API for this:
ui.backend.ttydeclaresextern "C" fn reef_tty_is_tty(fd: int): intprivately and uses it internally (if reef_tty_is_tty(STDOUT_FD) == 0), but does not export a wrapper.sys.fdexportsSTDIN(),STDOUT(),STDERR()and various read/write/dup primitives, but noisatty.sys.platform.libcdoes not bindisatty(3).
Workarounds either fail at link time (extern "C" declaration in user code links against an undefined symbol) or fail at compile time (importing ui.backend.tty pulls in conflicting extern int write(int fd, char* buf, int count); that clashes with the runtime's own write declaration).
Use case
repoman v0.1.1 task A2 (TTY detection for rsync progress): when stdout is a terminal, repoman wants to pass --info=stats2,progress2 to rsync (live progress); otherwise --info=stats2 (cron-friendly). Currently hardcoded is_tty: bool = false for cron compatibility; missing the live-progress UX in interactive use.
This is a generic CLI need — any tool that wants to render progress bars, ANSI colors, or interactive prompts needs to detect TTY context.
Proposed API
Either of:
// In sys.fd:
fn isatty(fd: int): bool
// Or in ui.backend.tty (publicly exported):
fn is_tty(fd: int): bool
Trivial wrapper:
fn isatty(fd: int): bool
return reef_tty_is_tty(fd) == 1
end isatty
sys.fd feels more correct since isatty(3) is a POSIX file-descriptor primitive, but ui.backend.tty is also reasonable since the implementation already lives there. Either works.
Side issue
If ui.backend.tty becomes the home, the existing extern int write(int fd, char* buf, int count); declaration inside that module needs to be removed or replaced — it conflicts with the runtime's own write declaration, which makes importing ui.backend.tty from a user program fail to compile (error: conflicting types for 'write'). If the goal is for user code to be able to import ui.backend.tty cleanly, that needs fixing regardless.
Repoman impact
A2 in our v0.1.1 polish list is parked until this lands. Trivial to wire in once the API exists (one-line replacement in cli.cmd_sync).
Filed by the repoman v0.1.1 build flow.