fix(runtime): throw a descriptive error when raw mode is unsupported (Ink parity, G10) (#40)
* fix(runtime): throw a descriptive error when raw mode is unsupported (Ink parity, G10) Previously the raw-mode acquire path silently no-opped on a stdin where raw mode is unsupported (non-TTY / isRawModeSupported false), so using useInput on such a stdin did nothing with no diagnostic. Ink's handleSetRawMode (App.tsx:315-327) instead throws immediately when enabling raw mode is unsupported, with two distinct messages (default process.stdin vs a custom stdin) both pointing at the isRawModeSupported docs. StdinController.acquireRawMode now throws that two-message error on !isRawModeSupported. The unguarded useInput path surfaces it (matching Ink's use-input.ts, which calls setRawMode(true) ungated). useFocus now guards on isRawModeSupported before acquiring (matching Ink's use-focus.ts), so focus degrades to a safe no-op on a non-TTY rather than throwing. releaseRawMode keeps its no-op guard — Ink only throws when enabling. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(parity): ledger — G10 pr-open, reconcile G09 merged Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(runtime): assert full raw-mode error message for exact Ink parity (G10, codex) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1048,7 +1048,22 @@ function createStdinController(
|
||||
internal_eventEmitter: emitter,
|
||||
internal_exitOnCtrlC: opts.exitOnCtrlC,
|
||||
acquireRawMode() {
|
||||
if (!appCtx.isRawModeSupported) return;
|
||||
if (!appCtx.isRawModeSupported) {
|
||||
// Match Ink's handleSetRawMode (App.tsx): enabling raw mode on an
|
||||
// unsupported stdin throws a descriptive error rather than silently
|
||||
// no-opping. Two messages — one for the default process.stdin, one for
|
||||
// a custom stream — both pointing at the isRawModeSupported docs. The
|
||||
// unguarded useInput path surfaces this; useFocus guards before calling
|
||||
// (see composables/useFocus.ts), so it degrades to a no-op like Ink.
|
||||
if (stdin === process.stdin) {
|
||||
throw new Error(
|
||||
"Raw mode is not supported on the current process.stdin, which Vue TUI uses as input stream by default.\nRead about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported",
|
||||
);
|
||||
}
|
||||
throw new Error(
|
||||
"Raw mode is not supported on the stdin provided to Vue TUI.\nRead about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported",
|
||||
);
|
||||
}
|
||||
const state = getRawModeState(stdin);
|
||||
if (state.refs === 0) {
|
||||
state.prevRaw = (stdin as { isRaw?: boolean }).isRaw ?? false;
|
||||
|
||||
Reference in New Issue
Block a user