fix(tools): make execute_bash non-interactive-safe - #43
Conversation
shauryagangrade
left a comment
There was a problem hiding this comment.
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.
- CHANGELOG (add):
CHANGELOG.mdUnreleased > Fixed is empty — add an entry per repo convention. - Behavior note to document (optional): catching
KeyboardInterrupthere means Ctrl-C at the approval prompt no longer propagates tomain()'s handler (gcode/cli.py:317) — the session continues instead of exiting. That's sensible and consistent withask_permission, but worth a line in the PR body so reviewers know it's intentional.
| 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): ") |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
|
Merged. Thanks for your work here. If you would like to contribute to more repos just like this, I recommend: https://github.com/shauryagangrade/intent-drift-skill |
Fixes #13
execute_bashused a bareinput()call for the y/n approval gate. In non-interactive environments (CI pipelines, Docker with no TTY, piped stdin) that raisesEOFErroror 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 makesexecute_bashconsistent 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
--yesmode; the docstring now documents the non-interactive rejection.