Skip to content

fix(shell): guard TUI render against non-TTY Docker environments#118

Merged
skulidropek merged 3 commits intoProverCoderAI:mainfrom
skulidropek:issue-100
Mar 9, 2026
Merged

fix(shell): guard TUI render against non-TTY Docker environments#118
skulidropek merged 3 commits intoProverCoderAI:mainfrom
skulidropek:issue-100

Conversation

@skulidropek
Copy link
Copy Markdown
Member

Summary

  • В runMenu добавлен guard через Effect.suspend — перед вызовом render() проверяется process.stdin.isTTY && typeof process.stdin.setRawMode === "function"
  • Если TTY отсутствует (Docker без флага -t, CI, piped stdin) — возвращается InputReadError с понятным сообщением вместо бесконечного зависания
  • Паттерн совпадает с существующими guard-ами в menu-shared.ts

Причина бага: Ink вызывает setRawMode(true) при монтировании компонента. Без псевдо-TTY это бросает "Raw mode is not supported", а waitUntilExit() никогда не resolve-ится → вечный hang.

Инвариант: ∀ env: ¬isTTY(env) → fail(InputReadError) ∧ ¬hang

Test plan

  • Запустить docker-git menu в контейнере без -t → должен получить ошибку "TUI requires a TTY. Attach a terminal: ssh into the container or use \docker run -it`."` вместо зависания
  • Запустить docker-git menu через SSH в контейнер → TUI работает как прежде

Closes #100

🤖 Generated with Claude Code

skulidropek and others added 3 commits March 8, 2026 19:56
Ink's render() calls setRawMode(true) on mount. When docker-git runs
without a pseudo-TTY (docker exec without -t, CI, piped stdin), this
throws "Raw mode is not supported" and waitUntilExit() never resolves,
causing an infinite hang.

- Wrap render() in Effect.suspend and check process.stdin.isTTY and
  typeof process.stdin.setRawMode before calling render()
- Fail immediately with a descriptive InputReadError guiding the user
  to attach a terminal (ssh or docker run -it)

Invariant: ∀ env: ¬isTTY(env) → fail(InputReadError) ∧ ¬hang

Closes ProverCoderAI#100

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Instead of failing with InputReadError, docker-git menu now runs
listProjectStatus in non-interactive environments (Docker without -t,
CI, piped stdin). Zero errors for the user.

∀ env: isTTY(env) → TUI, ¬isTTY(env) → listProjectStatus ∧ exit 0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace Effect.suspend (union of incompatible branches) with
Effect.flatMap on a boolean so TypeScript unifies the two branch
types: Effect<void, InputReadError, never> | Effect<void, never, R>
→ Effect<void, InputReadError, R>.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@skulidropek skulidropek merged commit 8f253a4 into ProverCoderAI:main Mar 9, 2026
12 checks passed
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.

Ошибка при сборке приложения в docker

1 participant