(
options: StartTUIChatOptions & { customStdin?: NodeJS.ReadStream },
)
| 30 | } |
| 31 | |
| 32 | export async function startTUIChat( |
| 33 | options: StartTUIChatOptions & { customStdin?: NodeJS.ReadStream }, |
| 34 | ) { |
| 35 | const { |
| 36 | initialPrompt, |
| 37 | resume, |
| 38 | fork, |
| 39 | config, |
| 40 | org, |
| 41 | rule, |
| 42 | prompt, |
| 43 | toolPermissionOverrides, |
| 44 | skipOnboarding, |
| 45 | customStdin, |
| 46 | } = options; |
| 47 | |
| 48 | // Critical safeguard: Prevent TUI initialization in headless mode |
| 49 | if (isHeadlessMode()) { |
| 50 | throw new Error( |
| 51 | "Cannot start TUI in headless mode. This is a programming error - " + |
| 52 | "startTUIChat should not be called when -p/--print flag is used.", |
| 53 | ); |
| 54 | } |
| 55 | |
| 56 | // Critical safeguard: Prevent TUI initialization in TTY-less environment |
| 57 | if (isTTYless() && !customStdin) { |
| 58 | throw new Error( |
| 59 | "Cannot start TUI in TTY-less environment. No TTY available for interactive mode.\n" + |
| 60 | "For non-interactive use, run with -p flag:\n" + |
| 61 | ' cn -p "your prompt here"', |
| 62 | ); |
| 63 | } |
| 64 | |
| 65 | // Initialize services only if not already done (skipOnboarding means already initialized) |
| 66 | if (!skipOnboarding) { |
| 67 | await initializeServices({ |
| 68 | options: { config, org, rule, prompt }, |
| 69 | headless: false, |
| 70 | toolPermissionOverrides, |
| 71 | }); |
| 72 | } |
| 73 | |
| 74 | // Validate stdin is available and suitable for Ink |
| 75 | const stdinToUse = customStdin || process.stdin; |
| 76 | |
| 77 | // Test raw mode capability (required by Ink) |
| 78 | if ( |
| 79 | stdinToUse.isTTY && |
| 80 | typeof (stdinToUse as any).setRawMode === "function" |
| 81 | ) { |
| 82 | try { |
| 83 | // Test that we can enter raw mode (Ink requirement) |
| 84 | (stdinToUse as any).setRawMode(true); |
| 85 | (stdinToUse as any).setRawMode(false); |
| 86 | logger.debug("Raw mode test passed - TTY is suitable for Ink"); |
| 87 | } catch { |
| 88 | throw new Error( |
| 89 | "Terminal does not support raw mode required for interactive UI.\n" + |
no test coverage detected