@devo-bmad-custom/agent-orchestration 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -2
- package/src/.agents/skills/tmux-commands/SKILL.md +1 -1
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/SKILL.md +475 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/references/vision-requests.md +736 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/references/visionkit-scanner.md +738 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/weatherkit/SKILL.md +410 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/weatherkit/references/weatherkit-patterns.md +567 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/widgetkit/SKILL.md +497 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/widgetkit/references/widgetkit-advanced.md +871 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/typography.csv +58 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/ui-reasoning.csv +101 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/ux-guidelines.csv +100 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/web-interface.csv +31 -0
- package/src/.agents/skills/ui-ux-pro-custom/scripts/core.py +253 -0
- package/src/.agents/skills/ui-ux-pro-custom/scripts/design_system.py +1067 -0
- package/src/.agents/skills/ui-ux-pro-custom/scripts/search.py +114 -0
- package/src/.agents/skills/ux-audit/SKILL.md +151 -0
- package/src/.agents/skills/websocket-engineer/SKILL.md +168 -0
- package/src/.agents/skills/websocket-engineer/references/alternatives.md +391 -0
- package/src/.agents/skills/websocket-engineer/references/patterns.md +400 -0
- package/src/.agents/skills/websocket-engineer/references/protocol.md +195 -0
- package/src/.agents/skills/websocket-engineer/references/scaling.md +333 -0
- package/src/.agents/skills/websocket-engineer/references/security.md +474 -0
- package/src/.agents/skills/writing-skills/SKILL.md +655 -0
- package/src/.agents/skills/writing-skills/anthropic-best-practices.md +1150 -0
- package/src/.agents/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- package/src/.agents/skills/writing-skills/graphviz-conventions.dot +172 -0
- package/src/.agents/skills/writing-skills/persuasion-principles.md +187 -0
- package/src/.agents/skills/writing-skills/render-graphs.js +168 -0
- package/src/.agents/skills/writing-skills/testing-skills-with-subagents.md +384 -0
- package/src/.claude/commands/bmad-track-compact.md +19 -0
- package/src/.claude/commands/bmad-track-extended.md +19 -0
- package/src/.claude/commands/bmad-track-large.md +19 -0
- package/src/.claude/commands/bmad-track-medium.md +19 -0
- package/src/.claude/commands/bmad-track-nano.md +19 -0
- package/src/.claude/commands/bmad-track-rv.md +18 -0
- package/src/.claude/commands/bmad-track-small.md +19 -0
- package/src/.claude/commands/master-orchestrator.md +15 -0
- package/src/_memory/master-orchestrator-sidecar/docs-index.md +3 -0
- package/src/_memory/master-orchestrator-sidecar/instructions.md +2616 -0
- package/src/_memory/master-orchestrator-sidecar/memories.md +8 -0
- package/src/_memory/master-orchestrator-sidecar/session-state.md +15 -0
- package/src/_memory/master-orchestrator-sidecar/triage-history.md +3 -0
- package/src/_memory/master-orchestrator-sidecar/workflows-overview.html +1230 -0
- package/src/core/agents/master-orchestrator.md +54 -0
- package/src/docs/dev/tmux/actions_popup.py +291 -0
- package/src/docs/dev/tmux/actions_popup.sh +110 -0
- package/src/docs/dev/tmux/claude_usage.sh +15 -0
- package/src/docs/dev/tmux/colors.conf +26 -0
- package/src/docs/dev/tmux/cpu_usage.sh +7 -0
- package/src/docs/dev/tmux/dispatch.sh +10 -0
- package/src/docs/dev/tmux/float_init.sh +13 -0
- package/src/docs/dev/tmux/float_term.sh +23 -0
- package/src/docs/dev/tmux/open_clip.sh +14 -0
- package/src/docs/dev/tmux/paste_claude.sh +26 -0
- package/src/docs/dev/tmux/paste_clipboard.sh +13 -0
- package/src/docs/dev/tmux/paste_image_wrapper.sh +98 -0
- package/src/docs/dev/tmux/ram_usage.sh +3 -0
- package/src/docs/dev/tmux/title_sync.sh +54 -0
- package/src/docs/dev/tmux/tmux-setup.md +867 -0
- package/src/docs/dev/tmux/tmux-test.sh +255 -0
- package/src/docs/dev/tmux/tmux.conf +127 -0
- package/src/docs/dev/tmux/xclip +18 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tmux-test.sh — Automated test suite for tmux agent orchestration commands
|
|
3
|
+
#
|
|
4
|
+
# Tests the verified command library from .agents/skills/tmux-commands/SKILL.md
|
|
5
|
+
# Run from inside a tmux session:
|
|
6
|
+
# bash docs/dev/tmux-test.sh
|
|
7
|
+
#
|
|
8
|
+
# Tests:
|
|
9
|
+
# 1. Pane creation (split-window + sleep + capture ID)
|
|
10
|
+
# 2. Pane verification (list-panes grep)
|
|
11
|
+
# 3. Message sending with delivery verification
|
|
12
|
+
# 4. Pane naming (select-pane -T)
|
|
13
|
+
# 5. Layout rebalance (main-vertical)
|
|
14
|
+
# 6. Multi-pane spawn + rebalance
|
|
15
|
+
# 7. Graceful kill (kill-pane + cleanup)
|
|
16
|
+
#
|
|
17
|
+
# Exit codes: 0 = all pass, 1 = failures
|
|
18
|
+
|
|
19
|
+
set -uo pipefail
|
|
20
|
+
|
|
21
|
+
PASS=0
|
|
22
|
+
FAIL=0
|
|
23
|
+
TESTS=()
|
|
24
|
+
|
|
25
|
+
pass() { PASS=$((PASS + 1)); TESTS+=("PASS: $1"); echo " PASS: $1"; }
|
|
26
|
+
fail() { FAIL=$((FAIL + 1)); TESTS+=("FAIL: $1"); echo " FAIL: $1"; }
|
|
27
|
+
|
|
28
|
+
# Cleanup function — kill any test panes on exit
|
|
29
|
+
TEST_PANES_TO_CLEAN=()
|
|
30
|
+
cleanup() {
|
|
31
|
+
for p in "${TEST_PANES_TO_CLEAN[@]}"; do
|
|
32
|
+
tmux kill-pane -t "$p" 2>/dev/null || true
|
|
33
|
+
done
|
|
34
|
+
}
|
|
35
|
+
trap cleanup EXIT
|
|
36
|
+
|
|
37
|
+
echo "========================================"
|
|
38
|
+
echo " Tmux Command Library Test Suite"
|
|
39
|
+
echo "========================================"
|
|
40
|
+
echo ""
|
|
41
|
+
|
|
42
|
+
# Pre-check: must be inside tmux
|
|
43
|
+
if [ -z "${TMUX:-}" ]; then
|
|
44
|
+
echo "ERROR: Not inside a tmux session. Run this from within tmux."
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
MASTER_PANE=$(tmux display-message -p "#{pane_id}")
|
|
49
|
+
SESSION_NAME=$(tmux display-message -p "#{session_name}")
|
|
50
|
+
WINDOW_ID=$(tmux display-message -p "#{window_id}")
|
|
51
|
+
echo "Master pane: $MASTER_PANE"
|
|
52
|
+
echo "Session: $SESSION_NAME"
|
|
53
|
+
echo "Window: $WINDOW_ID"
|
|
54
|
+
echo ""
|
|
55
|
+
|
|
56
|
+
# ─── Test 1: Split + Sleep + Capture ID ──────────────────────────────────────
|
|
57
|
+
echo "--- Test 1: Pane creation with sleep guards ---"
|
|
58
|
+
|
|
59
|
+
PANES_BEFORE=$(tmux list-panes -F "#{pane_id}" | wc -l)
|
|
60
|
+
sleep 10
|
|
61
|
+
# Use interactive bash so send-keys works in later tests
|
|
62
|
+
# WSL bash needs ~15s to fully load .bashrc (nvm, etc) before accepting input
|
|
63
|
+
tmux split-window -h -c "#{pane_current_path}" "bash"
|
|
64
|
+
sleep 15
|
|
65
|
+
|
|
66
|
+
PANES_AFTER=$(tmux list-panes -F "#{pane_id}" | wc -l)
|
|
67
|
+
TEST_PANE=$(tmux list-panes -F "#{pane_id}" | tail -1)
|
|
68
|
+
TEST_PANES_TO_CLEAN+=("$TEST_PANE")
|
|
69
|
+
|
|
70
|
+
if [ "$PANES_AFTER" -gt "$PANES_BEFORE" ] && [ -n "$TEST_PANE" ]; then
|
|
71
|
+
pass "Split-window created pane $TEST_PANE (before: $PANES_BEFORE, after: $PANES_AFTER)"
|
|
72
|
+
else
|
|
73
|
+
fail "Split-window did not create a new pane"
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# ─── Test 2: Pane verification ───────────────────────────────────────────────
|
|
77
|
+
echo ""
|
|
78
|
+
echo "--- Test 2: Pane verification ---"
|
|
79
|
+
|
|
80
|
+
sleep 10
|
|
81
|
+
VERIFIED=$(tmux list-panes -a -F "#{pane_id} #{session_name} #{window_id}" \
|
|
82
|
+
| grep "^$TEST_PANE ")
|
|
83
|
+
|
|
84
|
+
if [ -n "$VERIFIED" ]; then
|
|
85
|
+
pass "Pane $TEST_PANE verified: $VERIFIED"
|
|
86
|
+
else
|
|
87
|
+
fail "Pane $TEST_PANE not found in list-panes output"
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
# Negative test: verify non-existent pane fails
|
|
91
|
+
FAKE_VERIFIED=$(tmux list-panes -a -F "#{pane_id}" | grep -Fx "%99999")
|
|
92
|
+
if [ -z "$FAKE_VERIFIED" ]; then
|
|
93
|
+
pass "Non-existent pane %99999 correctly not found"
|
|
94
|
+
else
|
|
95
|
+
fail "Non-existent pane %99999 incorrectly found"
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
# ─── Test 3: Message sending with delivery verification ──────────────────────
|
|
99
|
+
echo ""
|
|
100
|
+
echo "--- Test 3: Message sending ---"
|
|
101
|
+
|
|
102
|
+
TEST_TOKEN="TMUX_TEST_MSG_$(date +%s)"
|
|
103
|
+
sleep 10
|
|
104
|
+
tmux send-keys -t "$TEST_PANE" "echo $TEST_TOKEN" Enter
|
|
105
|
+
sleep 15
|
|
106
|
+
|
|
107
|
+
BUFFER=$(tmux capture-pane -t "$TEST_PANE" -p -S -)
|
|
108
|
+
if echo "$BUFFER" | grep -qF "$TEST_TOKEN"; then
|
|
109
|
+
pass "Message '$TEST_TOKEN' delivered and verified in pane buffer"
|
|
110
|
+
else
|
|
111
|
+
# Retry once (per protocol)
|
|
112
|
+
echo " WARN: First delivery not found, retrying..."
|
|
113
|
+
sleep 10
|
|
114
|
+
tmux send-keys -t "$TEST_PANE" "echo $TEST_TOKEN" Enter
|
|
115
|
+
sleep 15
|
|
116
|
+
BUFFER2=$(tmux capture-pane -t "$TEST_PANE" -p -S -)
|
|
117
|
+
if echo "$BUFFER2" | grep -qF "$TEST_TOKEN"; then
|
|
118
|
+
pass "Message delivered on retry"
|
|
119
|
+
else
|
|
120
|
+
fail "Message '$TEST_TOKEN' not found in pane buffer after retry"
|
|
121
|
+
fi
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
# ─── Test 4: Pane naming ─────────────────────────────────────────────────────
|
|
125
|
+
echo ""
|
|
126
|
+
echo "--- Test 4: Pane naming (border title) ---"
|
|
127
|
+
|
|
128
|
+
TITLE="test-agent-${TEST_PANE}"
|
|
129
|
+
sleep 10
|
|
130
|
+
tmux set-option -t "$TEST_PANE" -p allow-rename off
|
|
131
|
+
sleep 10
|
|
132
|
+
tmux select-pane -t "$TEST_PANE" -T "$TITLE"
|
|
133
|
+
sleep 10
|
|
134
|
+
|
|
135
|
+
ACTUAL_TITLE=$(tmux display-message -t "$TEST_PANE" -p "#{pane_title}")
|
|
136
|
+
if [ "$ACTUAL_TITLE" = "$TITLE" ]; then
|
|
137
|
+
pass "Pane title set to '$TITLE'"
|
|
138
|
+
else
|
|
139
|
+
fail "Expected title '$TITLE', got '$ACTUAL_TITLE'"
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
# ─── Test 5: Layout rebalance ────────────────────────────────────────────────
|
|
143
|
+
echo ""
|
|
144
|
+
echo "--- Test 5: Layout rebalance (main-vertical) ---"
|
|
145
|
+
|
|
146
|
+
sleep 10
|
|
147
|
+
tmux select-pane -t "$MASTER_PANE"
|
|
148
|
+
sleep 10
|
|
149
|
+
tmux select-layout main-vertical 2>/dev/null
|
|
150
|
+
LAYOUT_EXIT=$?
|
|
151
|
+
sleep 10
|
|
152
|
+
|
|
153
|
+
if [ $LAYOUT_EXIT -eq 0 ]; then
|
|
154
|
+
pass "main-vertical layout applied successfully"
|
|
155
|
+
else
|
|
156
|
+
fail "select-layout main-vertical failed with exit code $LAYOUT_EXIT"
|
|
157
|
+
fi
|
|
158
|
+
|
|
159
|
+
# ─── Test 6: Spawn a second pane and rebalance ───────────────────────────────
|
|
160
|
+
echo ""
|
|
161
|
+
echo "--- Test 6: Multi-pane spawn + rebalance ---"
|
|
162
|
+
|
|
163
|
+
sleep 10
|
|
164
|
+
# Split from the test pane (not LAST_PANE which could be stale)
|
|
165
|
+
tmux split-window -v -t "$TEST_PANE" -c "#{pane_current_path}" "bash"
|
|
166
|
+
sleep 15
|
|
167
|
+
|
|
168
|
+
TEST_PANE_2=$(tmux list-panes -F "#{pane_id}" | tail -1)
|
|
169
|
+
TEST_PANES_TO_CLEAN+=("$TEST_PANE_2")
|
|
170
|
+
PANE_COUNT=$(tmux list-panes -F "#{pane_id}" | wc -l)
|
|
171
|
+
|
|
172
|
+
if [ "$PANE_COUNT" -ge 3 ]; then
|
|
173
|
+
pass "Second test pane $TEST_PANE_2 created (total: $PANE_COUNT panes)"
|
|
174
|
+
else
|
|
175
|
+
fail "Expected 3+ panes, got $PANE_COUNT"
|
|
176
|
+
fi
|
|
177
|
+
|
|
178
|
+
sleep 10
|
|
179
|
+
tmux select-pane -t "$MASTER_PANE"
|
|
180
|
+
sleep 10
|
|
181
|
+
tmux select-layout main-vertical 2>/dev/null
|
|
182
|
+
sleep 10
|
|
183
|
+
|
|
184
|
+
pass "Rebalanced with $PANE_COUNT panes"
|
|
185
|
+
|
|
186
|
+
# ─── Test 7: Graceful kill ────────────────────────────────────────────────────
|
|
187
|
+
echo ""
|
|
188
|
+
echo "--- Test 7: Graceful pane kill ---"
|
|
189
|
+
|
|
190
|
+
# Kill test pane 2 first (check it exists before trying)
|
|
191
|
+
sleep 10
|
|
192
|
+
if tmux list-panes -a -F "#{pane_id}" | grep -qFx "$TEST_PANE_2"; then
|
|
193
|
+
tmux kill-pane -t "$TEST_PANE_2" 2>/dev/null
|
|
194
|
+
sleep 10
|
|
195
|
+
STILL_EXISTS=$(tmux list-panes -a -F "#{pane_id}" | grep -Fx "$TEST_PANE_2")
|
|
196
|
+
if [ -z "$STILL_EXISTS" ]; then
|
|
197
|
+
pass "Pane $TEST_PANE_2 killed successfully"
|
|
198
|
+
else
|
|
199
|
+
fail "Pane $TEST_PANE_2 still exists after kill"
|
|
200
|
+
fi
|
|
201
|
+
else
|
|
202
|
+
fail "Pane $TEST_PANE_2 already gone before kill test"
|
|
203
|
+
fi
|
|
204
|
+
|
|
205
|
+
# Kill test pane 1
|
|
206
|
+
sleep 10
|
|
207
|
+
if tmux list-panes -a -F "#{pane_id}" | grep -qFx "$TEST_PANE"; then
|
|
208
|
+
tmux kill-pane -t "$TEST_PANE" 2>/dev/null
|
|
209
|
+
sleep 10
|
|
210
|
+
STILL_EXISTS_1=$(tmux list-panes -a -F "#{pane_id}" | grep -Fx "$TEST_PANE")
|
|
211
|
+
if [ -z "$STILL_EXISTS_1" ]; then
|
|
212
|
+
pass "Pane $TEST_PANE killed successfully"
|
|
213
|
+
else
|
|
214
|
+
fail "Pane $TEST_PANE still exists after kill"
|
|
215
|
+
fi
|
|
216
|
+
else
|
|
217
|
+
fail "Pane $TEST_PANE already gone before kill test"
|
|
218
|
+
fi
|
|
219
|
+
|
|
220
|
+
# Clear cleanup list since we already killed them
|
|
221
|
+
TEST_PANES_TO_CLEAN=()
|
|
222
|
+
|
|
223
|
+
# Rebalance after kills
|
|
224
|
+
sleep 10
|
|
225
|
+
tmux select-pane -t "$MASTER_PANE"
|
|
226
|
+
sleep 10
|
|
227
|
+
tmux select-layout main-vertical 2>/dev/null
|
|
228
|
+
sleep 10
|
|
229
|
+
|
|
230
|
+
FINAL_COUNT=$(tmux list-panes -F "#{pane_id}" | wc -l)
|
|
231
|
+
if [ "$FINAL_COUNT" -eq 1 ]; then
|
|
232
|
+
pass "Back to 1 pane after cleanup"
|
|
233
|
+
else
|
|
234
|
+
# Not a failure — other panes may exist from user activity
|
|
235
|
+
pass "Final pane count: $FINAL_COUNT (master pane intact)"
|
|
236
|
+
fi
|
|
237
|
+
|
|
238
|
+
# ─── Summary ─────────────────────────────────────────────────────────────────
|
|
239
|
+
echo ""
|
|
240
|
+
echo "========================================"
|
|
241
|
+
echo " Results: $PASS passed, $FAIL failed"
|
|
242
|
+
echo "========================================"
|
|
243
|
+
echo ""
|
|
244
|
+
for t in "${TESTS[@]}"; do
|
|
245
|
+
echo " $t"
|
|
246
|
+
done
|
|
247
|
+
echo ""
|
|
248
|
+
|
|
249
|
+
if [ $FAIL -gt 0 ]; then
|
|
250
|
+
echo "SOME TESTS FAILED"
|
|
251
|
+
exit 1
|
|
252
|
+
else
|
|
253
|
+
echo "ALL TESTS PASSED"
|
|
254
|
+
exit 0
|
|
255
|
+
fi
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# General
|
|
2
|
+
set -g mouse on
|
|
3
|
+
set -g base-index 1
|
|
4
|
+
setw -g pane-base-index 1
|
|
5
|
+
set -g default-terminal "tmux-256color"
|
|
6
|
+
set -ga terminal-overrides ",*256col*:Tc"
|
|
7
|
+
set -ga terminal-overrides ",*256col*:RGB"
|
|
8
|
+
set -ga terminal-overrides ",*:U8=0"
|
|
9
|
+
set -s escape-time 0
|
|
10
|
+
# allow-passthrough off: must stay off — "on" causes Claude Code's OSC 2 title sequences
|
|
11
|
+
# to pass through to Windows Terminal instead of tmux intercepting them, which breaks
|
|
12
|
+
# pane-title-changed hook and all session/window auto-naming.
|
|
13
|
+
set -g allow-passthrough off
|
|
14
|
+
set -g status-interval 1
|
|
15
|
+
|
|
16
|
+
# Copy & Paste (vi mode)
|
|
17
|
+
set -g set-clipboard on
|
|
18
|
+
setw -g mode-keys vi
|
|
19
|
+
bind -T copy-mode-vi v send-keys -X begin-selection
|
|
20
|
+
bind -T copy-mode-vi C-v send-keys -X rectangle-toggle
|
|
21
|
+
bind -T copy-mode-vi C-c send-keys -X copy-pipe-and-cancel 'clip.exe'
|
|
22
|
+
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'clip.exe'
|
|
23
|
+
bind -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel 'clip.exe'
|
|
24
|
+
|
|
25
|
+
# Alt+V pastes image/file/text from clipboard — saves to /tmp, types path into pane instantly
|
|
26
|
+
bind -n M-v run-shell "bash ~/.config/tmux/bin/paste_image_wrapper.sh '#{pane_id}'"
|
|
27
|
+
# Alt+F opens resizable float terminal (Ctrl+Up/Down to resize inside)
|
|
28
|
+
bind -n M-f run-shell -b "bash ~/.config/tmux/bin/float_term.sh '#{pane_id}'"
|
|
29
|
+
|
|
30
|
+
# Colors
|
|
31
|
+
if-shell '[ -f ~/.config/tmux/colors.conf ]' "source-file ~/.config/tmux/colors.conf"
|
|
32
|
+
|
|
33
|
+
# Plugins
|
|
34
|
+
set -g @plugin 'tmux-plugins/tpm'
|
|
35
|
+
set -g @plugin 'tmux-plugins/tmux-sensible'
|
|
36
|
+
set -g @plugin 'tmux-plugins/tmux-resurrect'
|
|
37
|
+
set -g @plugin 'tmux-plugins/tmux-continuum'
|
|
38
|
+
set -g @plugin 'tmux-plugins/tmux-yank'
|
|
39
|
+
set -g @plugin 'bjesus/muxile'
|
|
40
|
+
set -g @plugin 'lloydbond/tmux-floating-terminal'
|
|
41
|
+
set -g @plugin 'tmux-plugins/tmux-open'
|
|
42
|
+
# Plugin config
|
|
43
|
+
set -g @open 'wslview'
|
|
44
|
+
set -g @floating_scratch_term 'M-i'
|
|
45
|
+
|
|
46
|
+
# Appearance
|
|
47
|
+
set -g window-style 'default'
|
|
48
|
+
set -g window-active-style 'default'
|
|
49
|
+
|
|
50
|
+
# ── Pane borders (hidden with 1 pane, shown with 2+) ────────────────────────────
|
|
51
|
+
setw -g pane-border-status off
|
|
52
|
+
setw -g pane-border-lines single
|
|
53
|
+
setw -g pane-border-style 'fg=#414559'
|
|
54
|
+
setw -g pane-active-border-style 'fg=#{?#{==:#{pane_index},1},#3d6095,#{?#{==:#{pane_index},2},#4a6e38,#{?#{==:#{pane_index},3},#783a3c,#{?#{==:#{pane_index},4},#5c3c78,#784828}}}}'
|
|
55
|
+
# Cap styles: rounded | pointed (swap chars in format below to change)
|
|
56
|
+
setw -g pane-border-format '#{?pane_active,#[align=centre]#[fg=#{?#{==:#{pane_index},1},#3d6095,#{?#{==:#{pane_index},2},#4a6e38,#{?#{==:#{pane_index},3},#783a3c,#{?#{==:#{pane_index},4},#5c3c78,#784828}}}}]#[bg=default]#[fg=#d8ddf0]#[bg=#{?#{==:#{pane_index},1},#3d6095,#{?#{==:#{pane_index},2},#4a6e38,#{?#{==:#{pane_index},3},#783a3c,#{?#{==:#{pane_index},4},#5c3c78,#784828}}}}]#[bold] #{?#{@pane-hash},#{@pane-hash},#{pane_title}} ID #{s/%//:pane_id} #[fg=#{?#{==:#{pane_index},1},#3d6095,#{?#{==:#{pane_index},2},#4a6e38,#{?#{==:#{pane_index},3},#783a3c,#{?#{==:#{pane_index},4},#5c3c78,#784828}}}}]#[bg=default]#[nobold],#[align=centre]#[fg=#414559]#[bg=default]#[fg=#c6d0f5]#[bg=#414559] #{?#{@pane-hash},#{@pane-hash},#{pane_title}} ID #{s/%//:pane_id} #[fg=#414559]#[bg=default]}'
|
|
57
|
+
|
|
58
|
+
# Toggle borders on/off based on pane count
|
|
59
|
+
set-hook -g after-split-window 'if "[ #{window_panes} -gt 1 ]" "setw pane-border-status top" "setw pane-border-status off" ; run-shell "tmux set-option -pt #{pane_id} @pane-hash #{s/%//:pane_id}"'
|
|
60
|
+
set-hook -g pane-exited 'if "[ #{window_panes} -gt 1 ]" "setw pane-border-status top" "setw pane-border-status off"'
|
|
61
|
+
# Sync active pane title → window name, and session name (with cwd basename) if first window
|
|
62
|
+
# Session name = "<pane title> · <cwd basename>" so multiple Claude Code sessions stay unique
|
|
63
|
+
# pane-title-changed fires on every OSC 2 update (primary trigger)
|
|
64
|
+
set-hook -wg pane-title-changed 'run-shell "bash ~/.config/tmux/bin/title_sync.sh #{pane_id} #{pane_active} #{window_index} \"#{pane_title}\" \"#{b:pane_current_path}\""'
|
|
65
|
+
# Fallback: re-sync on pane/window/client focus so stale titles catch up even without a title change
|
|
66
|
+
set-hook -g after-select-pane 'run-shell "bash ~/.config/tmux/bin/title_sync.sh #{pane_id} #{pane_active} #{window_index} \"#{pane_title}\" \"#{b:pane_current_path}\""'
|
|
67
|
+
set-hook -g after-select-window 'run-shell "bash ~/.config/tmux/bin/title_sync.sh #{pane_id} #{pane_active} #{window_index} \"#{pane_title}\" \"#{b:pane_current_path}\""'
|
|
68
|
+
set-hook -g client-focus-in 'run-shell "bash ~/.config/tmux/bin/title_sync.sh #{pane_id} #{pane_active} #{window_index} \"#{pane_title}\" \"#{b:pane_current_path}\""'
|
|
69
|
+
set -g automatic-rename off
|
|
70
|
+
|
|
71
|
+
# ── Status bar ────────────────────────────────────────────────────────────────────────────────
|
|
72
|
+
set -g status on
|
|
73
|
+
set -g status-position bottom
|
|
74
|
+
set -g status-style 'bg=#232634'
|
|
75
|
+
set -g status-justify left
|
|
76
|
+
set -g window-status-format ''
|
|
77
|
+
set -g window-status-current-format ''
|
|
78
|
+
set -g window-status-separator ''
|
|
79
|
+
set -g status-right '#[fg=#3d6095]#[bg=#232634]#[fg=#d8ddf0]#[bg=#3d6095]#[bold]💻 ID #{s/[$]//:session_id} #[fg=#685820]#[bg=#3d6095]#[fg=#d8ddf0]#[bg=#685820]#[bold]🪟 ID #{s/@//:window_id} #[fg=#4a6e38]#[bg=#685820]#[fg=#d8ddf0]#[bg=#4a6e38]#[bold]📁 #{b:pane_current_path}#[fg=#784828]#[bg=#4a6e38]#[fg=#d8ddf0]#[bg=#784828]#[bold]🧮 #(~/.config/tmux/bin/cpu_usage.sh) #[fg=#783a3c]#[bg=#784828]#[fg=#d8ddf0]#[bg=#783a3c]#[bold]💾 #(~/.config/tmux/bin/ram_usage.sh) #[fg=#5c3c78]#[bg=#783a3c]#[fg=#d8ddf0]#[bg=#5c3c78]#[bold]⏰ %I:%M %p %a %d %b #[none]'
|
|
80
|
+
set -g status-left-length 500
|
|
81
|
+
set -g status-right-length 300
|
|
82
|
+
set -gu 'status-format[1]'
|
|
83
|
+
set -g status-left ' #{?client_prefix,#[fg=#783a3c]#[bg=#232634]#[fg=#d8ddf0]#[bg=#783a3c]#[bold]⌨ CTRL+B #[fg=#783a3c]#[bg=#232634]#[none] ,#[fg=#414559]#[bg=#232634]#[fg=#c6d0f5]#[bg=#414559]#[bold]▶#[fg=#414559]#[bg=#232634]#[none] }#[range=user|actions]#[fg=#3d6095]#[bg=#232634]#[fg=#d8ddf0]#[bg=#3d6095]#[bold]⚙ Actions#[fg=#3d6095]#[bg=#232634]#[none]#[norange] #[range=user|reload]#[fg=#685820]#[bg=#232634]#[fg=#d8ddf0]#[bg=#685820]#[bold]🔄 Reload#[fg=#685820]#[bg=#232634]#[none]#[norange] '
|
|
84
|
+
|
|
85
|
+
# ── Rename new session to cwd basename as initial placeholder ─────────────────────────
|
|
86
|
+
set-hook -g session-created "run-shell 'tmux rename-session \"#{b:pane_current_path}\" 2>/dev/null || true'"
|
|
87
|
+
|
|
88
|
+
# Hash-name new windows until Claude sets a real title
|
|
89
|
+
set-hook -g after-new-window 'run-shell "tmux rename-window #{window_id}; tmux set-option -pt #{pane_id} @pane-hash #{s/%//:pane_id}"'
|
|
90
|
+
|
|
91
|
+
# ── Load TPM ────────────────────────────────────────────────────────────────────────────────
|
|
92
|
+
run '~/.tmux/plugins/tpm/tpm'
|
|
93
|
+
# Override tmux-yank mouse drag: copy to tmux buffer only, not Windows clipboard
|
|
94
|
+
bind -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-selection-and-cancel
|
|
95
|
+
|
|
96
|
+
# ── Remove / replace stale bindings ───────────────────────────────────────────────────
|
|
97
|
+
# C-v: paste Windows clipboard text into active pane (bracketed paste — works with Claude Code)
|
|
98
|
+
bind -T root C-v run-shell "bash ~/.config/tmux/bin/paste_claude.sh '#{pane_id}'"
|
|
99
|
+
unbind -T root MouseDown2Status
|
|
100
|
+
unbind -T root MouseDown3Status
|
|
101
|
+
# Suppress tmux default right-click menu (shows split options — opens panes accidentally)
|
|
102
|
+
bind -T root MouseDown3Pane select-pane -t=
|
|
103
|
+
bind -T root MouseDown1Pane select-pane -t = \; send-keys -M -t =
|
|
104
|
+
bind -T root MouseUp1Pane select-pane -t = \; send-keys -M -t =
|
|
105
|
+
bind -T root M-n new-window
|
|
106
|
+
bind -T root M-N new-window
|
|
107
|
+
bind -T root MouseDown3Border display-menu -T "Pane Actions" -x M -y M \
|
|
108
|
+
"Split Vertical" "|" "split-window -h -c '#{pane_current_path}'" \
|
|
109
|
+
"Split Horizontal" "-" "split-window -v -c '#{pane_current_path}'" \
|
|
110
|
+
"" "" "" \
|
|
111
|
+
"Break to New Window" "b" "break-pane" \
|
|
112
|
+
"Swap Up" "u" "swap-pane -U" \
|
|
113
|
+
"Swap Down" "d" "swap-pane -D" \
|
|
114
|
+
"" "" "" \
|
|
115
|
+
"Kill Pane" "x" "confirm-before -p 'Kill pane? (y/n)' kill-pane"
|
|
116
|
+
|
|
117
|
+
# ── Mouse binding ─────────────────────────────────────────────────────────────────────────────
|
|
118
|
+
bind -T root MouseDown1Status {
|
|
119
|
+
if -F '#{==:#{mouse_status_range},actions}' {
|
|
120
|
+
display-popup -E -d '#{pane_current_path}' -xC -yS -w 92 -h 22 "python3 ~/.config/tmux/bin/actions_popup.py '#{pane_id}'"
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
bind -T root MouseUp1Status {
|
|
124
|
+
if -F '#{!=:#{mouse_status_range},actions}' {
|
|
125
|
+
run-shell -b "~/.config/tmux/bin/dispatch.sh '#{mouse_status_range}' '#{pane_id}'"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# WSL2 xclip shim — routes xclip calls to the Windows clipboard.
|
|
3
|
+
# Supports the common usage patterns that tmux-yank and other tools expect.
|
|
4
|
+
# Read (stdout): xclip -selection clipboard -o
|
|
5
|
+
# Write (stdin): xclip -selection clipboard
|
|
6
|
+
|
|
7
|
+
OUT=0
|
|
8
|
+
for arg in "$@"; do
|
|
9
|
+
[ "$arg" = "-o" ] || [ "$arg" = "-out" ] && OUT=1
|
|
10
|
+
done
|
|
11
|
+
|
|
12
|
+
if [ "$OUT" -eq 1 ]; then
|
|
13
|
+
powershell.exe -NoProfile -Command \
|
|
14
|
+
"[Console]::OutputEncoding=[System.Text.Encoding]::UTF8; Get-Clipboard" \
|
|
15
|
+
2>/dev/null | tr -d '\r'
|
|
16
|
+
else
|
|
17
|
+
clip.exe
|
|
18
|
+
fi
|