session-tools/bin/_claude-projects
Natalie 47434868e0 rclaude: list/resume now cover on-disk Claude sessions, not just tmux
- new bin/_claude-projects helper: prints tab-sep mtime/cwd/count for every
  ~/.claude/projects/ dir (parses .jsonl entries for cwd field)
- list_tmux_on / list_disk_on / list_all_on: unified enumeration with KIND col
- rclaude list [all|tmux|disk]: filterable view, sorted by recency
- rclaude resume <pattern>: matches against tmux + disk; tmux match attaches,
  disk match re-execs self to spawn fresh tmux + claude --continue at the cwd
- helper streamed to remote via 'ssh host python3 -' so no install required
  on the remote side beyond python3
2026-04-26 00:04:09 -07:00

50 lines
1.3 KiB
Python
Executable file

#!/usr/bin/env python3
# Internal helper for rclaude — prints one tab-separated line per Claude
# project directory under ~/.claude/projects/, sorted by most recent first.
#
# Output columns: <mtime_epoch>\t<cwd>\t<session_count>
#
# Used by `rclaude list` and `rclaude resume` to discover sessions that exist
# on disk but have no live tmux session attached. Run locally or invoked
# remotely via ssh.
import json
import os
import sys
from pathlib import Path
root = Path.home() / ".claude" / "projects"
if not root.is_dir():
sys.exit(0)
rows = []
for project_dir in root.iterdir():
if not project_dir.is_dir():
continue
jsonls = sorted(project_dir.glob("*.jsonl"), key=lambda p: p.stat().st_mtime, reverse=True)
if not jsonls:
continue
latest = jsonls[0]
cwd = None
try:
with latest.open() as f:
for line in f:
try:
entry = json.loads(line)
except json.JSONDecodeError:
continue
if entry.get("cwd"):
cwd = entry["cwd"]
break
except OSError:
continue
if not cwd:
continue
mtime = int(latest.stat().st_mtime)
rows.append((mtime, cwd, len(jsonls)))
rows.sort(reverse=True)
for mtime, cwd, count in rows:
print(f"{mtime}\t{cwd}\t{count}")