Skip to content

Instantly share code, notes, and snippets.

@laiso
Last active March 24, 2026 05:05
Show Gist options
  • Select an option

  • Save laiso/c79649fea1bd3534b00faa7dfb24885d to your computer and use it in GitHub Desktop.

Select an option

Save laiso/c79649fea1bd3534b00faa7dfb24885d to your computer and use it in GitHub Desktop.
Claude Code Plans CLI - List and resume Claude Code sessions with plans

Claude Code Plans CLI

A tool to list and resume Claude Code sessions with plans.

Installation

curl -LO https://gist.githubusercontent.com/laiso/c79649fea1bd3534b00faa7dfb24885d/raw/cc-plans.py
chmod +x cc-plans.py
mv cc-plans.py ~/bin/cc-plans

Then run cc-plans from anywhere.

Usage

./cc-plans.py /path/to/plans

Example output:

=== Claude Code Plans ===

[1] Feature: User Dashboard Implementation
    cd /Users/user/projects/app && claude --resume a75ca22a-ce2a-413c-a8d3-80c5e61538ea
    cd /Users/user/projects/app && claude --resume 7f1826d7-f709-48cb-ad31-354d907d3c87
    cd /Users/user/projects/app && claude --resume agent-acompact-8eb4436d57b4c0dd

[2] bugfix: Login Session Error
    cd /Users/user/projects/app && claude --resume agent-afe5980
    cd /Users/user/projects/app && claude --resume agent-a8fab8b
    cd /Users/user/projects/app && claude --resume agent-a70c926

[3] Refactor: API Layer Cleanup
    cd /Users/user/projects/myapp && claude --resume abc12345-def6-7890-ghij-klmnopqrstuv
    cd /Users/user/projects/myapp && claude --resume xyz98765-uvw4-3210-tsrf-qponmlkjihgf

Multiple sessions for the same plan are grouped together. Sessions are sorted by newest first. Copy the command with the session you want to resume.

Resume a Session

Copy and run the displayed command:

cd /Users/user/projects/myapp && claude --resume xyz98765-uvw4-3210-tsrf-qponmlkjihgf

How It Works

  1. Scans ~/.claude/projects/**/*.jsonl
  2. Parses JSON and extracts slug and cwd
  3. Checks for <plans_dir>/<slug>.md (default: ~/.claude/plans/)
  4. Displays title and session ID (newest sessions first)
#!/usr/bin/env python3
import json
import shlex
import sys
from pathlib import Path
PROJECTS_DIR = Path.home() / ".claude" / "projects"
def process_file(file_path, plans_dir):
session_id = Path(file_path).stem
slug = None
cwd = None
try:
with open(file_path, "r", encoding="utf-8") as f:
for line in f:
try:
data = json.loads(line)
if not slug and "slug" in data:
slug = data["slug"]
if not cwd and "cwd" in data:
cwd = data["cwd"]
if slug and cwd:
break
except json.JSONDecodeError:
continue
except Exception as e:
print(f"Warning: Failed to read {file_path}: {e}", file=sys.stderr)
return None
if not slug:
return None
plan_file = plans_dir / f"{slug}.md"
if not plan_file.exists():
return None
try:
with open(plan_file, "r", encoding="utf-8") as f:
title = f.readline().strip().lstrip("#").strip()
except Exception as e:
print(f"Warning: Failed to read {plan_file}: {e}", file=sys.stderr)
return None
mtime = file_path.stat().st_mtime
return (slug, title, session_id, cwd, mtime)
def main():
if len(sys.argv) > 1:
plans_dir = Path(sys.argv[1])
else:
plans_dir = Path.home() / ".claude" / "plans"
if not PROJECTS_DIR.exists():
print(f"Error: {PROJECTS_DIR} not found", file=sys.stderr)
return 1
if not plans_dir.exists():
print(f"Error: {plans_dir} not found", file=sys.stderr)
return 1
print("=== Claude Code Plans ===")
print()
jsonl_files = list(PROJECTS_DIR.rglob("*.jsonl"))
results = []
for f in jsonl_files:
r = process_file(f, plans_dir)
if r:
results.append(r)
grouped = {}
for slug, title, session_id, cwd, mtime in results:
if slug not in grouped:
grouped[slug] = (title, [])
grouped[slug][1].append((session_id, cwd, mtime))
sorted_results = sorted(grouped.items(), key=lambda x: x[0])
for slug, (title, sessions) in sorted_results:
sessions.sort(key=lambda x: x[2], reverse=True)
if not sorted_results:
print("No sessions found")
return 0
for i, (slug, (title, sessions)) in enumerate(sorted_results, 1):
print(f"[{i}] {title}")
for session_id, cwd, _ in sessions:
if cwd:
print(f" cd {shlex.quote(cwd)} && claude --resume {session_id}")
else:
print(f" claude --resume {session_id}")
print()
return 0
if __name__ == "__main__":
exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment