- 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
50 lines
1.3 KiB
Python
Executable file
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}")
|