About the piping thing, for this the libc (wrapped in fpcs termio unit) provides the function isatty, which lets you check for any file handle if it is connected to a terminal, or not (i.e. if it is a file or a pipe).
So you could do either restrict interactive mode just for ttys (or at least show some warning if trying to use interactive mode without a tty like vim does), or in case it is not a tty, then you can use read to read single chars without having any setup, because then it's the piping program that is controlling the buffering and not the terminal.
It's actually one of the things I was designing my LazTermUtils library around, to also work with files (even directly, you can say in the constructor to just use files as I/O target)