From 9564880ebf145f7dec5a31e6266b77f96a26a769 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 26 Aug 2026 04:37:52 -0400 Subject: [PATCH] fix: AI command edit - flatten multi-line for readline read -e -i only handles single-line text. Multi-line commands (docker install etc) broke it. Now flattens newlines to spaces before pre-filling the readline buffer. User sees a single editable line. --- DOC/AGENT_Context_Project.md | 2 +- bin/pos-ai | 51 +++++++++++++++++++++++++----------- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/DOC/AGENT_Context_Project.md b/DOC/AGENT_Context_Project.md index 63b23c4..cea540f 100644 --- a/DOC/AGENT_Context_Project.md +++ b/DOC/AGENT_Context_Project.md @@ -633,7 +633,7 @@ Use conventional prefixes: `feat:`, `fix:`, `docs:`, `refactor:`, `chore:` | `bin/pos-system-health` | 209 | Host health dashboard (disk, RAM, services, backup age, fail2ban, docker); exit 1 if any FAIL | | `bin/pos-system-schedule` | 151 | Scheduled jobs: run a command on a timer; notify on threshold/change/error/always or silently | | `bin/pos-system-uninstall` | 415 | Remove pos toolkit binaries, services, shell integration, config, and data | -| `bin/pos-ai` | 716 | AI assistant: ask, chat, sessions, capture, models, providers | +| `bin/pos-ai` | 735 | AI assistant: ask, chat, sessions, capture, models, providers | | `bin/pos-config` | 80 | Interactive editor for the tools' runtime config (reads # POS_CONFIG: registry) | | `bin/pos-tree` | 112 | Show the pos CLI command tree: categories, commands, and subcommands | | `completions/pos.bash` | 306 | Dynamic bash completion | diff --git a/bin/pos-ai b/bin/pos-ai index 8d91937..643b68c 100755 --- a/bin/pos-ai +++ b/bin/pos-ai @@ -396,35 +396,54 @@ _prompt_run_command() { esac } -# Inject command for editing: clipboard copy → xdotool typing → tmux → history. -# User pastes with Ctrl+Shift+V (X11) or Ctrl+V (Wayland/SSH). +# Inject command for editing. Priority: +# 1. read -e -i (bash native readline — works in ANY terminal, CLI or GUI) +# 2. Clipboard (xclip/wl-copy — GUI only) +# 3. xdotool typing (X11 GUI only) +# 4. tmux send-keys +# 5. History fallback (press ↑) _inject_command() { - local cmd="$1" injected="" - # 1. Clipboard (most universal — works over SSH via OSC52 in modern terminals) - if command -v xclip >/dev/null 2>&1 && [ -n "${DISPLAY:-}" ]; then - printf '%s' "$cmd" | xclip -selection clipboard && injected="clipboard" - elif command -v wl-copy >/dev/null 2>&1 && [ -n "${WAYLAND_DISPLAY:-}" ]; then - printf '%s' "$cmd" | wl-copy && injected="clipboard" + local cmd="$1" + # Flatten multi-line commands for readline (read -i only handles single line) + local flat + flat="$(printf '%s' "$cmd" | tr '\n' ' ' | sed 's/ */ /g; s/^ //; s/ $//')" + # 1. Bash readline: pre-fill the command on the line, user edits, Enter runs + if [ -w /dev/tty ]; then + local edited="" + printf '\n' >&2 + if edited="$(read -e -p "Command: " -i "$flat" /dev/null)"; then + [ -n "$edited" ] || { printf '%s\n' "Empty command — skipped." >&2; return 0; } + printf '%s\n' "$edited" + run eval "$edited" + return 0 + fi + # read failed (Ctrl+C / EOF) — fall through + fi + # 2. Clipboard (GUI only) + local injected="" + if command -v wl-copy >/dev/null 2>&1 && [ -n "${WAYLAND_DISPLAY:-}" ]; then + printf '%s' "$cmd" | wl-copy && injected="wayland" + elif command -v xclip >/dev/null 2>&1 && [ -n "${DISPLAY:-}" ]; then + printf '%s' "$cmd" | xclip -selection clipboard && injected="x11" elif command -v xsel >/dev/null 2>&1 && [ -n "${DISPLAY:-}" ]; then - printf '%s' "$cmd" | xsel --clipboard --input && injected="clipboard" + printf '%s' "$cmd" | xsel --clipboard --input && injected="x11" fi if [ -n "$injected" ]; then - printf '%s\n' "Command copied to clipboard — paste with Ctrl+Shift+V, edit, Enter to run." >&2 + local key="Ctrl+V"; [ "$injected" = "x11" ] && key="Ctrl+Shift+V" + printf '%s\n' "Command copied to clipboard — paste with $key, edit, Enter to run." >&2 return 0 fi - # 2. xdotool: simulate typing into focused terminal - if command -v xdotool >/dev/null 2>&1 && [ -n "${DISPLAY:-}${WAYLAND_DISPLAY:-}" ]; then - printf '%s\n' "Typing command — edit if needed, Enter to run." >&2 + # 3. xdotool (X11 GUI only) + if command -v xdotool >/dev/null 2>&1 && [ -n "${DISPLAY:-}" ]; then printf '%s' "$cmd" | xdotool type --clearmodifiers --file - return 0 fi - # 3. tmux: send keys directly into the pane + # 4. tmux if [ -n "${TMUX:-}" ]; then - printf '%s\n' "Typing command — edit if needed, Enter to run." >&2 tmux send-keys "$cmd" return 0 fi - # 4. Fallback: add to history, user presses ↑ to recall + # 5. History fallback history -s "$cmd" 2>/dev/null || true printf '%s\n' "Command added to history — press ↑ to recall, edit, and run." >&2 }