@humanu/orchestra 0.5.61 → 0.5.63

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@humanu/orchestra",
3
- "version": "0.5.61",
3
+ "version": "0.5.63",
4
4
  "description": "AI-powered Git worktree and tmux session manager with modern TUI",
5
5
  "keywords": [
6
6
  "git",
@@ -24,6 +24,9 @@ fi
24
24
  # Note: tmux session names cannot contain ':'; use a safe delimiter
25
25
  ORCHESTRA_SESSION_DELIM="__"
26
26
 
27
+ # Absolute directory that contains this script when sourced.
28
+ _TMUX_API_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
29
+
27
30
  # Helper: return delimiter
28
31
  _tmux_delim() { echo "$ORCHESTRA_SESSION_DELIM"; }
29
32
 
@@ -77,7 +80,7 @@ _tmux_normalize_app_from_command() {
77
80
 
78
81
  local base="${tokens[$i]}"
79
82
  base="${base##*/}"
80
- base="$(printf '%s' "$base" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9._-:' '_')"
83
+ base="$(printf '%s' "$base" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9._:-' '_')"
81
84
  base="${base//__/_}"
82
85
  base="${base##_}"
83
86
  base="${base%%_}"
@@ -108,18 +111,38 @@ _tmux_normalize_app_from_command() {
108
111
 
109
112
  # Helper: absolute path to the command hook script (if present)
110
113
  _orchestra_command_hook() {
111
- local root
112
- root="$(repo_root)"
113
- if [[ -z "$root" ]]; then
114
- echo ""
115
- return
114
+ local hook=""
115
+
116
+ # 1) Explicit install root set by wrappers (Homebrew/NPM)
117
+ if [[ -n "${GW_ORCHESTRATOR_ROOT-}" ]]; then
118
+ hook="$GW_ORCHESTRATOR_ROOT/shell/orchestra-command-hook.sh"
119
+ if [[ -f "$hook" ]]; then
120
+ echo "$hook"
121
+ return
122
+ fi
116
123
  fi
117
- local hook="$root/shell/orchestra-command-hook.sh"
124
+
125
+ # 2) Resolve relative to this script's install location
126
+ local script_root
127
+ script_root="$(cd "$_TMUX_API_DIR/.." && pwd -P)"
128
+ hook="$script_root/shell/orchestra-command-hook.sh"
118
129
  if [[ -f "$hook" ]]; then
119
130
  echo "$hook"
120
- else
121
- echo ""
131
+ return
122
132
  fi
133
+
134
+ # 3) Fallback to repo root for legacy/dev flows
135
+ local root
136
+ root="$(repo_root)"
137
+ if [[ -n "$root" ]]; then
138
+ hook="$root/shell/orchestra-command-hook.sh"
139
+ if [[ -f "$hook" ]]; then
140
+ echo "$hook"
141
+ return
142
+ fi
143
+ fi
144
+
145
+ echo ""
123
146
  }
124
147
 
125
148
  # Source the command hook inside a tmux session to enable command history logging
@@ -144,8 +167,8 @@ _tmux_source_command_hook() {
144
167
  pane_id="${line%% *}"
145
168
  pane_cmd="${line#* }"
146
169
  case "$pane_cmd" in
147
- bash|zsh|sh|fish|dash|ksh)
148
- tmux send-keys -t "$pane_id" "source '$hook'" C-m 2>/dev/null || true
170
+ bash|zsh)
171
+ tmux send-keys -t "$pane_id" ". '$hook'" C-m 2>/dev/null || true
149
172
  ;;
150
173
  *)
151
174
  ;;
@@ -1166,6 +1189,8 @@ if history_arg:
1166
1189
  history_commands = history_commands[-50:]
1167
1190
 
1168
1191
  prompt_pattern = re.compile(r"^[A-Za-z0-9_.@~/-]+$")
1192
+ prompt_sigil_pattern = re.compile(r"^(?P<prompt>[^\t]{0,120}?)(?P<sigil>[$#%])\s+(?P<cmd>.+)$")
1193
+ simple_sigil_pattern = re.compile(r"^(?P<sigil>[$#%])\s+(?P<cmd>.+)$")
1169
1194
  disallowed_prompts = {
1170
1195
  "warning",
1171
1196
  "error",
@@ -1296,26 +1321,49 @@ allowed_prefixes = (
1296
1321
  def clean_tokens(tokens):
1297
1322
  while tokens and tokens[0] in {"$", "#", "%"}:
1298
1323
  tokens = tokens[1:]
1324
+ while tokens and (tokens[0].endswith("$") or tokens[0].endswith("#") or tokens[0].endswith("%")):
1325
+ tokens = tokens[1:]
1299
1326
  return tokens
1300
1327
 
1301
1328
 
1302
- for raw_line in lines:
1329
+ def extract_prompt_and_command(raw_line):
1303
1330
  stripped = raw_line.strip()
1304
- if not stripped or ":" not in stripped:
1305
- continue
1306
-
1307
- prompt_part, command_part = stripped.split(":", 1)
1308
- prompt_part = prompt_part.strip().rstrip("#$%")
1309
- command_part = command_part.strip()
1310
-
1311
- if not prompt_part or not command_part:
1312
- continue
1331
+ if not stripped:
1332
+ return "", ""
1333
+
1334
+ # Pattern 1: host:path:command (common bash/zsh prompts)
1335
+ if ":" in stripped:
1336
+ maybe_prompt, maybe_cmd = stripped.split(":", 1)
1337
+ maybe_prompt = maybe_prompt.strip().rstrip("#$%")
1338
+ maybe_cmd = maybe_cmd.strip()
1339
+ if maybe_prompt and maybe_cmd and prompt_pattern.match(maybe_prompt):
1340
+ prompt_lower = maybe_prompt.lower()
1341
+ if prompt_lower not in disallowed_prompts:
1342
+ return maybe_prompt, maybe_cmd
1343
+
1344
+ # Pattern 2: prompt ending with $, #, % (supports prompts without ':')
1345
+ match = prompt_sigil_pattern.match(stripped)
1346
+ if match:
1347
+ maybe_prompt = (match.group("prompt") or "").strip().rstrip("#$%")
1348
+ maybe_cmd = (match.group("cmd") or "").strip()
1349
+ if maybe_cmd:
1350
+ if maybe_prompt and maybe_prompt.lower() in disallowed_prompts:
1351
+ return "", ""
1352
+ return (maybe_prompt if maybe_prompt else match.group("sigil")), maybe_cmd
1353
+
1354
+ # Pattern 3: bare prompt lines like "$ git status"
1355
+ match = simple_sigil_pattern.match(stripped)
1356
+ if match:
1357
+ maybe_cmd = (match.group("cmd") or "").strip()
1358
+ if maybe_cmd:
1359
+ return match.group("sigil"), maybe_cmd
1360
+
1361
+ return "", ""
1313
1362
 
1314
- if not prompt_pattern.match(prompt_part):
1315
- continue
1316
1363
 
1317
- prompt_lower = prompt_part.lower()
1318
- if prompt_lower in disallowed_prompts:
1364
+ for raw_line in lines:
1365
+ prompt_part, command_part = extract_prompt_and_command(raw_line)
1366
+ if not command_part:
1319
1367
  continue
1320
1368
 
1321
1369
  tokens = clean_tokens(command_part.split())
@@ -1468,7 +1516,7 @@ def normalize_app(cmd: str) -> str:
1468
1516
  return ""
1469
1517
  return base
1470
1518
 
1471
- app_commands = history_commands
1519
+ app_commands = history_commands if history_commands else app_command_candidates
1472
1520
  app_prefix = ""
1473
1521
  for candidate in reversed(app_commands):
1474
1522
  app_prefix = normalize_app(candidate)
@@ -86,7 +86,7 @@ _orchestra_normalize_app() {
86
86
 
87
87
  local base="${tokens[$i]}"
88
88
  base="${base##*/}"
89
- base="$(printf '%s' "$base" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9._-:' '_')"
89
+ base="$(printf '%s' "$base" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9._:-' '_')"
90
90
  base="${base//__/_}"
91
91
  base="${base##_}"
92
92
  base="${base%%_}"