Files
coyote/assets/functions/tools/execute_command.sh
T
Dark-Alex-17 304b8f635f fix(tools): interactive-shell semantics and stderr capture in execute_command
Two long-standing agent-facing defects:

1. bash -e aborted the model's script at the first intermediate
   non-zero status (grep with no matches exits 1, inspecting a failing
   test run, a probing subshell), so trailing guards like '; exit 0'
   never executed and output was partially or entirely lost. Dropped
   -e: the last statement now decides the exit code, matching the
   interactive-shell semantics models expect. pipefail is kept so a
   failing pipeline stage still surfaces in the exit code.

2. Only stdout was redirected into $LLM_OUTPUT, and the harness
   returns just $LLM_OUTPUT on success, so commands whose useful
   output goes to stderr (git push, cargo progress, curl -v) returned
   empty on success. Added 2>&1.
2026-08-26 14:15:34 -06:00

32 lines
1.4 KiB
Bash
Executable File

#!/usr/bin/env bash
set -e
# @describe Execute the shell command. DO NOT use this to write files — use fs_write (new files) or fs_patch (edits) instead. Shell-based file writes (cat >, echo >, printf >, tee, heredocs, python -c "open(...)") break on multi-line content, special characters, quoted strings, and nested language blocks.
# @option --command! The command to execute.
# @env LLM_OUTPUT=/dev/stdout The output path
# shellcheck disable=SC1090
source "$LLM_PROMPT_UTILS_FILE"
main() {
# shellcheck disable=SC2154
argc_command="$(jq -r '.command' <<< "$LLM_TOOL_RAW_JSON")"
guard_operation
local script
script="$(mktemp)"
# shellcheck disable=SC2064
trap "rm -f '$script'" EXIT
# shellcheck disable=SC2154
printf '%s\n' "$argc_command" > "$script"
# No -e: the command gets standard interactive-shell semantics — the last
# statement decides the exit code, so trailing guards like `; exit 0` work
# and an intermediate non-zero status (grep with no matches, a failing
# test run being inspected) cannot abort the script mid-way. pipefail is
# kept so a failing pipeline stage still surfaces in the exit code. 2>&1:
# the harness only returns $LLM_OUTPUT on success, so without it stderr
# (git push, cargo progress, curl -v) vanishes from successful calls.
bash -o pipefail "$script" >> "$LLM_OUTPUT" 2>&1
}