@humanu/orchestra 0.5.58 → 0.5.59

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.
@@ -3,14 +3,13 @@
3
3
  # Orchestra command history hook
4
4
  #
5
5
  # Source this file from your shell profile to log each executed command to a
6
- # per-tmux-session history file. The auto-rename pipeline can then use the
6
+ # per-tmux-pane history file. The auto-rename pipeline can then use the
7
7
  # captured history as the primary signal for determining app prefixes.
8
8
  #
9
9
  # source /path/to/orchestrator/shell/orchestra-command-hook.sh
10
10
  #
11
- # On Bash we automatically append the hook to PROMPT_COMMAND; on Zsh we add a
12
- # precmd hook (requires add-zsh-hook). Other shells can invoke
13
- # `orchestra_log_command` manually from their prompt hooks.
11
+ # On Bash we install a DEBUG pre-exec hook; on Zsh we install a preexec hook.
12
+ # This captures the last user command reliably before execution.
14
13
 
15
14
  if [[ -n "${ORCHESTRA_PROMPT_HOOK_INSTALLED-}" ]]; then
16
15
  return 0 2>/dev/null || exit 0
@@ -44,27 +43,118 @@ _orchestra_capture_command() {
44
43
  printf '%s' "$cmd"
45
44
  }
46
45
 
