@humanu/orchestra 0.5.72 → 0.5.73
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
package/resources/api/tmux.sh
CHANGED
|
@@ -416,6 +416,80 @@ _tmux_registry_sync_active_workspace_sessions() {
|
|
|
416
416
|
done < <(tmux list-sessions -F '#{session_name}' 2>/dev/null || true)
|
|
417
417
|
}
|
|
418
418
|
|
|
419
|
+
_tmux_workspace_cycle_target_cached() {
|
|
420
|
+
local current_session="$1"
|
|
421
|
+
local direction="$2"
|
|
422
|
+
local db_path="$3"
|
|
423
|
+
local active_file="$4"
|
|
424
|
+
|
|
425
|
+
python3 - "$db_path" "$current_session" "$direction" "$active_file" <<'PY'
|
|
426
|
+
import sqlite3
|
|
427
|
+
import sys
|
|
428
|
+
|
|
429
|
+
db_path, current_session, direction, active_path = sys.argv[1:5]
|
|
430
|
+
active = set()
|
|
431
|
+
active_orchestra = set()
|
|
432
|
+
with open(active_path, "r", encoding="utf-8") as handle:
|
|
433
|
+
for raw_line in handle:
|
|
434
|
+
line = raw_line.rstrip("\n")
|
|
435
|
+
if not line:
|
|
436
|
+
continue
|
|
437
|
+
parts = line.split("\t", 1)
|
|
438
|
+
name = parts[0].strip()
|
|
439
|
+
display_name = parts[1].strip() if len(parts) > 1 else ""
|
|
440
|
+
if not name:
|
|
441
|
+
continue
|
|
442
|
+
active.add(name)
|
|
443
|
+
if display_name:
|
|
444
|
+
active_orchestra.add(name)
|
|
445
|
+
|
|
446
|
+
try:
|
|
447
|
+
conn = sqlite3.connect(db_path)
|
|
448
|
+
current_row = conn.execute(
|
|
449
|
+
"SELECT repo_root FROM sessions WHERE tmux_name = ?1",
|
|
450
|
+
(current_session,),
|
|
451
|
+
).fetchone()
|
|
452
|
+
if current_row is None:
|
|
453
|
+
raise SystemExit(2)
|
|
454
|
+
|
|
455
|
+
registered = {
|
|
456
|
+
name
|
|
457
|
+
for (name,) in conn.execute("SELECT tmux_name FROM sessions").fetchall()
|
|
458
|
+
}
|
|
459
|
+
if active_orchestra.difference(registered):
|
|
460
|
+
raise SystemExit(2)
|
|
461
|
+
|
|
462
|
+
rows = conn.execute(
|
|
463
|
+
"""
|
|
464
|
+
SELECT tmux_name
|
|
465
|
+
FROM sessions
|
|
466
|
+
WHERE repo_root = ?1
|
|
467
|
+
ORDER BY worktree_path COLLATE NOCASE, created_at, tmux_name COLLATE NOCASE
|
|
468
|
+
""",
|
|
469
|
+
(current_row[0],),
|
|
470
|
+
).fetchall()
|
|
471
|
+
except sqlite3.Error:
|
|
472
|
+
raise SystemExit(2)
|
|
473
|
+
|
|
474
|
+
names = []
|
|
475
|
+
seen = set()
|
|
476
|
+
for (name,) in rows:
|
|
477
|
+
if name in active and name not in seen:
|
|
478
|
+
names.append(name)
|
|
479
|
+
seen.add(name)
|
|
480
|
+
|
|
481
|
+
if len(names) < 2 or current_session not in seen:
|
|
482
|
+
raise SystemExit(3)
|
|
483
|
+
|
|
484
|
+
index = names.index(current_session)
|
|
485
|
+
if direction == "next":
|
|
486
|
+
index = (index + 1) % len(names)
|
|
487
|
+
else:
|
|
488
|
+
index = (index - 1) % len(names)
|
|
489
|
+
print(names[index])
|
|
490
|
+
PY
|
|
491
|
+
}
|
|
492
|
+
|
|
419
493
|
_tmux_status_escape_text() {
|
|
420
494
|
local text="$1"
|
|
421
495
|
text="${text//\#/##}"
|
|
@@ -424,14 +498,22 @@ _tmux_status_escape_text() {
|
|
|
424
498
|
|
|
425
499
|
_tmux_truncate_tab_label() {
|
|
426
500
|
local label="$1"
|
|
427
|
-
local max_len="${2:-
|
|
501
|
+
local max_len="${2:-14}"
|
|
428
502
|
if (( ${#label} > max_len )); then
|
|
429
|
-
printf '%s
|
|
503
|
+
printf '%s' "${label:0:max_len}"
|
|
430
504
|
else
|
|
431
505
|
printf '%s' "$label"
|
|
432
506
|
fi
|
|
433
507
|
}
|
|
434
508
|
|
|
509
|
+
_tmux_pad_tab_label() {
|
|
510
|
+
local label="$1"
|
|
511
|
+
local width="${2:-14}"
|
|
512
|
+
|
|
513
|
+
label="$(_tmux_truncate_tab_label "$label" "$width")"
|
|
514
|
+
printf '%-*s' "$width" "$label"
|
|
515
|
+
}
|
|
516
|
+
|
|
435
517
|
_tmux_workspace_session_rows() {
|
|
436
518
|
local current_session="$1"
|
|
437
519
|
local repo_root="$2"
|
|
@@ -506,7 +588,9 @@ PY
|
|
|
506
588
|
_tmux_workspace_session_tabs() {
|
|
507
589
|
local current_session="$1"
|
|
508
590
|
local fallback_display_name="$2"
|
|
509
|
-
local session_dir repo_root rows tabs name display_name
|
|
591
|
+
local session_dir repo_root rows tabs name display_name tab_label escaped_tab_label divider active_style inactive_style muted_style reset_style
|
|
592
|
+
local tab_width=21
|
|
593
|
+
local active_label_width=19
|
|
510
594
|
|
|
511
595
|
session_dir="$(tmux display-message -t "$current_session" -p '#{pane_current_path}' 2>/dev/null || echo "")"
|
|
512
596
|
repo_root="$(_tmux_shared_root_for_path "$session_dir" 2>/dev/null || true)"
|
|
@@ -518,34 +602,42 @@ _tmux_workspace_session_tabs() {
|
|
|
518
602
|
fi
|
|
519
603
|
|
|
520
604
|
if [[ -z "$rows" ]]; then
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
printf '#[fg
|
|
605
|
+
tab_label="$(_tmux_pad_tab_label "$fallback_display_name" "$active_label_width")"
|
|
606
|
+
escaped_tab_label="$(_tmux_status_escape_text "$tab_label")"
|
|
607
|
+
printf '#[bg=#414868] #[fg=#ff9e64,bg=#414868,bold]● #[fg=#c0caf5,bg=#414868,bold]%s #[default]' "$escaped_tab_label"
|
|
524
608
|
return
|
|
525
609
|
fi
|
|
526
610
|
|
|
611
|
+
# Tokyo Night palette: midnight footer, muted inactive tabs, orange active marker.
|
|
612
|
+
active_style="#[fg=#c0caf5,bg=#414868,bold]"
|
|
613
|
+
inactive_style="#[fg=#a9b1d6,bg=#24283b,nobold]"
|
|
614
|
+
muted_style="#[fg=#565f89,bg=#1a1b26,nobold]"
|
|
615
|
+
reset_style="#[default]"
|
|
527
616
|
tabs=""
|
|
528
|
-
divider="
|
|
617
|
+
divider="${muted_style}|${reset_style}"
|
|
529
618
|
while IFS=$'\t' read -r name display_name; do
|
|
530
619
|
[[ -n "$name" ]] || continue
|
|
531
620
|
if [[ -n "$tabs" ]]; then
|
|
532
621
|
tabs+="$divider"
|
|
533
622
|
fi
|
|
534
623
|
if [[ "$name" == "__ellipsis__" ]]; then
|
|
535
|
-
|
|
624
|
+
tab_label="$(_tmux_pad_tab_label "⋯" "$tab_width")"
|
|
625
|
+
escaped_tab_label="$(_tmux_status_escape_text "$tab_label")"
|
|
626
|
+
tabs+="${muted_style} ${escaped_tab_label} ${reset_style}"
|
|
536
627
|
continue
|
|
537
628
|
fi
|
|
538
629
|
|
|
539
630
|
if [[ -z "$display_name" ]]; then
|
|
540
631
|
display_name="$(tmux_format_session_display "$name" without-timestamp)"
|
|
541
632
|
fi
|
|
542
|
-
label="$(_tmux_truncate_tab_label "$display_name")"
|
|
543
|
-
escaped_label="$(_tmux_status_escape_text "$label")"
|
|
544
|
-
|
|
545
633
|
if [[ "$name" == "$current_session" ]]; then
|
|
546
|
-
|
|
634
|
+
tab_label="$(_tmux_pad_tab_label "$display_name" "$active_label_width")"
|
|
635
|
+
escaped_tab_label="$(_tmux_status_escape_text "$tab_label")"
|
|
636
|
+
tabs+="#[bg=#414868] #[fg=#ff9e64,bg=#414868,bold]● ${active_style}${escaped_tab_label} ${reset_style}"
|
|
547
637
|
else
|
|
548
|
-
|
|
638
|
+
tab_label="$(_tmux_pad_tab_label "$display_name" "$tab_width")"
|
|
639
|
+
escaped_tab_label="$(_tmux_status_escape_text "$tab_label")"
|
|
640
|
+
tabs+="${inactive_style} ${escaped_tab_label} ${reset_style}"
|
|
549
641
|
fi
|
|
550
642
|
done <<< "$rows"
|
|
551
643
|
|
|
@@ -604,6 +696,7 @@ _tmux_configure_orchestra_status() {
|
|
|
604
696
|
tmux set-option -t "$session_name" @orchestra_worktree_name "$worktree_name" >/dev/null 2>&1 || true
|
|
605
697
|
tmux set-option -t "$session_name" status on >/dev/null 2>&1 || true
|
|
606
698
|
tmux set-option -t "$session_name" status-position bottom >/dev/null 2>&1 || true
|
|
699
|
+
tmux set-option -t "$session_name" status-style "fg=#c0caf5,bg=#1a1b26" >/dev/null 2>&1 || true
|
|
607
700
|
tmux set-option -t "$session_name" status-left "$status_left" >/dev/null 2>&1 || true
|
|
608
701
|
tmux set-option -t "$session_name" status-left-length 1000 >/dev/null 2>&1 || true
|
|
609
702
|
tmux set-option -t "$session_name" status-right "$status_right" >/dev/null 2>&1 || true
|
|
@@ -1438,7 +1531,7 @@ tmux_show_orchestra_help_popup() {
|
|
|
1438
1531
|
tmux_workspace_cycle_target() {
|
|
1439
1532
|
local current_session="$1"
|
|
1440
1533
|
local direction="$2"
|
|
1441
|
-
local session_dir repo_root db_path active_file target
|
|
1534
|
+
local session_dir repo_root db_path active_file target query_status
|
|
1442
1535
|
|
|
1443
1536
|
if ! tmux_available; then
|
|
1444
1537
|
err "tmux not installed"
|
|
@@ -1456,40 +1549,64 @@ tmux_workspace_cycle_target() {
|
|
|
1456
1549
|
;;
|
|
1457
1550
|
esac
|
|
1458
1551
|
|
|
1552
|
+
db_path="$(_tmux_session_registry_path)"
|
|
1553
|
+
have_cmd python3 || {
|
|
1554
|
+
err "python3 is required to read the Orchestra session registry"
|
|
1555
|
+
return 1
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1558
|
+
active_file="$(mktemp)"
|
|
1559
|
+
tmux list-sessions -F $'#{session_name}\t#{@orchestra_display_name}' > "$active_file" 2>/dev/null || {
|
|
1560
|
+
rm -f "$active_file"
|
|
1561
|
+
err "Unable to list tmux sessions"
|
|
1562
|
+
return 1
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
if [[ -f "$db_path" ]]; then
|
|
1566
|
+
if target="$(_tmux_workspace_cycle_target_cached "$current_session" "$direction" "$db_path" "$active_file")"; then
|
|
1567
|
+
query_status=0
|
|
1568
|
+
else
|
|
1569
|
+
query_status=$?
|
|
1570
|
+
fi
|
|
1571
|
+
if [[ $query_status -eq 0 && -n "$target" ]]; then
|
|
1572
|
+
rm -f "$active_file"
|
|
1573
|
+
printf '%s\n' "$target"
|
|
1574
|
+
return 0
|
|
1575
|
+
fi
|
|
1576
|
+
if [[ $query_status -eq 3 ]]; then
|
|
1577
|
+
rm -f "$active_file"
|
|
1578
|
+
return 1
|
|
1579
|
+
fi
|
|
1580
|
+
fi
|
|
1581
|
+
|
|
1459
1582
|
_tmux_registry_upsert_current_session "$current_session" >/dev/null 2>&1 || true
|
|
1460
1583
|
|
|
1461
1584
|
session_dir="$(tmux display-message -t "$current_session" -p '#{pane_current_path}' 2>/dev/null || echo "")"
|
|
1462
1585
|
repo_root="$(_tmux_shared_root_for_path "$session_dir" 2>/dev/null || true)"
|
|
1463
1586
|
if [[ -z "$repo_root" ]]; then
|
|
1587
|
+
rm -f "$active_file"
|
|
1464
1588
|
err "Unable to determine Orchestra workspace for session"
|
|
1465
1589
|
return 1
|
|
1466
1590
|
fi
|
|
1467
1591
|
_tmux_registry_sync_active_workspace_sessions "$repo_root" >/dev/null 2>&1 || true
|
|
1468
1592
|
|
|
1469
|
-
db_path="$(_tmux_session_registry_path)"
|
|
1470
1593
|
if [[ ! -f "$db_path" ]]; then
|
|
1594
|
+
rm -f "$active_file"
|
|
1471
1595
|
err "No Orchestra session registry found"
|
|
1472
1596
|
return 1
|
|
1473
1597
|
fi
|
|
1474
|
-
have_cmd python3 || {
|
|
1475
|
-
err "python3 is required to read the Orchestra session registry"
|
|
1476
|
-
return 1
|
|
1477
|
-
}
|
|
1478
1598
|
|
|
1479
|
-
|
|
1480
|
-
tmux list-sessions -F '#{session_name}' > "$active_file" 2>/dev/null || {
|
|
1481
|
-
rm -f "$active_file"
|
|
1482
|
-
err "Unable to list tmux sessions"
|
|
1483
|
-
return 1
|
|
1484
|
-
}
|
|
1485
|
-
|
|
1486
|
-
target="$(python3 - "$db_path" "$repo_root" "$current_session" "$direction" "$active_file" <<'PY'
|
|
1599
|
+
if target="$(python3 - "$db_path" "$repo_root" "$current_session" "$direction" "$active_file" <<'PY'
|
|
1487
1600
|
import sqlite3
|
|
1488
1601
|
import sys
|
|
1489
1602
|
|
|
1490
1603
|
db_path, repo_root, current_session, direction, active_path = sys.argv[1:6]
|
|
1491
1604
|
with open(active_path, "r", encoding="utf-8") as handle:
|
|
1492
|
-
active = {
|
|
1605
|
+
active = {
|
|
1606
|
+
line.rstrip("\n").split("\t", 1)[0].strip()
|
|
1607
|
+
for line in handle
|
|
1608
|
+
if line.rstrip("\n").split("\t", 1)[0].strip()
|
|
1609
|
+
}
|
|
1493
1610
|
|
|
1494
1611
|
conn = sqlite3.connect(db_path)
|
|
1495
1612
|
rows = conn.execute(
|
|
@@ -1519,8 +1636,11 @@ else:
|
|
|
1519
1636
|
index = (index - 1) % len(names)
|
|
1520
1637
|
print(names[index])
|
|
1521
1638
|
PY
|
|
1522
|
-
)"
|
|
1523
|
-
|
|
1639
|
+
)"; then
|
|
1640
|
+
query_status=0
|
|
1641
|
+
else
|
|
1642
|
+
query_status=$?
|
|
1643
|
+
fi
|
|
1524
1644
|
rm -f "$active_file"
|
|
1525
1645
|
if [[ $query_status -ne 0 ]]; then
|
|
1526
1646
|
err "Unable to query Orchestra session registry"
|
|
@@ -1543,13 +1663,15 @@ tmux_cycle_workspace_session() {
|
|
|
1543
1663
|
return 1
|
|
1544
1664
|
fi
|
|
1545
1665
|
|
|
1546
|
-
_tmux_refresh_orchestra_session_status "$target_session" >/dev/null 2>&1 || true
|
|
1547
|
-
|
|
1548
1666
|
if [[ -n "$target_client" ]]; then
|
|
1549
1667
|
tmux switch-client -c "$target_client" -t "$target_session" >/dev/null 2>&1 || return 1
|
|
1550
1668
|
else
|
|
1551
1669
|
tmux switch-client -t "$target_session" >/dev/null 2>&1 || return 1
|
|
1552
1670
|
fi
|
|
1671
|
+
|
|
1672
|
+
{
|
|
1673
|
+
_tmux_refresh_orchestra_session_status "$target_session" >/dev/null 2>&1 || true
|
|
1674
|
+
} &
|
|
1553
1675
|
}
|
|
1554
1676
|
|
|
1555
1677
|
# Load .env file if it exists
|
|
Binary file
|
|
Binary file
|
|
Binary file
|