Skip to content

Add the terminal user interface#212

Open
chengluyu wants to merge 8 commits intomainfrom
feat/tui
Open

Add the terminal user interface#212
chengluyu wants to merge 8 commits intomainfrom
feat/tui

Conversation

@chengluyu
Copy link
Copy Markdown
Collaborator

No description provided.

chengluyu and others added 8 commits April 26, 2026 20:04
Reuses the existing reactive runtime under a new full-screen terminal UI:
line-numbered editor with syntax highlighting, mouse support (click to
focus, drag to select, wheel to scroll), examples picker, and inline
//➜ output comments — feature parity with the web editor for echo-based
notebooks.

- terminal/screen.js: raw-mode I/O, SGR mouse + key parsing, diffing grid
- terminal/buffer.js: text buffer with cursor-aware change-spec mapping
- terminal/highlight.js: regex-based JS highlighting with output/error tints
- terminal/app.js: layout, render loop, runtime wiring, modals
- terminal/cli.js: executable entry point (bin: recho, script: pnpm tui)

Two minor adjustments to keep the runtime importable from plain Node 24:
strip TS parameter properties from BlockMetadata.ts and add explicit .js
extensions in runtime/controls/index.js. All 114 existing tests still pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…e UI

Examples like abacus that pull in d3 fail in Node ("document is not
defined"). The Observable runtime's variable-rejection path called
console.error directly, which scribbled raw stack traces into the
alt-screen and corrupted the layout. Process-level error handlers were
also over-eager and would tear down the whole TUI on async failures from
notebook code.

Now:
- console.{log,info,warn,error} and process.stderr.write are captured
  while the alt-screen is up and routed into a bounded message log.
- Consecutive identical errors are coalesced with a ×N badge so a
  generator firing 100 rejections doesn't spam the log.
- uncaughtException / unhandledRejection are logged to that same buffer
  instead of killing the UI.
- New ^L "Console" modal shows the full captured log with timestamps,
  error/warn tags, scroll, and Backspace-to-clear; the status bar shows
  an unread-error badge and the latest error summary.
- On clean exit we restore the originals and replay the most recent
  errors to stderr so the user isn't left wondering what failed.

Also: only LF-Enter (10) needs the special name; ^L (12) is now a free
binding for the console keymap.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
An infinite loop in a cell used to freeze the TUI forever — user input,
rendering, and the runtime were all blocked by a synchronous `while (true)`.

Now `safeEval` compiles the cell function with `vm.runInThisContext` and
calls it through a tiny pre-compiled wrapper script with `timeout` armed.
A synchronous infinite loop is interrupted after 1000ms (configurable
via `createRuntime(code, { cellTimeoutMs })`), surfaced as a friendly
`TimeoutError`, captured into the message log, and surfaced inline as
//✗ in the buffer. The host realm is reused intentionally so primordials
(Object, Array, Promise) match the rest of the runtime — sharing a fresh
vm context produced `[Object: null prototype]` in inspector output and
broke existing snapshots. We trade isolation for liveness; the user is
running their own notebook, so the goal is keeping the editor alive,
not security.

Async hangs (timers, awaits) are *not* caught — those need a worker
thread; this commit covers the most common shape of the bug.

Status indicator upgrades:
- title bar shows a Braille spinner while running, ● success / ● error /
  ⏱ timed out / ○ idle once settled, plus run elapsed time;
- run state settles after a 500ms-quiet window (no new changes, no new
  errors);
- timeouts are detected by sniffing the captured error and shown
  distinctly from generic errors.

All 114 existing tests still pass (TZ=America/New_York). PTY test
confirms an infinite-loop cell now times out, the TUI recovers, and a
follow-up cell runs successfully.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 26, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
recho-notebook Error Error Apr 26, 2026 10:01pm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant