feat: add external break signal for read_line interruption and mark Signal as non_exhaustive#1035
Merged
fdncred merged 3 commits intonushell:mainfrom Mar 12, 2026
Merged
Conversation
read_line interruption and mark Signal as non_exhaustiveread_line interruption and mark Signal as non_exhaustive
Contributor
|
Is there any way to test this automatically and/or manually? |
Contributor
Author
I've added an example so you can test it manually. Automated testing requires a terminal, which is tested in arf test suite (eitsupi/arf#113) using https://github.com/doy/vt100-rust (unfortunately not compatible with Windows). |
Contributor
|
Thanks! |
Contributor
|
Hi. I was bumping reedline in nushell. How should nushell handle this? Should it just ignore it? Both nusehll repl and the |
Contributor
|
@Juhan280 For now it can be ignored but in the future it would be cool to have proper support for it. |
Contributor
|
Ok |
eitsupi
added a commit
to eitsupi/arf
that referenced
this pull request
Mar 19, 2026
…113) ## Summary Add an experimental JSON-RPC 2.0 IPC server for AI agents, IDE extensions, and other external tools to interact with a running arf R session. ### Features - **Transport**: Unix domain sockets (Linux/macOS), Windows named pipes - **Protocol**: JSON-RPC 2.0 over HTTP (curl-compatible) or raw JSON - **`evaluate` method**: Silent or visible evaluation with captured stdout/value/error via WriteConsoleEx interception - **`user_input` method**: Inject code into the REPL via reedline's `ExternalBreak` signal (nushell/reedline#1035), with full echo, history, spinner, and duration tracking - **`send` method**: Alias for `user_input` - **`:ipc` meta command**: Start/stop/check server status at runtime - **`arf ipc` subcommand**: CLI client for eval/send/list/status from another terminal - **Session discovery**: `~/.cache/arf/sessions/<pid>.json`, cleaned up on exit ### Safety - Mutual exclusion with console input: IPC requests are rejected with `USER_IS_TYPING` (-32003) when the user has typed something in the buffer - Alternate screen modes (help pager, history browser, shell mode): IPC requests are rejected immediately with `R_NOT_AT_PROMPT` (-32001) - Prompt position is preserved after rejected ExternalBreak (reedline fix: nushell/reedline#1042) ### Tests - 7 cross-platform IPC unit tests (protocol, evaluate, user_input) - 6 PTY integration tests (evaluate capture, visible/silent modes, user_input, rejection, prompt position)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add a break signal that allows external threads to interrupt
read_line(), causing it to return a newSignal::ExternalBreak(String)variant with the current buffer contents.Motivation
Applications that embed a REPL alongside external control systems (e.g., AI agents) need a way to interrupt
read_line()from another thread.For example, an AI agent controlling the console may need to inject input while the user is at the prompt — but
read_line()is a blocking loop with no external interruption mechanism.Currently, there is no way for an external thread to cause
read_line()to return.The
external_printerfeature can print messages above the prompt, but cannot break out of the input loop.The
idle_callbackfeature (#1015) allows periodic processing but also cannot cause an early return.Design
The break signal check is placed in the
read_line_helperloop alongsideidle_callbackandexternal_printer.When
break_signalis configured,needs_pollingis set totruesoread_line()usespoll()instead of blocking indefinitely oncrossterm::event::read().API
Note
Signalis now#[non_exhaustive].Downstream match arms on
Signalwill need a wildcard_pattern.This is a one-time change that prevents future additions from being breaking.