Commit 28313e7f1394

Vincent Demeester <vincent@sbr.pm>
2026-01-29 13:45:16
feat(shpool): add shpool-connect fuzzel/fzf session selector
Add interactive script to connect to shpool sessions on remote hosts: - Dynamically extracts shpool-enabled hosts from SSH config - Two-step selection: host first, then session - Works with fuzzel (wayland) and fzf (terminal) - Opens sessions in kitty when running in wayland environment - Supports creating new sessions via [new session] option Includes .desktop file for launching from app launchers. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent e3492a1
Changed files (3)
home
pkgs
my
scripts
home/common/desktop/default.nix
@@ -64,4 +64,5 @@
   };
 
   home.file.".local/share/applications/yubikey-oath.desktop".source = ./yubikey-oath.desktop;
+  home.file.".local/share/applications/shpool-connect.desktop".source = ./shpool-connect.desktop;
 }
home/common/desktop/shpool-connect.desktop
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Name=Shpool Connect
+Comment=Connect to shpool sessions on remote hosts
+Exec=shpool-connect
+Type=Application
+Terminal=false
+Categories=Utility;System;
+Icon=utilities-terminal
pkgs/my/scripts/bin/shpool-connect
@@ -0,0 +1,116 @@
+#!/usr/bin/env bash
+# shpool-connect - Interactive shpool session selector with fuzzel/fzf
+#
+# Features:
+# - Lists available hosts from SSH config (detects shpool-enabled hosts)
+# - Lists sessions on selected host
+# - Attaches to selected session using kitty (wayland) or current terminal
+set -euo pipefail
+
+# Extract shpool-enabled hosts from SSH config
+# These are hosts with the pattern "host/*" (shpool session aliases)
+get_shpool_hosts() {
+    ssh -G "dummy.home/test" 2>/dev/null | head -1 >/dev/null  # validate ssh config works
+    # Parse SSH config for "Host X/*" patterns and extract X
+    grep -E '^Host [^*]+/\*$' ~/.ssh/config 2>/dev/null | \
+        sed 's/^Host //' | sed 's|/\*$||' | sort -u
+}
+
+# Detect environment
+DESKTOP="${XDG_CURRENT_DESKTOP:-}"
+GRAPHICS=1
+
+if [[ "$DESKTOP" != "sway" && "$DESKTOP" != "niri" ]]; then
+    if ! command -v xset &>/dev/null; then
+        GRAPHICS=0
+    elif ! timeout 1s xset q &>/dev/null 2>&1; then
+        GRAPHICS=0
+    fi
+fi
+
+# Select function based on environment
+select_item() {
+    local prompt="$1"
+    if [[ GRAPHICS -eq 0 ]]; then
+        fzf --prompt "$prompt"
+    elif [[ "$DESKTOP" == "sway" || "$DESKTOP" == "niri" ]]; then
+        fuzzel --dmenu --prompt "$prompt" --lines 15 --width 50
+    else
+        fzf --prompt "$prompt"
+    fi
+}
+
+notify() {
+    local title="$1"
+    local msg="$2"
+    if [[ GRAPHICS -eq 1 ]]; then
+        notify-send "$title" "$msg"
+    else
+        echo "$title: $msg"
+    fi
+}
+
+# Step 1: Select host
+shpool_hosts=$(get_shpool_hosts)
+
+if [[ -z "$shpool_hosts" ]]; then
+    notify "shpool" "No shpool-enabled hosts found in SSH config"
+    exit 1
+fi
+
+selected_host=$(echo "$shpool_hosts" | select_item "Host: ")
+
+if [[ -z "$selected_host" ]]; then
+    exit 0
+fi
+
+# Step 2: Get sessions on the host
+sessions=$(ssh "$selected_host" shpool list 2>/dev/null | tail -n +2 | awk '{print $1}')
+
+if [[ -z "$sessions" ]]; then
+    notify "shpool" "No sessions on $selected_host"
+    exit 0
+fi
+
+# Add option to create new session
+sessions="[new session]"$'\n'"$sessions"
+
+selected_session=$(echo "$sessions" | select_item "Session on $selected_host: ")
+
+if [[ -z "$selected_session" ]]; then
+    exit 0
+fi
+
+# Handle new session creation
+if [[ "$selected_session" == "[new session]" ]]; then
+    # Prompt for session name
+    if [[ GRAPHICS -eq 0 ]]; then
+        echo -n "Session name: "
+        read -r selected_session
+    elif [[ "$DESKTOP" == "sway" || "$DESKTOP" == "niri" ]]; then
+        selected_session=$(echo "" | fuzzel --dmenu --prompt "New session name: " --width 30)
+    else
+        echo -n "Session name: "
+        read -r selected_session
+    fi
+
+    if [[ -z "$selected_session" ]]; then
+        exit 0
+    fi
+fi
+
+# Step 3: Attach to session
+ssh_target="${selected_host}/${selected_session}"
+
+if [[ GRAPHICS -eq 1 ]] && [[ "$DESKTOP" == "sway" || "$DESKTOP" == "niri" ]]; then
+    # Use kitty for graphical wayland environments
+    if command -v kitty &>/dev/null; then
+        exec kitty --single-instance --instance-group=shpool ssh "$ssh_target"
+    else
+        notify "shpool" "kitty not found, falling back to terminal"
+        exec ssh "$ssh_target"
+    fi
+else
+    # Terminal mode - just SSH directly
+    exec ssh "$ssh_target"
+fi