46
+ _orchestra_normalize_app() {
47
+ local cmd="$1"
48
+ if [[ -n "${ZSH_VERSION-}" ]]; then
49
+ setopt local_options ksharrays 2>/dev/null || true
50
+ fi
51
+ cmd="${cmd#"${cmd%%[![:space:]]*}"}"
52
+ cmd="${cmd%"${cmd##*[![:space:]]}"}"
53
+ if [[ -z "$cmd" ]]; then
54
+ return
55
+ fi
56
+
57
+ local tokens=()
58
+ if [[ -n "${ZSH_VERSION-}" ]]; then
59
+ tokens=(${=cmd})
60
+ else
61
+ read -r -a tokens <<< "$cmd"
62
+ fi
63
+ if [[ ${#tokens[@]} -eq 0 ]]; then
64
+ return
65
+ fi
66
+
67
+ local i=0
68
+ while [[ $i -lt ${#tokens[@]} ]]; do
69
+ local t="${tokens[$i]}"
70
+ if [[ "$t" =~ ^[A-Za-z_][A-Za-z0-9_]*= ]]; then
71
+ ((i++))
72
+ continue
73
+ fi
74
+ case "$t" in
75
+ sudo|env|command|nohup|time)
76
+ ((i++))
77
+ continue
78
+ ;;
79
+ esac
80
+ break
81
+ done
82
+
83
+ if [[ $i -ge ${#tokens[@]} ]]; then
84
+ return
85
+ fi
86
+
87
+ local base="${tokens[$i]}"
88
+ base="${base##*/}"
89
+ base="$(printf '%s' "$base" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9._-:' '_')"
90
+ base="${base//__/_}"
91
+ base="${base##_}"
92
+ base="${base%%_}"
93
+
94
+ case "$base" in
95
+ python3|python3.*)
96
+ base="python"
97
+ ;;
98
+ pip3|pip3.*)
99
+ base="pip"
100
+ ;;
101
+ docker-compose|docker_compose)
102
+ base="docker_compose"
103
+ ;;
104
+ nvim|nvim.app)
105
+ base="nvim"
106
+ ;;
107
+ esac
108
+
109
+ case "$base" in
110
+ ""|bash|zsh|sh|fish|tmux|login|sudo|man|less|more|cat|tail|watch|source|export|set|alias|unalias|history|bindkey)
111
+ return
112
+ ;;
113
+ esac
114
+
115
+ printf '%s' "$base"
116
+ }
117
+
47
118
  orchestra_log_command() {
48
- local command=$(_orchestra_capture_command)
49
- command="${command## }"
119
+ local command="${1-}"
120
+ if [[ -z "$command" ]]; then
121
+ command=$(_orchestra_capture_command)
122
+ fi
123
+ command="${command#"${command%%[![:space:]]*}"}"
124
+ command="${command%"${command##*[![:space:]]}"}"
50
125
  if [[ -z "$command" ]]; then
51
126
  return
52
127
  fi
53
128
 
129
+ case "$command" in
130
+ orchestra_*|_orchestra_*)
131
+ return
132
+ ;;
133
+ esac
134
+
54
135
  # Avoid logging duplicate consecutive commands within the same shell
55
136
  if [[ "$command" == "${ORCHESTRA_LAST_COMMAND-}" ]]; then
56
137
  return
57
138
  fi
58
139
  ORCHESTRA_LAST_COMMAND="$command"
59
140
 
141
+ local pane_id=""
60
142
  local session_name=""
61
143
  if command -v tmux >/dev/null 2>&1 && [[ -n "${TMUX-}" ]]; then
144
+ pane_id="${TMUX_PANE-}"
145
+ if [[ -z "$pane_id" ]]; then
146
+ pane_id="$(tmux display-message -p '#{pane_id}' 2>/dev/null || echo "")"
147
+ fi
62
148
  session_name="$(tmux display-message -p '#{session_name}' 2>/dev/null || echo "")"
63
149
  fi
64
150
  session_name="${session_name:-shell}"
65
151
 
66
152
  local key
67
- key=$(_orchestra_history_key "$session_name")
153
+ if [[ -n "$pane_id" ]]; then
154
+ key=$(_orchestra_history_key "$pane_id")
155
+ else
156
+ key=$(_orchestra_history_key "$session_name")
157
+ fi
68
158
  if [[ -z "$key" ]]; then
69
159
  key="shell"
70
160
  fi
@@ -74,31 +164,65 @@ orchestra_log_command() {
74
164
  local timestamp
75
165
  timestamp=$(date '+%Y-%m-%dT%H:%M:%S%z')
76
166
  printf '%s\t%s\n' "$timestamp" "$command" >> "$ORCHESTRA_HISTORY_DIR/$key.log"
167
+
168
+ local app
169
+ app="$(_orchestra_normalize_app "$command")"
170
+ if [[ -n "$app" ]]; then
171
+ printf '%s\n' "$app" > "$ORCHESTRA_HISTORY_DIR/$key.last_app"
172
+ fi
173
+ printf '%s\n' "$command" > "$ORCHESTRA_HISTORY_DIR/$key.last_cmd"
77
174
  }
78
175
 
79
176
  _orchestra_install_hook_bash() {
80
- if [[ "${PROMPT_COMMAND-}" == *orchestra_log_command* ]]; then
177
+ _orchestra_bash_preexec_hook() {
178
+ if [[ "${ORCHESTRA_DEBUG_TRAP_ACTIVE-}" == "1" ]]; then
179
+ return
180
+ fi
181
+ ORCHESTRA_DEBUG_TRAP_ACTIVE=1
182
+ local cmd="${BASH_COMMAND-}"
183
+ ORCHESTRA_DEBUG_TRAP_ACTIVE=0
184
+ orchestra_log_command "$cmd"
185
+ }
186
+
187
+ local existing_debug
188
+ existing_debug="$(trap -p DEBUG 2>/dev/null | sed -n "s/^trap -- '\(.*\)' DEBUG$/\1/p")"
189
+ if [[ "$existing_debug" == *"_orchestra_bash_preexec_hook"* ]]; then
81
190
  return
82
191
  fi
83
- if [[ -n "${PROMPT_COMMAND-}" ]]; then
84
- PROMPT_COMMAND="orchestra_log_command; ${PROMPT_COMMAND}"
192
+
193
+ if [[ -n "$existing_debug" ]]; then
194
+ trap "_orchestra_bash_preexec_hook; $existing_debug" DEBUG
85
195
  else
86
- PROMPT_COMMAND="orchestra_log_command"
196
+ trap '_orchestra_bash_preexec_hook' DEBUG
87
197
  fi
88
198
  }
89
199
 
90
200
  _orchestra_install_hook_zsh() {
201
+ _orchestra_zsh_preexec_hook() {
202
+ orchestra_log_command "$1"
203
+ }
204
+
205
+ if ! command -v add-zsh-hook >/dev/null 2>&1; then
206
+ autoload -Uz add-zsh-hook 2>/dev/null || true
207
+ fi
91
208
  if command -v add-zsh-hook >/dev/null 2>&1; then
92
- add-zsh-hook precmd orchestra_log_command
209
+ add-zsh-hook preexec _orchestra_zsh_preexec_hook
93
210
  else
94
- # Fallback: append to precmd_functions manually
95
- if [[ -z "${precmd_functions[(r)orchestra_log_command]}" ]]; then
96
- precmd_functions+=(orchestra_log_command)
211
+ # Fallback: append to preexec_functions manually
212
+ if [[ -z "${preexec_functions[(r)_orchestra_zsh_preexec_hook]}" ]]; then
213
+ preexec_functions+=(_orchestra_zsh_preexec_hook)
97
214
  fi
98
215
  fi
99
216
  }
100
217
 
101
218
  _orchestra_install_hook() {
219
+ case "$-" in
220
+ *i*) ;;
221
+ *)
222
+ return
223
+ ;;
224
+ esac
225
+
102
226
  if [[ -n "${ZSH_VERSION-}" ]]; then
103
227
  _orchestra_install_hook_zsh
104
228
  else