Skip to content

fix: prevent devai:install composer hang on invisible prompt#140

Merged
markshust merged 1 commit into
developfrom
feature/devai-install-composer-hang-fix
Jun 24, 2026
Merged

fix: prevent devai:install composer hang on invisible prompt#140
markshust merged 1 commit into
developfrom
feature/devai-install-composer-hang-fix

Conversation

@markshust

Copy link
Copy Markdown
Collaborator

Problem

marko devai:install could hang indefinitely at:

Installing marko/docs-fts via composer (this may take a moment)…

The docs-driver step shells out to composer require --dev via CommandRunner, which opened only stdout/stderr pipes and left the child inheriting the parent's TTY stdin. Composer thus detected an interactive terminal and could block on a prompt (most commonly the allow-plugins trust question). Because CommandRunner buffers all child output and never echoes it, that prompt was invisible — composer sat waiting for a keystroke the user couldn't see, an infinite hang.

It reproduced reliably with a cold cache + missing driver:

composer remove marko/docs-fts --no-interaction
rm -rf vendor/marko/docs-fts
composer clearcache
marko devai:install   # answer y → hangs

Fix

  • CommandRunner — detach the child's stdin to /dev/null (0 => ['file', '/dev/null', 'r']) so no shelled-out command can ever block on terminal input. Structural guard for every caller.
  • InstallCommand — pass --no-interaction --no-progress to the composer require call so composer is contractually forbidden from prompting.

Tests

  • New CommandRunnerTest case: a child running read line; echo done now returns in <10s instead of deadlocking — the deterministic guarantee that stdin can't block.
  • Updated InstallCommandTest assertion to expect the new composer args.

Full packages/devai suite green (253 passed); lint clean on all touched files.

Out of scope

The buffered-silence UX (no live progress during a slow resolve) is unchanged — this PR stops the hang, not the quiet. A follow-up could stream runner output live.

🤖 Generated with Claude Code

The devai:install docs-driver step shelled out to `composer require --dev`
through CommandRunner, which opened only stdout/stderr pipes and left the
child inheriting the parent's TTY stdin. Composer therefore saw an
interactive terminal and could block on a prompt (e.g. the allow-plugins
trust question) whose text was buffered and never echoed — an invisible,
infinite hang.

Detach the child's stdin to /dev/null in CommandRunner so no shelled-out
command can ever block on terminal input, and pass --no-interaction
--no-progress to the composer require call so composer is contractually
forbidden from prompting. Add a CommandRunner test proving a stdin-reading
child returns immediately instead of deadlocking.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@markshust markshust merged commit 2fc7f6b into develop Jun 24, 2026
1 check passed
@markshust markshust deleted the feature/devai-install-composer-hang-fix branch June 24, 2026 21:54
@github-actions github-actions Bot added the bug Something isn't working label Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant