Skip to content

fix(tools): make execute_bash non-interactive-safe - #43

Merged
shauryagangrade merged 1 commit into
shauryagangrade:mainfrom
aryansk:fix/tools/non-interactive-execute-bash
Aug 14, 2026
Merged

fix(tools): make execute_bash non-interactive-safe#43
shauryagangrade merged 1 commit into
shauryagangrade:mainfrom
aryansk:fix/tools/non-interactive-execute-bash

Conversation

@aryansk

@aryansk aryansk commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Fixes #13

execute_bash used a bare input() call for the y/n approval gate. In non-interactive environments (CI pipelines, Docker with no TTY, piped stdin) that raises EOFError or blocks forever, hanging the agent. The rest of the codebase already handles this case — RichUI.ask_permission (gcode/ui.py) catches (EOFError, KeyboardInterrupt) and denies. This makes execute_bash consistent with that pattern: if approval cannot be read, the command is rejected instead of crashing or hanging. Operators in non-interactive environments can run with --yes (auto-approve), which skips the prompt entirely.

Behavior is unchanged for interactive sessions and for --yes mode; the docstring now documents the non-interactive rejection.

@shauryagangrade shauryagangrade left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review

Solid, focused fix — matches the existing RichUI.ask_permission pattern (gcode/ui.py:197). Verified: 29/29 tests pass, ruff/mypy/bandit clean, and non-interactive stdin now rejects instead of raising.

  1. CHANGELOG (add): CHANGELOG.md Unreleased > Fixed is empty — add an entry per repo convention.
  2. Behavior note to document (optional): catching KeyboardInterrupt here means Ctrl-C at the approval prompt no longer propagates to main()'s handler (gcode/cli.py:317) — the session continues instead of exiting. That's sensible and consistent with ask_permission, but worth a line in the PR body so reviewers know it's intentional.

Comment thread gcode/tools.py
if not AUTO_APPROVE:
confirm = input(f"GCode wants to run: {command}\nApprove? (y/n): ")
try:
confirm = input(f"GCode wants to run: {command}\nApprove? (y/n): ")

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: on EOFError there was no user, yet the model is told "cancelled by user" — in CI the agent will misread this as the human declining. Consider a distinct message for the non-interactive case, e.g. "Command rejected: no terminal available (non-interactive). Run with --yes to auto-approve.", and keep the "cancelled by user" text for real denials.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — agreed that in CI there is no human declining, so the current wording could mislead an agent into reading a rejection. This PR merged as submitted (commit 568e62f). If you'd like, I can open a small follow-up that uses a distinct non-interactive rejection message (e.g. no terminal available — run with --yes to auto-approve) so the two cases stay unambiguous.

@shauryagangrade
shauryagangrade marked this pull request as ready for review August 14, 2026 10:07
@shauryagangrade
shauryagangrade merged commit 568e62f into shauryagangrade:main Aug 14, 2026
6 checks passed
@shauryagangrade

Copy link
Copy Markdown
Owner

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.

[Bug]: execute_bash confirmation prompt not compatible with non-interactive environments

2 participants