Error in user YAML: (<unknown>): mapping values are not allowed in this context at line 2 column 613
---
log:
2026-05-07: Fixed `colab console` piped-stdin handling. Previously a piped invocation (e.g. `echo 'cmd' | colab console -s s`) sent the command and then hung indefinitely because the previous EOF handler emitted a bare `\x04` (Ctrl-D), which the remote `tmux`-wrapped bash treats as a literal character rather than a session terminator. The new handler sends `exit\n` (which bash actually exits on) and then closes the websocket from the client side after a short grace period (`PIPED_EOF_GRACE_SECONDS = 0.5s`) so any tail output (bash `logout`, tmux `[exited]`) makes it back to the user. TTY mode is unchanged: real-terminal EOF is left to the remote shell. Verified live: `echo 'echo HELLO' | colab console -s s` now exits in ~1.2s instead of hanging.
2026-05-07: Fixed `print_kitty` (used by `colab exec --output-image` and any image-producing exec) to no-op when `sys.stdout.isatty()` is false. The Kitty Graphics Protocol escape sequence is meaningless when stdout is a file or pipe and was visually corrupting captured output (a multi-KB base64 PNG blob would land in log files, grep targets, or showboat captures). Image bytes are still saved to disk via `handle_image`'s file-write path; only the inline-render attempt is suppressed.
2026-06-04: Bumped the default `--timeout` for `colab exec` from 10s to 30s (and the matching `colab run` default) so brief silent tasks are less likely to hit a premature `TimeoutError`. Explicit `--timeout` overrides are unaffected.
---
Execution involves sending Python code (or shell commands) to the Jupyter kernel running on the Colab VM and processing the stream of output messages.
- Transport: WebSockets (using
websocketslibrary if allowed, or a customhttp.clientbased long-polling implementation if we're strictly stdlib). - Communication: Jupyter Kernel Messaging Protocol.
execute_request: Send code string.execute_reply: Get status.iopub.stream: Capturestdoutandstderr.
- Interactive Mode: Standard Python
cmd.Cmdorcode.InteractiveConsolefor local input/output. - Piping Support: Detect
sys.stdin.isatty(). If not a TTY, read all input and send as a single execution request.
- File Handling:
- If file path is local: Read content, send as code.
- If file path is remote: Execute
!python <path>.
- Multi-Modal Output: Handle
display_datamessages (e.g.,image/png,text/html). For the CLI, we'll save images to temporary files and print their paths, or if the terminal supports it (e.g., iTerm2), inline them. - Timeout Configuration: Exposes a
--timeoutflag (default 30s) to allow long-running silent tasks (like model compilation or data downloading) to execute without being prematurely killed.
- Implementation: Connects directly to the backend terminal endpoint (
/colab/tty) via WebSockets usingwebsocket-client. - Interactive: Bypasses the Jupyter kernel entirely to provide a raw, PTY-backed bash session on the Colab VM.
- Terminal Management: Configures
sys.stdinto raw mode usingtermiosandtty, passing single characters to the socket and writing raw ANSI escape sequences directly tosys.stdout.buffer. Hooks intoSIGWINCHto communicate local terminal dimensions (cols/rows) to the remote bash environment so output rendering works perfectly during resizing. - Piped stdin: Detected via
sys.stdin.isatty(). When piped, the input characters are forwarded one at a time to the remote pty, and on EOF the client sendsexit\nand then closes the websocket itself afterPIPED_EOF_GRACE_SECONDS(0.5s) so the user's shell goodbye text drains back. The remote/colab/ttyendpoint wraps bash in tmux, which intercepts a bare\x04as a literal character — that is why we sendexit\nrather than Ctrl-D.
- Kernel Management:
ColabRuntime(fromcolab-agent) already handles message signing and message types. - Output Streaming: Continuous polling or asynchronous message handling to provide real-time output.
- Piping Example:
cat script.py | colab exec -s my-session.
TDD is mandatory for all execution features.
- Test Case: Verify
ColabRuntimecorrectly sends anexecute_requestmessage over the websocket. - Test Case: Verify
iopub.streammessages are correctly handled and printed tostdoutin real-time. - Test Case: Verify
display_data(specificallyimage/png) triggers the correct local handling (saving or display).
- Test Case: Mock
sys.stdin.isatty()to verifycolab replcorrectly switches between interactive mode and one-shot piped execution. - Test Case: Verify large piped inputs are handled without buffer overflow or truncation.
- Test Case:
colab consolewith piped stdin sendsexit\nand callsws.close()on EOF (regression: previously sent\x04only and hung). - Test Case:
colab consolein TTY mode does not synthesize an exit on EOF (the user owns the session lifecycle). - Test Case:
print_kittyis a no-op whensys.stdout.isatty()is false (regression: previously emitted ANSI/base64 into pipes and files).