@humanu/orchestra 0.5.65 → 0.5.66
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 +130 -12
- 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/shell/bridge/ai.sh +10 -0
- package/resources/scripts/shell/bridge/tmux.sh +22 -2
- package/resources/scripts/shell/orchestra-command-hook.sh +101 -0
package/package.json
CHANGED
package/resources/api/tmux.sh
CHANGED
|
@@ -109,6 +109,57 @@ _tmux_normalize_app_from_command() {
|
|
|
109
109
|
printf '%s' "$base"
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
_tmux_truthy() {
|
|
113
|
+
case "$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')" in
|
|
114
|
+
1|yes|true|on)
|
|
115
|
+
return 0
|
|
116
|
+
;;
|
|
117
|
+
esac
|
|
118
|
+
return 1
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
_tmux_is_known_tui_app() {
|
|
122
|
+
local app
|
|
123
|
+
app="$(_tmux_normalize_app_from_command "$1")"
|
|
124
|
+
case "$app" in
|
|
125
|
+
opencode|claude|vim|nvim|vi|lazygit|gitui|tig|top|htop|btop|k9s|fzf|yazi|ranger|nnn|less|man)
|
|
126
|
+
return 0
|
|
127
|
+
;;
|
|
128
|
+
esac
|
|
129
|
+
return 1
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
_tmux_is_tui_context() {
|
|
133
|
+
local pane_cmd="$1"
|
|
134
|
+
local alternate_on="$2"
|
|
135
|
+
local mouse_any_flag="$3"
|
|
136
|
+
local pane_mode="$4"
|
|
137
|
+
local window_name="$5"
|
|
138
|
+
local pane_title="$6"
|
|
139
|
+
|
|
140
|
+
if _tmux_truthy "$alternate_on" || _tmux_truthy "$mouse_any_flag"; then
|
|
141
|
+
return 0
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
if [[ -n "$pane_mode" ]]; then
|
|
145
|
+
return 0
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
if _tmux_is_known_tui_app "$pane_cmd"; then
|
|
149
|
+
return 0
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
local combined
|
|
153
|
+
combined="$(printf '%s %s' "$window_name" "$pane_title" | tr '[:upper:]' '[:lower:]')"
|
|
154
|
+
case "$combined" in
|
|
155
|
+
*opencode*|*claude*|*vim*|*nvim*|*lazygit*|*gitui*|*tig*|*k9s*|*fzf*|*yazi*|*ranger*|*nnn*)
|
|
156
|
+
return 0
|
|
157
|
+
;;
|
|
158
|
+
esac
|
|
159
|
+
|
|
160
|
+
return 1
|
|
161
|
+
}
|
|
162
|
+
|
|
112
163
|
# Helper: absolute path to the command hook script (if present)
|
|
113
164
|
_orchestra_command_hook() {
|
|
114
165
|
local hook=""
|
|
@@ -1077,15 +1128,13 @@ tmux_generate_ai_session_name() {
|
|
|
1077
1128
|
|
|
1078
1129
|
local openai_model="${OPENAI_MODEL:-gpt-4o-mini}"
|
|
1079
1130
|
|
|
1080
|
-
|
|
1081
|
-
local content
|
|
1082
|
-
content="$(tmux capture-pane -t "$session" -p -S -200 2>/dev/null)" || {
|
|
1083
|
-
err "Failed to capture tmux pane content"
|
|
1084
|
-
return 1
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
local pane_cmd
|
|
1131
|
+
local pane_cmd pane_mode window_name pane_title alternate_on mouse_any_flag
|
|
1088
1132
|
pane_cmd="$(tmux display-message -t "$session" -p '#{pane_current_command}' 2>/dev/null || echo "")"
|
|
1133
|
+
pane_mode="$(tmux display-message -t "$session" -p '#{pane_mode}' 2>/dev/null || echo "")"
|
|
1134
|
+
window_name="$(tmux display-message -t "$session" -p '#{window_name}' 2>/dev/null || echo "")"
|
|
1135
|
+
pane_title="$(tmux display-message -t "$session" -p '#{pane_title}' 2>/dev/null || echo "")"
|
|
1136
|
+
alternate_on="$(tmux display-message -t "$session" -p '#{alternate_on}' 2>/dev/null || echo "0")"
|
|
1137
|
+
mouse_any_flag="$(tmux display-message -t "$session" -p '#{mouse_any_flag}' 2>/dev/null || echo "0")"
|
|
1089
1138
|
|
|
1090
1139
|
local history_temp=""
|
|
1091
1140
|
local history_arg=""
|
|
@@ -1100,6 +1149,27 @@ tmux_generate_ai_session_name() {
|
|
|
1100
1149
|
local session_key
|
|
1101
1150
|
session_key="$(_orchestra_history_key "$session")"
|
|
1102
1151
|
|
|
1152
|
+
local is_tui="false"
|
|
1153
|
+
if _tmux_is_tui_context "$pane_cmd" "$alternate_on" "$mouse_any_flag" "$pane_mode" "$window_name" "$pane_title"; then
|
|
1154
|
+
is_tui="true"
|
|
1155
|
+
fi
|
|
1156
|
+
|
|
1157
|
+
local content=""
|
|
1158
|
+
local visible_content=""
|
|
1159
|
+
if [[ "$is_tui" == "true" ]]; then
|
|
1160
|
+
visible_content="$(tmux capture-pane -e -p -q -a -t "${pane_id:-$session}" 2>/dev/null || echo "")"
|
|
1161
|
+
fi
|
|
1162
|
+
local scrollback_content
|
|
1163
|
+
scrollback_content="$(tmux capture-pane -t "$session" -p -S -200 2>/dev/null)" || {
|
|
1164
|
+
err "Failed to capture tmux pane content"
|
|
1165
|
+
return 1
|
|
1166
|
+
}
|
|
1167
|
+
if [[ -n "$visible_content" ]]; then
|
|
1168
|
+
content="### Visible terminal view\n${visible_content}\n\n### Recent scrollback\n${scrollback_content}"
|
|
1169
|
+
else
|
|
1170
|
+
content="$scrollback_content"
|
|
1171
|
+
fi
|
|
1172
|
+
|
|
1103
1173
|
local app_source_path=""
|
|
1104
1174
|
if [[ -n "$pane_key" && -f "$history_dir/$pane_key.last_app" ]]; then
|
|
1105
1175
|
app_source_path="$history_dir/$pane_key.last_app"
|
|
@@ -1131,6 +1201,16 @@ tmux_generate_ai_session_name() {
|
|
|
1131
1201
|
history_arg="$history_temp"
|
|
1132
1202
|
fi
|
|
1133
1203
|
|
|
1204
|
+
local metadata_block=""
|
|
1205
|
+
metadata_block+="Session metadata:\n"
|
|
1206
|
+
metadata_block+="- pane_current_command: ${pane_cmd:-unknown}\n"
|
|
1207
|
+
metadata_block+="- window_name: ${window_name:-}\n"
|
|
1208
|
+
metadata_block+="- pane_title: ${pane_title:-}\n"
|
|
1209
|
+
metadata_block+="- pane_mode: ${pane_mode:-}\n"
|
|
1210
|
+
metadata_block+="- alternate_screen_active: ${alternate_on:-0}\n"
|
|
1211
|
+
metadata_block+="- mouse_mode_active: ${mouse_any_flag:-0}\n"
|
|
1212
|
+
metadata_block+="- likely_tui_app: ${is_tui}\n"
|
|
1213
|
+
|
|
1134
1214
|
# If content is empty or too short, keep a placeholder
|
|
1135
1215
|
if [[ ${#content} -lt 10 ]]; then
|
|
1136
1216
|
content="(no terminal output captured)"
|
|
@@ -1157,7 +1237,7 @@ tmux_generate_ai_session_name() {
|
|
|
1157
1237
|
if have_cmd python3; then
|
|
1158
1238
|
# Use Python to safely build the request body and extract typed commands from the capture
|
|
1159
1239
|
request_payload=$(
|
|
1160
|
-
python3 - "$temp_file" "$history_arg" "$provider" "$openai_model" 2>/dev/null <<'PYCODE'
|
|
1240
|
+
python3 - "$temp_file" "$history_arg" "$provider" "$openai_model" "$pane_cmd" "$window_name" "$pane_title" "$pane_mode" "$alternate_on" "$mouse_any_flag" "$is_tui" 2>/dev/null <<'PYCODE'
|
|
1161
1241
|
import json
|
|
1162
1242
|
import re
|
|
1163
1243
|
import sys
|
|
@@ -1168,6 +1248,13 @@ content = temp_path.read_text()
|
|
|
1168
1248
|
history_arg = sys.argv[2] if len(sys.argv) > 2 else ""
|
|
1169
1249
|
provider = sys.argv[3] if len(sys.argv) > 3 else "anthropic"
|
|
1170
1250
|
openai_model = sys.argv[4] if len(sys.argv) > 4 and sys.argv[4] else "gpt-4o-mini"
|
|
1251
|
+
pane_cmd = sys.argv[5] if len(sys.argv) > 5 else ""
|
|
1252
|
+
window_name = sys.argv[6] if len(sys.argv) > 6 else ""
|
|
1253
|
+
pane_title = sys.argv[7] if len(sys.argv) > 7 else ""
|
|
1254
|
+
pane_mode = sys.argv[8] if len(sys.argv) > 8 else ""
|
|
1255
|
+
alternate_on = sys.argv[9] if len(sys.argv) > 9 else "0"
|
|
1256
|
+
mouse_any_flag = sys.argv[10] if len(sys.argv) > 10 else "0"
|
|
1257
|
+
is_tui = sys.argv[11] if len(sys.argv) > 11 else "false"
|
|
1171
1258
|
|
|
1172
1259
|
lines = content.splitlines()
|
|
1173
1260
|
command_candidates = [] # Commands captured with high confidence
|
|
@@ -1444,11 +1531,28 @@ description_guidance = """Description rules:
|
|
|
1444
1531
|
- Do NOT include any app/tool name or prefix in the output.
|
|
1445
1532
|
- If git activity is visible, the description should reflect it (e.g., reviewing changes), but do not add 'git_'."""
|
|
1446
1533
|
|
|
1534
|
+
metadata_summary = "\n".join(
|
|
1535
|
+
line
|
|
1536
|
+
for line in [
|
|
1537
|
+
f"pane_current_command: {pane_cmd}" if pane_cmd else "",
|
|
1538
|
+
f"window_name: {window_name}" if window_name else "",
|
|
1539
|
+
f"pane_title: {pane_title}" if pane_title else "",
|
|
1540
|
+
f"pane_mode: {pane_mode}" if pane_mode else "",
|
|
1541
|
+
f"alternate_screen_active: {alternate_on}",
|
|
1542
|
+
f"mouse_mode_active: {mouse_any_flag}",
|
|
1543
|
+
f"likely_tui_app: {is_tui}",
|
|
1544
|
+
]
|
|
1545
|
+
if line
|
|
1546
|
+
)
|
|
1547
|
+
|
|
1447
1548
|
prompt = f"""Analyze this terminal session and create a descriptive tmux session name based on what the user actually did.
|
|
1448
1549
|
|
|
1449
1550
|
Terminal output (last capture):
|
|
1450
1551
|
{content}
|
|
1451
1552
|
|
|
1553
|
+
Tmux metadata (use as supporting hints, not as the primary source of truth):
|
|
1554
|
+
{metadata_summary}
|
|
1555
|
+
|
|
1452
1556
|
Extracted command history (oldest to newest):
|
|
1453
1557
|
{command_history}
|
|
1454
1558
|
|
|
@@ -1460,6 +1564,8 @@ Focus: produce a concise description of the activity. Follow these rules:
|
|
|
1460
1564
|
|
|
1461
1565
|
{'No clear prompt/command lines were detected. Rely on the terminal output context.' if not commands_detected else ''}
|
|
1462
1566
|
|
|
1567
|
+
{'An interactive TUI is likely running. Prefer the visible screen content plus recent command history over generic app names.' if is_tui.lower() in {'1', 'true', 'yes', 'on'} else ''}
|
|
1568
|
+
|
|
1463
1569
|
{'First 10 lines of terminal output (useful for identifying running app/service):\n' + first_ten_lines if not commands_detected and first_ten_lines else ''}
|
|
1464
1570
|
|
|
1465
1571
|
If no commands were detected, fall back to terminal output analysis but describe the main activity in the name. Identify the dominant application or process implied by the output (e.g., web server, test runner, build tool).
|
|
@@ -1545,7 +1651,18 @@ PYCODE
|
|
|
1545
1651
|
if [[ -z "$request_body" ]]; then
|
|
1546
1652
|
# Fallback: base64 encode the content to avoid escaping issues
|
|
1547
1653
|
local encoded_content
|
|
1548
|
-
|
|
1654
|
+
local fallback_file
|
|
1655
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
1656
|
+
fallback_file=$(mktemp -t gw_fb)
|
|
1657
|
+
else
|
|
1658
|
+
fallback_file=$(mktemp)
|
|
1659
|
+
fi
|
|
1660
|
+
{
|
|
1661
|
+
printf '%b\n\n' "$metadata_block"
|
|
1662
|
+
cat "$temp_file"
|
|
1663
|
+
} > "$fallback_file"
|
|
1664
|
+
encoded_content=$(base64 < "$fallback_file" | tr -d '\n')
|
|
1665
|
+
rm -f "$fallback_file"
|
|
1549
1666
|
if [[ "$provider" == "openai" ]]; then
|
|
1550
1667
|
request_body=$(cat <<EOF
|
|
1551
1668
|
{
|
|
@@ -1555,7 +1672,7 @@ PYCODE
|
|
|
1555
1672
|
"messages": [
|
|
1556
1673
|
{
|
|
1557
1674
|
"role": "user",
|
|
1558
|
-
"content": "I'll send you base64-encoded terminal output. Please decode it, analyze it, and create a descriptive name for this tmux session.\n\nIMPORTANT:
|
|
1675
|
+
"content": "I'll send you base64-encoded terminal output. Please decode it, analyze it, and create a descriptive name for this tmux session.\n\nIMPORTANT: Use terminal metadata only as supporting hints. Prioritize the visible terminal content and recent command history.\n\nCRITICAL: Check for Git patterns FIRST:\n- Git commands: git status, diff, add, commit, push, pull, checkout, branch, merge, rebase, log, stash\n- Git output: 'On branch', 'Changes not staged', 'modified:', 'new file:', diff output (+/-/@@), commit hashes\n- If ANY Git patterns found, the description should reflect git activity (but do not add 'git_').\n\nDESCRIPTION ONLY: Return a short description of the activity.\n- Do NOT include the app/tool name or any prefix in the output.\n\nUse underscores only. Max 100 chars total.\n\nExamples:\n- reviewing_changes_before_commit\n- resolving_merge_conflicts\n- fixing_auth_bug\n- running_nextjs_dev_server\n\nBase64 terminal output:\n${encoded_content}\n\nRespond with ONLY the session name, nothing else."
|
|
1559
1676
|
}
|
|
1560
1677
|
]
|
|
1561
1678
|
}
|
|
@@ -1569,7 +1686,7 @@ EOF
|
|
|
1569
1686
|
"messages": [
|
|
1570
1687
|
{
|
|
1571
1688
|
"role": "user",
|
|
1572
|
-
"content": "I'll send you base64-encoded terminal output. Please decode it, analyze it, and create a descriptive name for this tmux session.\n\nIMPORTANT:
|
|
1689
|
+
"content": "I'll send you base64-encoded terminal output. Please decode it, analyze it, and create a descriptive name for this tmux session.\n\nIMPORTANT: Use terminal metadata only as supporting hints. Prioritize the visible terminal content and recent command history.\n\nCRITICAL: Check for Git patterns FIRST:\n- Git commands: git status, diff, add, commit, push, pull, checkout, branch, merge, rebase, log, stash\n- Git output: 'On branch', 'Changes not staged', 'modified:', 'new file:', diff output (+/-/@@), commit hashes\n- If ANY Git patterns found, the description should reflect git activity (but do not add 'git_').\n\nDESCRIPTION ONLY: Return a short description of the activity.\n- Do NOT include the app/tool name or any prefix in the output.\n\nUse underscores only. Max 100 chars total.\n\nExamples:\n- reviewing_changes_before_commit\n- resolving_merge_conflicts\n- fixing_auth_bug\n- running_nextjs_dev_server\n\nBase64 terminal output:\n${encoded_content}\n\nRespond with ONLY the session name, nothing else."
|
|
1573
1690
|
}
|
|
1574
1691
|
]
|
|
1575
1692
|
}
|
|
@@ -1591,6 +1708,7 @@ EOF
|
|
|
1591
1708
|
context_file=$(mktemp)
|
|
1592
1709
|
fi
|
|
1593
1710
|
{
|
|
1711
|
+
printf '%b\n\n' "$metadata_block"
|
|
1594
1712
|
printf 'TMUX SESSION CAPTURE\n\n'
|
|
1595
1713
|
cat "$temp_file"
|
|
1596
1714
|
if [[ -n "$history_arg" && -f "$history_arg" ]]; then
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -191,11 +191,18 @@ bridge_rename_session() {
|
|
|
191
191
|
fi
|
|
192
192
|
original_session_name="$1"
|
|
193
193
|
|
|
194
|
+
clear_auto_rename_requested() {
|
|
195
|
+
if tmux_available && tmux_session_exists "$original_session_name"; then
|
|
196
|
+
tmux set-option -qu -t "$original_session_name" @orchestra_auto_rename_requested >/dev/null 2>&1 || true
|
|
197
|
+
fi
|
|
198
|
+
}
|
|
199
|
+
|
|
194
200
|
# Load API key from config file or fallback to .env
|
|
195
201
|
load_openai_api_key
|
|
196
202
|
load_anthropic_api_key
|
|
197
203
|
|
|
198
204
|
if [[ -z "${OPENAI_API_KEY-}" && -z "${ANTHROPIC_API_KEY-}" ]]; then
|
|
205
|
+
clear_auto_rename_requested
|
|
199
206
|
echo "\"missing_api_key\""
|
|
200
207
|
return 0
|
|
201
208
|
fi
|
|
@@ -234,6 +241,7 @@ bridge_rename_session() {
|
|
|
234
241
|
ai_name="$(echo "$ai_name" | tr ' ' '_' | sed 's/[^a-zA-Z0-9_-]//g' | cut -c1-100)"
|
|
235
242
|
ai_name="$(echo "$ai_name" | sed 's/^_*//')"
|
|
236
243
|
if [[ -z "$ai_name" ]]; then
|
|
244
|
+
clear_auto_rename_requested
|
|
237
245
|
echo "\"ai_generation_failed\""
|
|
238
246
|
return 0
|
|
239
247
|
fi
|
|
@@ -251,10 +259,12 @@ bridge_rename_session() {
|
|
|
251
259
|
echo "\"success\""
|
|
252
260
|
fi
|
|
253
261
|
else
|
|
262
|
+
clear_auto_rename_requested
|
|
254
263
|
echo "\"rename_failed\""
|
|
255
264
|
fi
|
|
256
265
|
else
|
|
257
266
|
# AI generation failed, keep original name
|
|
267
|
+
clear_auto_rename_requested
|
|
258
268
|
if [[ -n "$ai_err" ]]; then
|
|
259
269
|
echo "\"ai_generation_failed: ${ai_err}\""
|
|
260
270
|
elif [[ $ai_status -ne 0 ]]; then
|
|
@@ -125,12 +125,32 @@ bridge_session_metadata() {
|
|
|
125
125
|
window_name=$(tmux display-message -t "$session_name" -p '#{window_name}' 2>/dev/null || echo "")
|
|
126
126
|
pane_title=$(tmux display-message -t "$session_name" -p '#{pane_title}' 2>/dev/null || echo "")
|
|
127
127
|
pane_cmd=$(tmux display-message -t "$session_name" -p '#{pane_current_command}' 2>/dev/null || echo "")
|
|
128
|
-
|
|
128
|
+
pane_mode=$(tmux display-message -t "$session_name" -p '#{pane_mode}' 2>/dev/null || echo "")
|
|
129
|
+
alternate_on=$(tmux display-message -t "$session_name" -p '#{alternate_on}' 2>/dev/null || echo "0")
|
|
130
|
+
mouse_any_flag=$(tmux display-message -t "$session_name" -p '#{mouse_any_flag}' 2>/dev/null || echo "0")
|
|
131
|
+
auto_rename_requested=$(tmux show-options -qv -t "$session_name" @orchestra_auto_rename_requested 2>/dev/null || echo "")
|
|
132
|
+
case "$(printf '%s' "$alternate_on" | tr '[:upper:]' '[:lower:]')" in
|
|
133
|
+
1|yes|true|on) alternate_on=true ;;
|
|
134
|
+
*) alternate_on=false ;;
|
|
135
|
+
esac
|
|
136
|
+
case "$(printf '%s' "$mouse_any_flag" | tr '[:upper:]' '[:lower:]')" in
|
|
137
|
+
1|yes|true|on) mouse_any_flag=true ;;
|
|
138
|
+
*) mouse_any_flag=false ;;
|
|
139
|
+
esac
|
|
140
|
+
case "$(printf '%s' "$auto_rename_requested" | tr '[:upper:]' '[:lower:]')" in
|
|
141
|
+
1|yes|true|on) auto_rename_requested=true ;;
|
|
142
|
+
*) auto_rename_requested=false ;;
|
|
143
|
+
esac
|
|
144
|
+
|
|
129
145
|
# Return JSON with metadata
|
|
130
146
|
json_object \
|
|
131
147
|
"window_name:s=$window_name" \
|
|
132
148
|
"pane_title:s=$pane_title" \
|
|
133
|
-
"current_command:s=$pane_cmd"
|
|
149
|
+
"current_command:s=$pane_cmd" \
|
|
150
|
+
"pane_mode:s=$pane_mode" \
|
|
151
|
+
"alternate_on:b=$alternate_on" \
|
|
152
|
+
"mouse_any_flag:b=$mouse_any_flag" \
|
|
153
|
+
"auto_rename_requested:b=$auto_rename_requested"
|
|
134
154
|
else
|
|
135
155
|
json_error "tmux not available"
|
|
136
156
|
fi
|
|
@@ -18,6 +18,8 @@ fi
|
|
|
18
18
|
ORCHESTRA_HISTORY_DIR="${ORCHESTRA_HISTORY_DIR:-$HOME/.orchestra/history}"
|
|
19
19
|
ORCHESTRA_PROMPT_HOOK_INSTALLED=1
|
|
20
20
|
|
|
21
|
+
_ORCHESTRA_HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
|
|
22
|
+
|
|
21
23
|
_orchestra_history_key() {
|
|
22
24
|
local key="$1"
|
|
23
25
|
key="${key//\//_}"
|
|
@@ -31,6 +33,101 @@ _orchestra_history_key() {
|
|
|
31
33
|
echo "$key"
|
|
32
34
|
}
|
|
33
35
|
|
|
36
|
+
_orchestra_bridge_path() {
|
|
37
|
+
local bridge=""
|
|
38
|
+
|
|
39
|
+
if [[ -n "${GW_ORCHESTRATOR_ROOT-}" ]]; then
|
|
40
|
+
bridge="$GW_ORCHESTRATOR_ROOT/gw-bridge.sh"
|
|
41
|
+
if [[ -f "$bridge" ]]; then
|
|
42
|
+
echo "$bridge"
|
|
43
|
+
return
|
|
44
|
+
fi
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
bridge="$(cd "$_ORCHESTRA_HOOK_DIR/.." && pwd -P)/gw-bridge.sh"
|
|
48
|
+
if [[ -f "$bridge" ]]; then
|
|
49
|
+
echo "$bridge"
|
|
50
|
+
return
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
echo ""
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
_orchestra_should_auto_rename_session() {
|
|
57
|
+
local session_name="$1"
|
|
58
|
+
[[ -n "$session_name" && "$session_name" == *"__auto_"* ]]
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
_orchestra_should_trigger_auto_rename_command() {
|
|
62
|
+
local command="$1"
|
|
63
|
+
local app="$2"
|
|
64
|
+
|
|
65
|
+
[[ -n "$command" ]] || return 1
|
|
66
|
+
|
|
67
|
+
case "$app" in
|
|
68
|
+
""|cd|ls|pwd|clear|reset)
|
|
69
|
+
return 1
|
|
70
|
+
;;
|
|
71
|
+
esac
|
|
72
|
+
|
|
73
|
+
return 0
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
_orchestra_auto_rename_flag_path() {
|
|
77
|
+
local session_name="$1"
|
|
78
|
+
local session_key
|
|
79
|
+
session_key=$(_orchestra_history_key "$session_name")
|
|
80
|
+
if [[ -z "$session_key" ]]; then
|
|
81
|
+
return
|
|
82
|
+
fi
|
|
83
|
+
printf '%s/%s.rename_requested\n' "$ORCHESTRA_HISTORY_DIR" "$session_key"
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
_orchestra_auto_rename_delay_secs() {
|
|
87
|
+
local delay="${ORCHESTRA_AUTO_RENAME_DELAY_SECS:-10}"
|
|
88
|
+
if [[ ! "$delay" =~ ^[0-9]+([.][0-9]+)?$ ]]; then
|
|
89
|
+
delay="10"
|
|
90
|
+
fi
|
|
91
|
+
printf '%s\n' "$delay"
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
_orchestra_trigger_auto_rename_async() {
|
|
95
|
+
local session_name="$1"
|
|
96
|
+
local command="$2"
|
|
97
|
+
local app="$3"
|
|
98
|
+
|
|
99
|
+
[[ -n "$session_name" ]] || return
|
|
100
|
+
_orchestra_should_auto_rename_session "$session_name" || return
|
|
101
|
+
_orchestra_should_trigger_auto_rename_command "$command" "$app" || return
|
|
102
|
+
|
|
103
|
+
local bridge
|
|
104
|
+
bridge="$(_orchestra_bridge_path)"
|
|
105
|
+
[[ -n "$bridge" && -f "$bridge" ]] || return
|
|
106
|
+
|
|
107
|
+
local flag_path
|
|
108
|
+
flag_path="$(_orchestra_auto_rename_flag_path "$session_name")"
|
|
109
|
+
[[ -n "$flag_path" ]] || return
|
|
110
|
+
if [[ -f "$flag_path" ]]; then
|
|
111
|
+
return
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
local timestamp
|
|
115
|
+
timestamp=$(date '+%Y-%m-%dT%H:%M:%S%z')
|
|
116
|
+
printf '%s\n' "$timestamp" > "$flag_path"
|
|
117
|
+
|
|
118
|
+
if command -v tmux >/dev/null 2>&1; then
|
|
119
|
+
tmux set-option -q -t "$session_name" @orchestra_auto_rename_requested 1 >/dev/null 2>&1 || true
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
local delay
|
|
123
|
+
delay="$(_orchestra_auto_rename_delay_secs)"
|
|
124
|
+
|
|
125
|
+
(
|
|
126
|
+
sleep "$delay"
|
|
127
|
+
command bash "$bridge" rename-session "$session_name" >/dev/null 2>&1 || true
|
|
128
|
+
) >/dev/null 2>&1 &
|
|
129
|
+
}
|
|
130
|
+
|
|
34
131
|
_orchestra_capture_command() {
|
|
35
132
|
local cmd=""
|
|
36
133
|
if [[ -n "${ZSH_VERSION-}" ]]; then
|
|
@@ -171,6 +268,10 @@ orchestra_log_command() {
|
|
|
171
268
|
printf '%s\n' "$app" > "$ORCHESTRA_HISTORY_DIR/$key.last_app"
|
|
172
269
|
fi
|
|
173
270
|
printf '%s\n' "$command" > "$ORCHESTRA_HISTORY_DIR/$key.last_cmd"
|
|
271
|
+
|
|
272
|
+
if [[ -n "$session_name" && "$session_name" != "shell" ]]; then
|
|
273
|
+
_orchestra_trigger_auto_rename_async "$session_name" "$command" "$app" || true
|
|
274
|
+
fi
|
|
174
275
|
}
|
|
175
276
|
|
|
176
277
|
_orchestra_install_hook_bash() {
|