feat(tmux): implement 2-hour inactivity session TTL reaper and prune command

This commit is contained in:
operator
2026-10-05 16:23:45 +00:00
parent c13ee20ea4
commit 945e6bb481
4 changed files with 72 additions and 0 deletions
+39
View File
@@ -105,6 +105,40 @@ def cmd_kill(args):
print(f"Error: {err.strip() or out.strip()}", file=sys.stderr)
return rc
def cmd_prune(args):
ttl_seconds = getattr(args, "ttl", 7200) or 7200
rc, out, err = _run_tmux("list-sessions", "-F", "#{session_name} #{session_activity} #{session_attached}")
if rc != 0:
if "no server running" in (err or "").lower() or rc == 1:
print(f"No active tmux server on {SOCKET_PATH}.")
return 0
print(f"Error listing sessions: {err.strip() or out.strip()}", file=sys.stderr)
return rc
now = int(time.time())
reaped = []
kept = []
for line in out.strip().splitlines():
parts = line.split()
if len(parts) >= 3:
s_name, s_activity, s_attached = parts[0], int(parts[1]), int(parts[2])
idle_time = now - s_activity
# Only prune if unattached and idle > TTL
if s_attached == 0 and idle_time > ttl_seconds:
_run_tmux("kill-session", "-t", s_name)
reaped.append((s_name, idle_time))
else:
kept.append((s_name, idle_time, s_attached))
if reaped:
print(f"✔ Reaped {len(reaped)} stale unattached session(s) (idle > {ttl_seconds//3600}h):")
for s_name, idle in reaped:
print(f" • {s_name} (idle: {idle//60}m)")
else:
print(f"No stale unattached sessions to reap (all active within {ttl_seconds//3600}h).")
return 0
def cmd_attach(args):
session = args.session
cmd = [TMUX_BIN, "-S", SOCKET_PATH, "attach", "-t", session]
@@ -144,6 +178,11 @@ def main():
p_kill.add_argument("session", help="Session name")
p_kill.set_defaults(func=cmd_kill)
# prune
p_prune = subparsers.add_parser("prune", help="Reap stale unattached sessions inactive for >TTL (default: 7200s / 2h)")
p_prune.add_argument("--ttl", type=int, default=7200, help="Inactivity threshold in seconds (default: 7200)")
p_prune.set_defaults(func=cmd_prune)
# attach
p_att = subparsers.add_parser("attach", help="Attach to a session interactively")
p_att.add_argument("session", help="Session name")