feat: run shell commands through the detected user shell - #21
Merged
Merged
Conversation
The bash tool hardcoded /bin/sh -c and the interactive !cmd/!!cmd shell-out hardcoded bash -c, so commands ran without the user's shell environment. Both now resolve the shell via the new extras/shell.user_shell(): $SHELL when it points at an executable (absolute or on PATH), /bin/sh otherwise — the previous behavior. The tool description names the resolved shell so the model adapts its syntax, and background tasks inherit the shell through _run_shell. Hooks keep their documented /bin/sh -c contract.
# Conflicts: # src/lecode/agent/tools/bash.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
lecode executed shell commands through hardcoded shells — the agent's
bashtool used/bin/sh -c, and the interactive!cmd/!!cmdshell-out usedbash -c— so commands ran without the user's shell environment. Both now detect and use the user's shell.How
extras/shell.py:user_shell()resolves$SHELLviashutil.which(accepts absolute paths and bare names), falling back to/bin/shwhen$SHELLis unset, empty, missing, or not executable — i.e. the previous behavior is the fallbackagent/tools/bash.py:BashToolresolves the shell at construction (shell=param for injection) and_run_shellexecutes it; background shell tasks inherit the shell since they run through_run_shellRun a shell command (/bin/zsh -c)…) so the model can adapt its syntax (e.g. fish vs POSIX)tui/app.py:!cmd/!!cmdrun throughuser_shell() -cDeliberately unchanged: hooks keep their documented
/bin/sh -ccontract (docs/hooks.md), and loop mode's configured command still runs viabash.Tests
tests/test_shell.py: unset/empty/missing/non-executable$SHELL→/bin/sh; absolute path used; bare name resolved onPATHtest_tool_bash.py: the tool runs commands through$SHELL -c(pinned with/bin/echo, which prints its argv) and the description names the detected shelltest_tui_app.py:!cmduses the detected shellSHELL=/bin/zsh: description reads/bin/zsh -c,$0and$ZSH_VERSIONconfirm zsh executes the command