fix(tui): run every command from piped stdin, not just the first#49
Open
clawedassistant26 wants to merge 1 commit into
Open
Conversation
Piped stdin is delivered in chunks and readline emits every line of a
chunk as soon as it lands. The prompt loop asked for input with a
one-shot `rl.question`, so it captured the first line and dropped the
rest, then waited forever on input that had already gone by.
printf '/pwd\n/pwd\n/quit\n' | moshcode
ran one /pwd, skipped the second, never reached /quit, and still exited
0 with no farewell. Anything driving moshcode from a script or CI lost
every command after the first, silently.
Queue the lines as they arrive and hand them out one at a time. The
queue lives at module scope so it survives the interface being torn
down and rebuilt around a passthrough child, and end of input is
tracked on process.stdin rather than the interface, since rl.close()
fires on every teardown. End of input now leaves the pit the way Ctrl-D
does. The TTY path is untouched.
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.
The bug
Piping commands into
moshcoderuns only the first one. Everything after it is silently dropped,/quitincluded, and the process still exits 0.On unmodified
main(5029919):One
/pwdran. The other two never did,/quitwas never reached, and thecode hard, mosh harder. 🤘farewell never printed. Exit status is 0, so a script has no way to tell.Why
mkrl()deliberately supports non-TTY input (terminal: Boolean(process.stdin.isTTY)), but the loop asks for lines with a one-shotrl.question. Withterminal: false, readline emits every line of an incoming chunk as soon as that chunk lands.rl.questionregisters a single handler, takes line 1, and the remaining lines are emitted with nobody listening. The loop then awaits input that has already gone by, stdin ends, the promise never settles, the event loop drains and the process exits quietly.Reduced to plain readline, no moshcode involved:
Worth noting: the tests in
test/tui.test.mjsall pipe"<command>\n/quit\n"and assertstatus === 0. That assertion passes today for the wrong reason —/quitis never executed, the process just falls off the end.The fix
src/tui.mjsonly. Queue lines as readline emits them and hand them out one at a time./shell,/install,/start, …).process.stdin.on("end"), not the interface'sclose, becauserl.close()fires on every one of those teardowns and is not the end of the input.rl.questionand is unchanged.Verified after the fix: all three
/pwds run and/quitis honoured;/shell echo FIRST→/pwd→/shell echo SECOND→/quitall run in order across two interface rebuilds; input ending without/quitexits cleanly; an interactive pty session behaves as before.Tests
Two added to
test/tui.test.mjs, both driving the real binary through the file's existingrunTuihelper:/quitis reached/quitstill leaves cleanlyStash-verified with
git stash push -- src/: both fail unpatched (9 pass / 2 fail), 11/11 with the fix.Full suite
node --test: 166 tests, 163 pass, 0 fail, 3 skipped (main baseline: 164 / 161 / 0 fail / 3 skipped).