From 4cfcdf6108e02d0f7fce35ad9de78dd4df2e6c8d Mon Sep 17 00:00:00 2001 From: marcusquinn <6428977+marcusquinn@users.noreply.github.com> Date: Sun, 8 Feb 2026 19:42:22 +0000 Subject: [PATCH] hotfix: fix dispatch command breaking on multi-line prompts The bash -c construction used printf '%q' to escape cmd_parts, but multi-line prompts (from t173 worker restrictions) produce $'\n' sequences that break when embedded in bash -c double-quoted strings. Workers received malformed commands and printed help text instead of executing. Fix: write dispatch commands to temp script files in pids/ directory and execute those instead. This is robust regardless of prompt content. Fixes both cmd_dispatch (tabby + headless) and cmd_reprompt paths. --- .agents/scripts/supervisor-helper.sh | 33 ++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/.agents/scripts/supervisor-helper.sh b/.agents/scripts/supervisor-helper.sh index 42e85116c..a8d297b9f 100755 --- a/.agents/scripts/supervisor-helper.sh +++ b/.agents/scripts/supervisor-helper.sh @@ -3113,20 +3113,34 @@ cmd_dispatch() { # This ensures headless mode even if the AI doesn't parse --headless from the prompt local headless_env="FULL_LOOP_HEADLESS=true" + # Write dispatch script to a temp file to avoid bash -c quoting issues + # with multi-line prompts (newlines in printf '%q' break bash -c strings) + local dispatch_script="${SUPERVISOR_DIR}/pids/${task_id}-dispatch.sh" + { + echo '#!/usr/bin/env bash' + echo "cd '${worktree_path}' || exit 1" + echo "export ${headless_env}" + # Write each cmd_part as a properly quoted array element + printf 'exec ' + printf '%q ' "${cmd_parts[@]}" + printf '\n' + } > "$dispatch_script" + chmod +x "$dispatch_script" + if [[ "$dispatch_mode" == "tabby" ]]; then # Tabby: attempt to open in a new tab via OSC 1337 escape sequence log_info "Opening Tabby tab for $task_id..." local tab_cmd - tab_cmd="cd '${worktree_path}' && ${headless_env} ${cmd_parts[*]} > '${log_file}' 2>&1; echo \"EXIT:\$?\" >> '${log_file}'" + tab_cmd="'${dispatch_script}' > '${log_file}' 2>&1; echo \"EXIT:\$?\" >> '${log_file}'" printf '\e]1337;NewTab=%s\a' "$tab_cmd" 2>/dev/null || true # Also start background process as fallback (Tabby may not support OSC 1337) # Use nohup + disown to survive parent (cron) exit - nohup bash -c "cd '${worktree_path}' && export ${headless_env} && $(printf '%q ' "${cmd_parts[@]}") > '${log_file}' 2>&1; echo \"EXIT:\$?\" >> '${log_file}'" &>/dev/null & + nohup bash -c "'${dispatch_script}' > '${log_file}' 2>&1; echo \"EXIT:\$?\" >> '${log_file}'" &>/dev/null & else # Headless: background process # Use nohup + disown to survive parent (cron) exit — without this, # workers die after ~2 minutes when the cron pulse script exits - nohup bash -c "cd '${worktree_path}' && export ${headless_env} && $(printf '%q ' "${cmd_parts[@]}") > '${log_file}' 2>&1; echo \"EXIT:\$?\" >> '${log_file}'" &>/dev/null & + nohup bash -c "'${dispatch_script}' > '${log_file}' 2>&1; echo \"EXIT:\$?\" >> '${log_file}'" &>/dev/null & fi local worker_pid=$! @@ -3787,8 +3801,19 @@ Task description: ${tdesc:-$task_id}" # Ensure PID directory exists mkdir -p "$SUPERVISOR_DIR/pids" + # Write dispatch script to avoid bash -c quoting issues with multi-line prompts + local dispatch_script="${SUPERVISOR_DIR}/pids/${task_id}-reprompt.sh" + { + echo '#!/usr/bin/env bash' + echo "cd '${work_dir}' || exit 1" + printf 'exec ' + printf '%q ' "${cmd_parts[@]}" + printf '\n' + } > "$dispatch_script" + chmod +x "$dispatch_script" + # Use nohup + disown to survive parent (cron) exit - nohup bash -c "cd '${work_dir}' && $(printf '%q ' "${cmd_parts[@]}") > '${new_log_file}' 2>&1; echo \"EXIT:\$?\" >> '${new_log_file}'" &>/dev/null & + nohup bash -c "'${dispatch_script}' > '${new_log_file}' 2>&1; echo \"EXIT:\$?\" >> '${new_log_file}'" &>/dev/null & local worker_pid=$! disown "$worker_pid" 2>/dev/null || true