@humanu/orchestra 0.5.75 → 0.5.77
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 +1 -1
- package/resources/api/tmux.sh +152 -8
- package/resources/prebuilt/linux-x64/orchestra +0 -0
- package/resources/prebuilt/macos-arm64/orchestra +0 -0
- package/resources/prebuilt/macos-intel/orchestra +0 -0
- package/resources/scripts/gw-bridge.sh +12 -0
- package/resources/scripts/shell/bridge/tmux.sh +40 -0
package/package.json
CHANGED
package/resources/api/tmux.sh
CHANGED
|
@@ -506,9 +506,18 @@ _tmux_truncate_tab_label() {
|
|
|
506
506
|
fi
|
|
507
507
|
}
|
|
508
508
|
|
|
509
|
+
_tmux_pad_menu_label() {
|
|
510
|
+
local label="$1"
|
|
511
|
+
local width="${2:-56}"
|
|
512
|
+
|
|
513
|
+
label="$(_tmux_truncate_tab_label "$label" "$width")"
|
|
514
|
+
printf '%-*s' "$width" "$label"
|
|
515
|
+
}
|
|
516
|
+
|
|
509
517
|
_tmux_workspace_session_rows() {
|
|
510
518
|
local current_session="$1"
|
|
511
519
|
local repo_root="$2"
|
|
520
|
+
local mode="${3:-visible}"
|
|
512
521
|
local db_path active_file
|
|
513
522
|
db_path="$(_tmux_session_registry_path)"
|
|
514
523
|
|
|
@@ -521,11 +530,11 @@ _tmux_workspace_session_rows() {
|
|
|
521
530
|
return 0
|
|
522
531
|
}
|
|
523
532
|
|
|
524
|
-
python3 - "$db_path" "$repo_root" "$current_session" "$active_file" <<'PY'
|
|
533
|
+
python3 - "$db_path" "$repo_root" "$current_session" "$active_file" "$mode" <<'PY'
|
|
525
534
|
import sqlite3
|
|
526
535
|
import sys
|
|
527
536
|
|
|
528
|
-
db_path, repo_root, current_session, active_path = sys.argv[1:
|
|
537
|
+
db_path, repo_root, current_session, active_path, mode = sys.argv[1:6]
|
|
529
538
|
with open(active_path, "r", encoding="utf-8") as handle:
|
|
530
539
|
active = {line.strip() for line in handle if line.strip()}
|
|
531
540
|
|
|
@@ -551,7 +560,7 @@ if not filtered:
|
|
|
551
560
|
raise SystemExit(0)
|
|
552
561
|
|
|
553
562
|
max_tabs = 8
|
|
554
|
-
if len(filtered) <= max_tabs:
|
|
563
|
+
if mode == "all" or len(filtered) <= max_tabs:
|
|
555
564
|
visible = filtered
|
|
556
565
|
prefix = suffix = False
|
|
557
566
|
else:
|
|
@@ -636,10 +645,21 @@ _tmux_workspace_session_tabs() {
|
|
|
636
645
|
printf '%s' "$tabs"
|
|
637
646
|
}
|
|
638
647
|
|
|
648
|
+
_tmux_current_session_label() {
|
|
649
|
+
local session_display_name="$1"
|
|
650
|
+
local label escaped_label
|
|
651
|
+
|
|
652
|
+
label="$(_tmux_truncate_tab_label "$session_display_name" 28)"
|
|
653
|
+
escaped_label="$(_tmux_status_escape_text "$label")"
|
|
654
|
+
printf '#[fg=#7aa2f7,bg=#1a1b26,bold] %s #[fg=#565f89,bg=#1a1b26,nobold]│#[default]' "$escaped_label"
|
|
655
|
+
}
|
|
656
|
+
|
|
639
657
|
_tmux_orchestra_status_left() {
|
|
640
658
|
local session_name="$1"
|
|
641
659
|
local session_display_name="$3"
|
|
642
|
-
|
|
660
|
+
printf '%s%s' \
|
|
661
|
+
"$(_tmux_current_session_label "$session_display_name")" \
|
|
662
|
+
"$(_tmux_workspace_session_tabs "$session_name" "$session_display_name")"
|
|
643
663
|
}
|
|
644
664
|
|
|
645
665
|
_tmux_orchestra_status_right() {
|
|
@@ -651,14 +671,17 @@ _tmux_configure_orchestra_bindings() {
|
|
|
651
671
|
bridge="$(_orchestra_bridge_script)"
|
|
652
672
|
[[ -f "$bridge" ]] || return
|
|
653
673
|
|
|
654
|
-
local quoted_bridge rename_command prompt_command next_command previous_command new_session_command help_command
|
|
674
|
+
local quoted_bridge rename_command prompt_command next_command previous_command new_session_command list_command close_command close_prompt_command help_command
|
|
655
675
|
printf -v quoted_bridge '%q' "$bridge"
|
|
656
676
|
rename_command="$quoted_bridge manual-rename-session \\\"#{session_name}\\\" \\\"%%\\\" >/dev/null 2>&1"
|
|
657
677
|
prompt_command="command-prompt -p 'Rename Orchestra session:' 'run-shell -b \"$rename_command\"'"
|
|
658
678
|
next_command="$quoted_bridge cycle-workspace-session \\\"#{session_name}\\\" next \\\"#{client_tty}\\\" >/dev/null 2>&1"
|
|
659
679
|
previous_command="$quoted_bridge cycle-workspace-session \\\"#{session_name}\\\" previous \\\"#{client_tty}\\\" >/dev/null 2>&1"
|
|
660
|
-
new_session_command="$quoted_bridge create-workspace-session \\\"#{session_name}\\\" \\\"#{client_tty}\\\" >/dev/null 2>&1"
|
|
661
|
-
|
|
680
|
+
new_session_command="$quoted_bridge create-workspace-session \\\"#{session_name}\\\" \\\"#{client_tty}\\\" >/dev/null 2>&1 || true"
|
|
681
|
+
list_command="$quoted_bridge workspace-session-menu \\\"#{session_name}\\\" \\\"#{client_tty}\\\" >/dev/null 2>&1 || true"
|
|
682
|
+
close_command="$quoted_bridge close-workspace-session \\\"#{session_name}\\\" \\\"#{client_tty}\\\" >/dev/null 2>&1 || true"
|
|
683
|
+
close_prompt_command="confirm-before -p 'Close current Orchestra session? (y/n)' 'run-shell -b \"$close_command\"'"
|
|
684
|
+
help_command="$quoted_bridge tmux-help-popup \\\"#{client_tty}\\\" >/dev/null 2>&1 || true"
|
|
662
685
|
|
|
663
686
|
tmux bind-key -T prefix '?' if-shell -F '#{@orchestra_display_name}' \
|
|
664
687
|
"run-shell -b \"$help_command\"" 'list-keys -N' >/dev/null 2>&1 || true
|
|
@@ -666,6 +689,12 @@ _tmux_configure_orchestra_bindings() {
|
|
|
666
689
|
"run-shell -b \"$help_command\"" 'refresh-client -S' >/dev/null 2>&1 || true
|
|
667
690
|
tmux bind-key -T prefix n if-shell -F '#{@orchestra_display_name}' \
|
|
668
691
|
"run-shell -b \"$new_session_command\"" 'next-window' >/dev/null 2>&1 || true
|
|
692
|
+
tmux bind-key -T prefix l if-shell -F '#{@orchestra_display_name}' \
|
|
693
|
+
"run-shell -b \"$list_command\"" 'last-window' >/dev/null 2>&1 || true
|
|
694
|
+
tmux bind-key -T prefix q if-shell -F '#{@orchestra_display_name}' \
|
|
695
|
+
"$close_prompt_command" 'display-panes' >/dev/null 2>&1 || true
|
|
696
|
+
tmux bind-key -T prefix X if-shell -F '#{@orchestra_display_name}' \
|
|
697
|
+
"$close_prompt_command" 'confirm-before -p "kill-session #S? (y/n)" kill-session' >/dev/null 2>&1 || true
|
|
669
698
|
tmux bind-key -T prefix r if-shell -F '#{@orchestra_display_name}' \
|
|
670
699
|
"$prompt_command" 'refresh-client -S' >/dev/null 2>&1 || true
|
|
671
700
|
tmux bind-key -T prefix '>' if-shell -F '#{@orchestra_display_name}' \
|
|
@@ -944,6 +973,37 @@ tmux_create_workspace_session() {
|
|
|
944
973
|
printf '%s\n' "$new_session"
|
|
945
974
|
}
|
|
946
975
|
|
|
976
|
+
# Close the current Orchestra session after switching the client to the next one.
|
|
977
|
+
# Usage: tmux_close_workspace_session <current_session> [client_tty]
|
|
978
|
+
tmux_close_workspace_session() {
|
|
979
|
+
local current_session="$1"
|
|
980
|
+
local target_client="${2:-}"
|
|
981
|
+
local target_session
|
|
982
|
+
|
|
983
|
+
if ! tmux_available; then
|
|
984
|
+
err "tmux not installed"
|
|
985
|
+
return 1
|
|
986
|
+
fi
|
|
987
|
+
if [[ -z "$current_session" ]]; then
|
|
988
|
+
err "tmux_close_workspace_session: current session required"
|
|
989
|
+
return 1
|
|
990
|
+
fi
|
|
991
|
+
|
|
992
|
+
if ! target_session="$(tmux_workspace_cycle_target "$current_session" next)"; then
|
|
993
|
+
tmux display-message -d 2500 "No other Orchestra sessions; current session kept" 2>/dev/null || true
|
|
994
|
+
return 1
|
|
995
|
+
fi
|
|
996
|
+
|
|
997
|
+
if [[ -n "$target_client" ]]; then
|
|
998
|
+
tmux switch-client -c "$target_client" -t "$target_session" >/dev/null 2>&1 || return 1
|
|
999
|
+
else
|
|
1000
|
+
tmux switch-client -t "$target_session" >/dev/null 2>&1 || return 1
|
|
1001
|
+
fi
|
|
1002
|
+
|
|
1003
|
+
tmux_kill_session "$current_session" >/dev/null 2>&1 || return 1
|
|
1004
|
+
_tmux_refresh_orchestra_session_status "$target_session" >/dev/null 2>&1 || true
|
|
1005
|
+
}
|
|
1006
|
+
|
|
947
1007
|
# Check if a session exists
|
|
948
1008
|
# Usage: tmux_session_exists <session_name>
|
|
949
1009
|
tmux_session_exists() {
|
|
@@ -1556,6 +1616,8 @@ printf "%s\n" \
|
|
|
1556
1616
|
"Ctrl+b, d Detach and return to Orchestra" \
|
|
1557
1617
|
"Ctrl+b, r Rename the current Orchestra session" \
|
|
1558
1618
|
"Ctrl+b, n New Orchestra session in this worktree" \
|
|
1619
|
+
"Ctrl+b, q Close current session and switch next" \
|
|
1620
|
+
"Ctrl+b, l List active sessions" \
|
|
1559
1621
|
"" \
|
|
1560
1622
|
"Ctrl+b, Left Previous Orchestra session in this workspace" \
|
|
1561
1623
|
"Ctrl+b, Right Next Orchestra session in this workspace" \
|
|
@@ -1573,7 +1635,89 @@ exit 0
|
|
|
1573
1635
|
EOF
|
|
1574
1636
|
)"
|
|
1575
1637
|
|
|
1576
|
-
tmux display-popup "${target_args[@]}"
|
|
1638
|
+
tmux display-popup "${target_args[@]}" \
|
|
1639
|
+
-E \
|
|
1640
|
+
-w 84 \
|
|
1641
|
+
-h 22 \
|
|
1642
|
+
-s "fg=#c0caf5,bg=#1a1b26" \
|
|
1643
|
+
-S "fg=#7aa2f7,bg=#1a1b26" \
|
|
1644
|
+
-T "Orchestra shortcuts" \
|
|
1645
|
+
"$popup_command" >/dev/null 2>&1 || true
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
# Show active Orchestra sessions in a native tmux menu for arrow-key selection.
|
|
1649
|
+
# Usage: tmux_show_workspace_session_menu <current_session> [client_tty]
|
|
1650
|
+
tmux_show_workspace_session_menu() {
|
|
1651
|
+
local current_session="$1"
|
|
1652
|
+
local target_client="${2:-}"
|
|
1653
|
+
local session_dir repo_root rows name display_name label target_command
|
|
1654
|
+
local menu_width=56
|
|
1655
|
+
local min_menu_rows=10
|
|
1656
|
+
local menu_row_count=0
|
|
1657
|
+
|
|
1658
|
+
if ! tmux_available; then
|
|
1659
|
+
err "tmux not installed"
|
|
1660
|
+
return 1
|
|
1661
|
+
fi
|
|
1662
|
+
if [[ -z "$current_session" ]]; then
|
|
1663
|
+
err "tmux_show_workspace_session_menu: current session required"
|
|
1664
|
+
return 1
|
|
1665
|
+
fi
|
|
1666
|
+
|
|
1667
|
+
session_dir="$(tmux display-message -t "$current_session" -p '#{pane_current_path}' 2>/dev/null || echo "")"
|
|
1668
|
+
repo_root="$(_tmux_shared_root_for_path "$session_dir" 2>/dev/null || true)"
|
|
1669
|
+
if [[ -z "$repo_root" ]]; then
|
|
1670
|
+
tmux display-message -d 2500 "Unable to determine Orchestra workspace" 2>/dev/null || true
|
|
1671
|
+
return 1
|
|
1672
|
+
fi
|
|
1673
|
+
|
|
1674
|
+
_tmux_registry_sync_active_workspace_sessions "$repo_root" >/dev/null 2>&1 || true
|
|
1675
|
+
rows="$(_tmux_workspace_session_rows "$current_session" "$repo_root" all 2>/dev/null || true)"
|
|
1676
|
+
if [[ -z "$rows" ]]; then
|
|
1677
|
+
tmux display-message -d 2500 "No active Orchestra sessions in this workspace" 2>/dev/null || true
|
|
1678
|
+
return 1
|
|
1679
|
+
fi
|
|
1680
|
+
|
|
1681
|
+
local target_args=()
|
|
1682
|
+
if [[ -n "$target_client" ]]; then
|
|
1683
|
+
target_args=(-c "$target_client")
|
|
1684
|
+
fi
|
|
1685
|
+
|
|
1686
|
+
local menu_items=()
|
|
1687
|
+
while IFS=$'\t' read -r name display_name; do
|
|
1688
|
+
[[ -n "$name" && "$name" != "__ellipsis__" ]] || continue
|
|
1689
|
+
if [[ -z "$display_name" ]]; then
|
|
1690
|
+
display_name="$(tmux_format_session_display "$name" without-timestamp)"
|
|
1691
|
+
fi
|
|
1692
|
+
label="$(_tmux_truncate_tab_label "$display_name" 42)"
|
|
1693
|
+
if [[ "$name" == "$current_session" ]]; then
|
|
1694
|
+
label="● $label"
|
|
1695
|
+
else
|
|
1696
|
+
label=" $label"
|
|
1697
|
+
fi
|
|
1698
|
+
label="$(_tmux_pad_menu_label "$label" "$menu_width")"
|
|
1699
|
+
label="$(_tmux_status_escape_text "$label")"
|
|
1700
|
+
target_command="switch-client -t \"$name\""
|
|
1701
|
+
menu_items+=("$label" "" "$target_command")
|
|
1702
|
+
menu_row_count=$((menu_row_count + 1))
|
|
1703
|
+
done <<< "$rows"
|
|
1704
|
+
|
|
1705
|
+
if [[ ${#menu_items[@]} -eq 0 ]]; then
|
|
1706
|
+
tmux display-message -d 2500 "No active Orchestra sessions in this workspace" 2>/dev/null || true
|
|
1707
|
+
return 1
|
|
1708
|
+
fi
|
|
1709
|
+
|
|
1710
|
+
while (( menu_row_count < min_menu_rows )); do
|
|
1711
|
+
menu_items+=("$(_tmux_pad_menu_label "" "$menu_width")" "" "")
|
|
1712
|
+
menu_row_count=$((menu_row_count + 1))
|
|
1713
|
+
done
|
|
1714
|
+
|
|
1715
|
+
tmux display-menu "${target_args[@]}" \
|
|
1716
|
+
-s "fg=#c0caf5,bg=#1a1b26" \
|
|
1717
|
+
-S "fg=#7aa2f7,bg=#1a1b26" \
|
|
1718
|
+
-H "fg=#1a1b26,bg=#ff9e64,bold" \
|
|
1719
|
+
-T "Orchestra sessions" \
|
|
1720
|
+
"${menu_items[@]}" >/dev/null 2>&1 || true
|
|
1577
1721
|
}
|
|
1578
1722
|
|
|
1579
1723
|
# Find the adjacent active Orchestra session registered for the current repo.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -102,6 +102,14 @@ case "${1:-}" in
|
|
|
102
102
|
bridge_create_workspace_session "${2:-}" "${3:-}"
|
|
103
103
|
;;
|
|
104
104
|
|
|
105
|
+
"close-workspace-session")
|
|
106
|
+
bridge_close_workspace_session "${2:-}" "${3:-}"
|
|
107
|
+
;;
|
|
108
|
+
|
|
109
|
+
"workspace-session-menu")
|
|
110
|
+
bridge_workspace_session_menu "${2:-}" "${3:-}"
|
|
111
|
+
;;
|
|
112
|
+
|
|
105
113
|
"kill-session")
|
|
106
114
|
bridge_kill_session "${2:-}"
|
|
107
115
|
;;
|
|
@@ -249,6 +257,10 @@ Commands:
|
|
|
249
257
|
Switch within registered Orchestra sessions for this repo
|
|
250
258
|
create-workspace-session <session> [client]
|
|
251
259
|
Create a new session in the current worktree and switch to it
|
|
260
|
+
close-workspace-session <session> [client]
|
|
261
|
+
Close current session after switching to the next one
|
|
262
|
+
workspace-session-menu <session> [client]
|
|
263
|
+
Show an interactive active-session menu
|
|
252
264
|
tmux-help-popup [client] Show Orchestra tmux shortcut popup
|
|
253
265
|
repo-info Get repository information
|
|
254
266
|
git-status Get git status --porcelain
|
|
@@ -82,6 +82,46 @@ bridge_create_workspace_session() {
|
|
|
82
82
|
fi
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
# Close current tmux session after switching to the next workspace session.
|
|
86
|
+
bridge_close_workspace_session() {
|
|
87
|
+
if [[ -z "${1:-}" ]]; then
|
|
88
|
+
json_error "Current session name required"
|
|
89
|
+
return 1
|
|
90
|
+
fi
|
|
91
|
+
session_name="$1"
|
|
92
|
+
target_client="${2:-}"
|
|
93
|
+
|
|
94
|
+
if tmux_available; then
|
|
95
|
+
tmux_close_workspace_session "$session_name" "$target_client" || {
|
|
96
|
+
json_error "Failed to close workspace session"
|
|
97
|
+
return 1
|
|
98
|
+
}
|
|
99
|
+
json_object "ok:b=true"
|
|
100
|
+
else
|
|
101
|
+
json_error "tmux not available"
|
|
102
|
+
fi
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
# Show interactive workspace session menu.
|
|
106
|
+
bridge_workspace_session_menu() {
|
|
107
|
+
if [[ -z "${1:-}" ]]; then
|
|
108
|
+
json_error "Current session name required"
|
|
109
|
+
return 1
|
|
110
|
+
fi
|
|
111
|
+
session_name="$1"
|
|
112
|
+
target_client="${2:-}"
|
|
113
|
+
|
|
114
|
+
if tmux_available; then
|
|
115
|
+
tmux_show_workspace_session_menu "$session_name" "$target_client" || {
|
|
116
|
+
json_error "Failed to show workspace session menu"
|
|
117
|
+
return 1
|
|
118
|
+
}
|
|
119
|
+
json_object "ok:b=true"
|
|
120
|
+
else
|
|
121
|
+
json_error "tmux not available"
|
|
122
|
+
fi
|
|
123
|
+
}
|
|
124
|
+
|
|
85
125
|
# Kill tmux session
|
|
86
126
|
bridge_kill_session() {
|
|
87
127
|
if [[ -z "${1:-}" ]]; then
|