256 lines
6.5 KiB
Bash
Executable File
256 lines
6.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# list-sessions.sh - List all registered tmux sessions
|
|
#
|
|
# Lists all sessions in the registry with health status information.
|
|
# Supports both human-readable table format and JSON output.
|
|
#
|
|
# Usage:
|
|
# ./list-sessions.sh [--json]
|
|
#
|
|
# Options:
|
|
# --json Output as JSON instead of table
|
|
# -h, --help Show this help message
|
|
#
|
|
# Exit codes:
|
|
# 0 - Success
|
|
# 1 - Error
|
|
|
|
set -euo pipefail
|
|
|
|
# Get script directory to source libraries
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
# shellcheck source=lib/registry.sh
|
|
source "$SCRIPT_DIR/lib/registry.sh"
|
|
# shellcheck source=lib/time_utils.sh
|
|
source "$SCRIPT_DIR/lib/time_utils.sh"
|
|
|
|
# Path to pane-health tool
|
|
PANE_HEALTH="$SCRIPT_DIR/pane-health.sh"
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Configuration
|
|
#------------------------------------------------------------------------------
|
|
|
|
output_format="table"
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Functions
|
|
#------------------------------------------------------------------------------
|
|
|
|
usage() {
|
|
cat << EOF
|
|
Usage: $(basename "$0") [--json]
|
|
|
|
List all registered tmux sessions with health status.
|
|
|
|
Options:
|
|
--json Output as JSON instead of table format
|
|
-h, --help Show this help message
|
|
|
|
Output Formats:
|
|
Table (default):
|
|
NAME SOCKET TARGET STATUS PID CREATED
|
|
my-python claude.sock my-python:0.0 alive 1234 2h ago
|
|
my-gdb claude.sock my-gdb:0.0 dead - 1h ago
|
|
|
|
JSON (--json):
|
|
{
|
|
"sessions": [
|
|
{"name": "my-python", "socket": "...", "status": "alive", ...}
|
|
],
|
|
"total": 2,
|
|
"alive": 1,
|
|
"dead": 1
|
|
}
|
|
|
|
Health Status:
|
|
alive - Session is running and healthy
|
|
dead - Pane is marked as dead
|
|
missing - Session/pane not found
|
|
zombie - Process not running
|
|
server - Tmux server not running
|
|
|
|
Examples:
|
|
# List sessions in table format
|
|
$(basename "$0")
|
|
|
|
# List sessions as JSON
|
|
$(basename "$0") --json
|
|
|
|
Exit codes:
|
|
0 - Success
|
|
1 - Error
|
|
EOF
|
|
}
|
|
|
|
# Get health status for a session
|
|
# Returns: status string (alive, dead, missing, zombie, server)
|
|
get_health_status() {
|
|
local socket="$1"
|
|
local target="$2"
|
|
|
|
if [[ ! -x "$PANE_HEALTH" ]]; then
|
|
echo "unknown"
|
|
return
|
|
fi
|
|
|
|
# Call pane-health.sh and interpret exit code
|
|
if "$PANE_HEALTH" -S "$socket" -t "$target" --format text >/dev/null 2>&1; then
|
|
echo "alive"
|
|
else
|
|
local exit_code=$?
|
|
case $exit_code in
|
|
1) echo "dead" ;;
|
|
2) echo "missing" ;;
|
|
3) echo "zombie" ;;
|
|
4) echo "server" ;;
|
|
*) echo "unknown" ;;
|
|
esac
|
|
fi
|
|
}
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Argument parsing
|
|
#------------------------------------------------------------------------------
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--json)
|
|
output_format="json"
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Error: Unknown option: $1" >&2
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Get sessions from registry
|
|
#------------------------------------------------------------------------------
|
|
|
|
registry_data=$(registry_list_sessions)
|
|
session_names=$(echo "$registry_data" | jq -r '.sessions | keys[]' 2>/dev/null || echo "")
|
|
|
|
# Count sessions
|
|
total_count=0
|
|
alive_count=0
|
|
dead_count=0
|
|
|
|
# Build session list with health info
|
|
sessions_with_health=()
|
|
|
|
if [[ -n "$session_names" ]]; then
|
|
while IFS= read -r name; do
|
|
[[ -z "$name" ]] && continue
|
|
|
|
# Get session data
|
|
socket=$(echo "$registry_data" | jq -r ".sessions[\"$name\"].socket")
|
|
target=$(echo "$registry_data" | jq -r ".sessions[\"$name\"].target")
|
|
type=$(echo "$registry_data" | jq -r ".sessions[\"$name\"].type")
|
|
pid=$(echo "$registry_data" | jq -r ".sessions[\"$name\"].pid // \"\"")
|
|
created=$(echo "$registry_data" | jq -r ".sessions[\"$name\"].created_at")
|
|
|
|
# Get health status
|
|
status=$(get_health_status "$socket" "$target")
|
|
|
|
# Update counters
|
|
total_count=$((total_count + 1))
|
|
if [[ "$status" == "alive" ]]; then
|
|
alive_count=$((alive_count + 1))
|
|
else
|
|
dead_count=$((dead_count + 1))
|
|
fi
|
|
|
|
# Store session info
|
|
sessions_with_health+=("$name|$socket|$target|$status|$pid|$created|$type")
|
|
done <<< "$session_names"
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Output results
|
|
#------------------------------------------------------------------------------
|
|
|
|
if [[ "$output_format" == "json" ]]; then
|
|
# JSON output
|
|
echo "{"
|
|
echo " \"sessions\": ["
|
|
|
|
first=true
|
|
for session_info in "${sessions_with_health[@]+"${sessions_with_health[@]}"}"; do
|
|
IFS='|' read -r name socket target status pid created type <<< "$session_info"
|
|
|
|
if [[ "$first" == false ]]; then
|
|
echo ","
|
|
fi
|
|
first=false
|
|
|
|
# Get basename of socket for cleaner output
|
|
socket_basename=$(basename "$socket")
|
|
|
|
cat << EOF
|
|
{
|
|
"name": "$name",
|
|
"socket": "$socket",
|
|
"socket_basename": "$socket_basename",
|
|
"target": "$target",
|
|
"type": "$type",
|
|
"status": "$status",
|
|
"pid": ${pid:-null},
|
|
"created_at": "$created"
|
|
}
|
|
EOF
|
|
done
|
|
|
|
echo ""
|
|
echo " ],"
|
|
echo " \"total\": $total_count,"
|
|
echo " \"alive\": $alive_count,"
|
|
echo " \"dead\": $dead_count"
|
|
echo "}"
|
|
else
|
|
# Table output
|
|
if [[ $total_count -eq 0 ]]; then
|
|
echo "No sessions registered."
|
|
exit 0
|
|
fi
|
|
|
|
# Print header
|
|
printf "%-20s %-20s %-20s %-10s %-8s %-15s\n" \
|
|
"NAME" "SOCKET" "TARGET" "STATUS" "PID" "CREATED"
|
|
printf "%-20s %-20s %-20s %-10s %-8s %-15s\n" \
|
|
"----" "------" "------" "------" "---" "-------"
|
|
|
|
# Print sessions
|
|
for session_info in "${sessions_with_health[@]+"${sessions_with_health[@]}"}"; do
|
|
IFS='|' read -r name socket target status pid created type <<< "$session_info"
|
|
|
|
# Get basename of socket for cleaner output
|
|
socket_basename=$(basename "$socket")
|
|
|
|
# Format time ago
|
|
time_str=$(time_ago "$created")
|
|
|
|
# Truncate long values
|
|
name_trunc="${name:0:20}"
|
|
socket_trunc="${socket_basename:0:20}"
|
|
target_trunc="${target:0:20}"
|
|
|
|
printf "%-20s %-20s %-20s %-10s %-8s %-15s\n" \
|
|
"$name_trunc" "$socket_trunc" "$target_trunc" "$status" "${pid:--}" "$time_str"
|
|
done
|
|
|
|
# Print summary
|
|
echo ""
|
|
echo "Total: $total_count | Alive: $alive_count | Dead: $dead_count"
|
|
fi
|
|
|
|
exit 0
|