menu_ask_value used line-oriented read -rp: a multiline Ctrl+V paste
flooded the tty queue, read consumed only the first line, and the rest
executed as commands later (or were eaten by a later prompt).
- lib/menu-lib.sh: new menu_read_value() raw-mode bracketed-paste
reader (stty -icanon -echo -isig, \e[?2004h/l, literal newlines inside
[200~..[201~, Enter submits outside paste, edit keys, cancel on
Ctrl-D-empty/Ctrl-C/Z/\, terminal restored via trap). Bytes via
dd|od|tr chunks, not bash read: read self-interrupts on ETX from a
tty even with ISIG disabled.
- bin/pos-ai-alias: prompt encode/decode (backslash, newline) with
load/save wiring; newline-safe truncate; edit wizard Enter keeps the
full original prompt (no more silent >80-char truncation).
Verified via pty harnesses: multiline + single-line paste captured
verbatim with nothing executed, Ctrl-D/Ctrl-C cancel cleanly, full
create/list/show/edit E2E, round-trips byte-exact. Gates: make gen &&
make check, make lint 0 FAIL 0 WARN.
Add an optional5th 'trusted' field to aliases
(name|provider|session|prompt|trusted). Trusted aliases pass --trust to
pos ai, which makes _prompt_run_command auto-execute the agent's detected
commands without the Y/n confirmation (command still printed for audit).
- bin/pos-ai: new --trust global flag; _prompt_run_command takes trusted
arg and skips the prompt when set; POS_FLAGS + usage updated
- bin/pos-ai-alias: _ALIAS_TRUSTED array, 5-field env format (backward
compat: missing field defaults to untrusted), Trust column in table,
trust row in show, trust step (5/5) in create wizard with security
warning, trust toggle (4/4) with diff tag in edit wizard, wrapper
scripts get --trust when alias is trusted
- completions/pos.bash + gen docs updated
Gates: make gen && make check && make lint = 0 FAIL, 0 WARN
_alias_load() used 'name' as its while-read loop variable, which — via
bash dynamic scoping — clobbered the caller's local 'name'. When _alias_create
passed 'searcher', _alias_load overwrote it to '' (last env-file line's name),
making _wrapper_path produce '~/.local/bin/' (the directory itself). Since
directories always exist, [ -e ] triggered a spurious 'already exists' error.
Fix: rename _alias_load loop vars to _ln/_lp/_ls/_lp2/_lr (local), breaking
the dynamic-scope collision. Reproduced and verified with a test harness.
Gates: make gen && make check && make lint = 0 FAIL, 0 WARN
- Create/edit/remove named aliases (provider + session + system prompt)
- Aliases stored in ai-aliases.env, generated ai-aliases.sh sourced by bashrc
- Interactive menu using lib/menu-lib.sh primitives
- Provider auto-discovered from lib/ai-providers/
Fix: _alias_find() return 1 crashed under set -e; changed to return 0
since -1 sentinel is the not-found signal, not the exit code.