Files
sar/.agents/skills/bmad-story-automator/data/tmux-long-command-testing.md
julian 17c08e6392 chore: initial monorepo scaffold + WDS Phase 1+2 artifacts
- 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>
2026-05-27 14:34:20 +00:00

185 lines
4.5 KiB
Markdown

# 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:
```bash
# 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:
```bash
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
```bash
# 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:
1. **Normal input:** Characters arrive, shell builds command buffer
2. **Wrapped input:** Terminal sends characters that visually wrap
3. **Problem:** Some shell/terminal combinations mishandle the wrap points
4. **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
```bash
#!/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
```bash
#!/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` (see `new-session` options)
- Shell line editing: readline (bash) / zle (zsh)
- Related issue: Commands with many arguments or long strings failing in tmux