- Nx 22.7 monorepo (pnpm 11.1, TypeScript 5.9, Node 24) - apps/api: NestJS 11 (CJS conforme CODING-RULES.md PGD-DB-004) - apps/web: React 19 + Vite 8 (ESM) - libs/shared/api-interface: Zod contract base - Docker Compose dev: Postgres 18, Valkey 8, MinIO, Mailpit - WDS artifacts: - design-artifacts/A-Product-Brief/ (5 docs canônicos + 16 dialogs) - design-artifacts/B-Trigger-Map/ (hub + 4 personas + feature impact) - Stack canon: STACK.md v2.2 + CODING-RULES.md v2.0 + brand.md - AGENTS.md + README.md como entrada para devs/agentes Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.5 KiB
4.5 KiB
Tmux Long Command Testing & Investigation
Related: See tmux-long-command-debugging.md for root cause analysis and solution.
Investigation Process
Step 1: Verify Command Syntax
First, confirm the command itself is valid:
# Build the command
cmd=$("$scripts" tmux-wrapper build-cmd retro 2 --agent "codex")
# Check for syntax issues
echo "$cmd" | od -c | head -20 # Look for unexpected characters
# Test parsing
bash -n -c "$cmd" # Syntax check only
Finding: Command syntax was correct. Quotes and escapes were properly formed.
Step 2: Test Progressive Lengths
Binary search to find the breaking point:
test_length() {
local len=$1
local sess="test-len-$len-$$"
local prompt="Execute the BMAD retrospective workflow for epic 2. $(printf 'x%.0s' $(seq 1 $len))"
tmux new-session -d -s "$sess"
tmux send-keys -t "$sess" "claude --dangerously-skip-permissions \"$prompt\"" Enter
sleep 5
local capture=$(tmux capture-pane -t "$sess" -p)
tmux kill-session -t "$sess" 2>/dev/null
if echo "$capture" | grep -qiE "interrupt|Working|Running"; then
echo "Length $len: SUCCESS"
else
echo "Length $len: FAILED"
fi
}
# Test different lengths
test_length 200 # SUCCESS
test_length 500 # SUCCESS
test_length 800 # SUCCESS
test_length 1000 # SUCCESS
test_length 1200 # FAILED
Finding: Commands failed around 1000-1200 characters.
Step 3: Test Terminal Width Hypothesis
# Default dimensions
sess="test-default-$$"
tmux new-session -d -s "$sess"
tmux display -t "$sess" -p 'cols:#{pane_width} rows:#{pane_height}'
# Output: cols:80 rows:24
# Send long command
tmux send-keys -t "$sess" "$long_cmd" Enter
sleep 10
# Result: FAILED - no activity
# Wide terminal
sess="test-wide-$$"
tmux new-session -d -s "$sess" -x 200 -y 50
tmux display -t "$sess" -p 'cols:#{pane_width} rows:#{pane_height}'
# Output: cols:200 rows:50
# Send same long command
tmux send-keys -t "$sess" "$long_cmd" Enter
sleep 10
# Result: SUCCESS - Claude running!
Finding: Wide terminal (200 cols) prevents the failure.
Step 4: Understand the Mechanism
The shell's line editor (readline/zle) handles input differently when lines wrap:
- Normal input: Characters arrive, shell builds command buffer
- Wrapped input: Terminal sends characters that visually wrap
- Problem: Some shell/terminal combinations mishandle the wrap points
- Result: Command buffer corruption or premature execution
This is why the command "appears" in the terminal (tmux captured it) but doesn't execute properly (shell didn't parse it correctly).
Testing Methodology
Quick Smoke Test
#!/bin/bash
# smoke-test-tmux-command.sh
cmd="$1"
cmd_len=${#cmd}
echo "Testing command of length: $cmd_len"
# Test with default dimensions
sess="smoke-default-$$"
tmux new-session -d -s "$sess"
tmux send-keys -t "$sess" "$cmd" Enter
sleep 5
if tmux capture-pane -t "$sess" -p | grep -qiE "interrupt|Working|Running|Read"; then
echo "Default (80x24): SUCCESS"
else
echo "Default (80x24): FAILED"
fi
tmux kill-session -t "$sess" 2>/dev/null
# Test with wide dimensions
sess="smoke-wide-$$"
tmux new-session -d -s "$sess" -x 200 -y 50
tmux send-keys -t "$sess" "$cmd" Enter
sleep 5
if tmux capture-pane -t "$sess" -p | grep -qiE "interrupt|Working|Running|Read"; then
echo "Wide (200x50): SUCCESS"
else
echo "Wide (200x50): FAILED"
fi
tmux kill-session -t "$sess" 2>/dev/null
Comprehensive Test
#!/bin/bash
# test-tmux-long-commands.sh
test_at_width() {
local width=$1
local cmd_len=$2
local sess="test-w${width}-l${cmd_len}-$$"
# Generate command of specific length
local padding=$(printf 'x%.0s' $(seq 1 $cmd_len))
local cmd="echo \"test $padding\""
tmux new-session -d -s "$sess" -x "$width" -y 24
tmux send-keys -t "$sess" "$cmd" Enter
sleep 2
local output=$(tmux capture-pane -t "$sess" -p)
tmux kill-session -t "$sess" 2>/dev/null
if echo "$output" | grep -q "test xxx"; then
echo "Width $width, Length $cmd_len: PASS"
return 0
else
echo "Width $width, Length $cmd_len: FAIL"
return 1
fi
}
# Test matrix
for width in 80 120 160 200; do
for len in 500 1000 1500 2000; do
test_at_width $width $len
done
done
References
- tmux manual:
man tmux(seenew-sessionoptions) - Shell line editing: readline (bash) / zle (zsh)
- Related issue: Commands with many arguments or long strings failing in tmux