Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,17 @@
},
"source": "./plugins/security-guidance",
"category": "security"
},
{
"name": "sessions",
"description": "List, inspect, and delete Claude Code sessions stored locally. Project-scoped by default with cross-platform support.",
"version": "1.0.0",
"author": {
"name": "Venkat Chinni",
"email": "nithinchinni2002@gmail.com"
},
"source": "./plugins/session-manager",
"category": "productivity"
}
]
}
9 changes: 9 additions & 0 deletions plugins/session-manager/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "sessions",
"description": "List, inspect, and delete Claude Code sessions stored locally",
"version": "1.0.0",
"author": {
"name": "Venkat Chinni",
"email": "nithinchinni2002@gmail.com"
}
}
76 changes: 76 additions & 0 deletions plugins/session-manager/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Sessions Plugin

Manage Claude Code sessions stored on your local machine. List, inspect, and delete sessions that accumulate over time.

## Why?

Claude Code stores every conversation as session files locally. Over time these accumulate and there's no built-in way to clean them up. This plugin adds that capability.

## Commands

### `/sessions:list [--all | search term]`

List sessions for the **current project** by default. Pass `--all` to see sessions across all projects.

Shows:
- Session title and ID
- Start date
- Disk usage
- Orphan status (sessions with conversation data but no metadata)

### `/sessions:delete [session-id | search term | --all]`

Delete one or more sessions from the **current project**. Pass `--all` to operate across all projects.

Supports:
- Deleting by session ID (UUID)
- Searching by title
- Interactive selection from a numbered list
- Bulk deletion

Always asks for confirmation before deleting. Will not delete the currently active session.

**Files removed per session:**
- `{config_dir}/projects/{path}/{sessionId}/` (subagent logs directory)
- `{config_dir}/projects/{path}/{sessionId}.jsonl` (conversation data)
- `{config_dir}/sessions/{pid}.json` (metadata)

## Cross-Platform Support

The plugin automatically detects the correct config directory:

| Platform | Config Directory | Notes |
|----------|-----------------|-------|
| macOS | `~/.claude` | Default location |
| Linux | `$XDG_CONFIG_HOME/claude` | Falls back to `~/.claude` |
| Windows | `%APPDATA%\claude` | Falls back to `%LOCALAPPDATA%\claude`, then `~\.claude` |
| Any | `$CLAUDE_CONFIG_DIR` | Override via environment variable (highest priority) |

## Session Storage Layout

```
{config_dir}/
├── sessions/
│ └── {pid}.json # Session metadata (pid, sessionId, cwd, startedAt)
├── projects/
│ └── {encoded-cwd}/
│ ├── {sessionId}.jsonl # Full conversation history
│ └── {sessionId}/ # Subagent logs (tied to session)
│ └── subagents/
│ └── agent-*.jsonl
└── history.jsonl # All user prompts across sessions
```

## Installation

Launch Claude Code with the plugin directory:

```bash
claude --plugin-dir /path/to/plugins/session-manager
```

Or to always have it available, add a shell alias:

```bash
alias claude='claude --plugin-dir /path/to/plugins/session-manager'
```
92 changes: 92 additions & 0 deletions plugins/session-manager/commands/delete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
allowed-tools: Read, Glob, Bash(rm:*), Bash(rm -r:*)
description: Delete Claude Code sessions for the current project
argument-hint: "[session-id, search term, or --all]"
---

## Context

You are helping the user delete Claude Code sessions stored on their local machine. By default, only show and delete sessions for the **current project directory**. If the user passes `--all` as part of `$ARGUMENTS`, operate across all projects.

### How to find the config directory

The Claude Code config directory varies by platform:
- **Override**: `$CLAUDE_CONFIG_DIR` (if set)
- **macOS**: `~/.claude`
- **Linux**: `$XDG_CONFIG_HOME/claude` (fallback: `~/.claude`)
- **Windows**: `%APPDATA%\claude` (fallback: `%LOCALAPPDATA%\claude`, then `~\.claude`)

### How sessions are stored

1. **Session metadata**: `{config_dir}/sessions/{pid}.json` — contains `pid`, `sessionId`, `cwd`, `startedAt`
2. **Session conversation data**: `{config_dir}/projects/{encoded-path}/{sessionId}.jsonl` — the actual conversation log. The `{encoded-path}` is the working directory with `/` replaced by `-` and a leading `-` (e.g., `/Users/me/project` becomes `-Users-me-project`).
3. **Session history**: `{config_dir}/history.jsonl` — contains all user prompts with their `sessionId`

### How to scope to current project

Convert the current working directory to the encoded path format. For example:
- CWD: `/Users/jane/projects/my-app`
- Encoded: `-Users-jane-projects-my-app`
- JSONL location: `{config_dir}/projects/-Users-jane-projects-my-app/*.jsonl`

## Steps

### Step 1: Find sessions

**IMPORTANT**: Session JSONL files are UUID-named files directly under the project directory (e.g., `a1b2c3d4-e5f6-7890-abcd-ef1234567890.jsonl`). There are also `subagents/` subdirectories containing agent log files — **ignore those**. Use a UUID glob pattern to match only session files:

Use **Glob** to find session JSONL files:
- **Project-scoped** (default): `{config_dir}/projects/{encoded-cwd}/????????-????-????-????-????????????.jsonl`
- **All projects** (if `--all` in arguments): `{config_dir}/projects/*/????????-????-????-????-????????????.jsonl`

Then use **Read** to get the title from the first few lines of each JSONL (look for `"type": "custom-title"`).

Also use **Glob** and **Read** on `{config_dir}/sessions/*.json` to find matching metadata files.

### Step 2: Identify which session(s) to delete

If the user provided `$ARGUMENTS` (besides `--all`):
- If it looks like a UUID, match it against session IDs
- If it's a number, treat it as a selection from the list
- Otherwise, search session titles for the term

If no specific session was identified, present a numbered list and ask the user which session(s) they want to delete. Support:
- A single number (e.g., "3")
- Multiple numbers (e.g., "1, 3, 5")
- "all" to delete all listed sessions
- A search term to filter

### Step 3: Confirm before deleting

**IMPORTANT**: Before deleting, clearly show the user:
- Session ID
- Session title (if available)
- Start date
- Files that will be deleted (full paths)

Ask for explicit confirmation. Do NOT delete without the user saying yes.

**Do not delete the current session.** You can identify the current session because its session ID matches the one in the most recent metadata file for the current working directory.

### Step 4: Delete the session files

For each confirmed session, delete these in order:
1. The subagents directory (if it exists): `rm -r {config_dir}/projects/{encoded-path}/{sessionId}/` — this contains subagent log files tied to the session
2. The conversation JSONL: `rm {config_dir}/projects/{encoded-path}/{sessionId}.jsonl`
3. The matching metadata file (if any): `rm {config_dir}/sessions/{pid}.json` — find the right one by reading each metadata JSON and matching the `sessionId` field

Delete one item at a time. Only use `rm -r` on the `{sessionId}/` subagents directory — never on anything else.

### Step 5: Summary

Report:
- How many sessions were deleted
- Which files were removed
- Any errors encountered

### Important notes

- Use **Read** and **Glob** for discovery. Only use **Bash** for the actual `rm` deletion step.
- Read multiple files in parallel when possible for speed.
- Never delete the currently active session.
- Never use `rm -rf` or wildcards — only delete specific named files.
84 changes: 84 additions & 0 deletions plugins/session-manager/commands/list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
allowed-tools: Read, Glob
description: List Claude Code sessions for the current project
argument-hint: "[--all to show all projects]"
---

## Context

You are listing Claude Code sessions stored on the user's local machine. By default, only show sessions for the **current project directory**. If the user passes `--all` as `$ARGUMENTS`, show sessions across all projects.

### How to find the config directory

The Claude Code config directory varies by platform:
- **Override**: `$CLAUDE_CONFIG_DIR` (if set)
- **macOS**: `~/.claude`
- **Linux**: `$XDG_CONFIG_HOME/claude` (fallback: `~/.claude`)
- **Windows**: `%APPDATA%\claude` (fallback: `%LOCALAPPDATA%\claude`, then `~\.claude`)

### How sessions are stored

1. **Session metadata**: `{config_dir}/sessions/{pid}.json` — contains `pid`, `sessionId`, `cwd`, `startedAt`
2. **Session conversation data**: `{config_dir}/projects/{encoded-path}/{sessionId}.jsonl` — the actual conversation log. The `{encoded-path}` is the working directory with `/` replaced by `-` and a leading `-` (e.g., `/Users/me/project` becomes `-Users-me-project`).
3. **Session history**: `{config_dir}/history.jsonl` — contains all user prompts with their `sessionId`

### How to scope to current project

Convert the current working directory to the encoded path format used in `{config_dir}/projects/`. For example:
- CWD: `/Users/jane/projects/my-app`
- Encoded: `-Users-jane-projects-my-app`
- JSONL location: `{config_dir}/projects/-Users-jane-projects-my-app/*.jsonl`

## Steps

### Step 1: Determine the config directory

Use the platform detection logic above. For most users this will be `~/.claude`.

### Step 2: Find session JSONL files

**IMPORTANT**: Session JSONL files are UUID-named files directly under the project directory (e.g., `a1b2c3d4-e5f6-7890-abcd-ef1234567890.jsonl`). There are also `subagents/` subdirectories containing agent log files — **ignore those**. Use a UUID glob pattern to match only session files:

Use the **Glob** tool to find session files:
- **Project-scoped** (default): Glob for `{config_dir}/projects/{encoded-cwd}/????????-????-????-????-????????????.jsonl`
- **All projects** (if `$ARGUMENTS` contains `--all`): Glob for `{config_dir}/projects/*/????????-????-????-????-????????????.jsonl`

This UUID pattern ensures subagent files in nested directories are excluded.

### Step 3: Read session details

For each JSONL file found:
1. Use **Read** to read the first 5 lines of each JSONL file to find the `custom-title` entry (it's typically the first line with `"type": "custom-title"`)
2. Note the file size from the Glob results or by reading the file

Also use **Glob** to find `{config_dir}/sessions/*.json`, then **Read** each one to get metadata (`sessionId`, `cwd`, `startedAt`). Match these to the JSONL files by `sessionId`.

JSONL files that have no matching metadata JSON are **orphaned sessions** — mark them as `[orphan]`.

### Step 4: Display results

Present a clean numbered list:

```
Sessions for /Users/jane/projects/my-app:

1. Add authentication flow
ID: a1b2c3d4-e5f6-7890-abcd-ef1234567890
Started: 2026-03-13 14:53
Size: 678.0 KB

2. (no title) [orphan]
ID: f9e8d7c6-b5a4-3210-fedc-ba0987654321
Started: 2026-03-10 09:00
Size: 12.5 KB

Found 2 session(s): 1 active, 1 orphaned (total: 690.5 KB)
```

If `$ARGUMENTS` contains a search term (not `--all`), filter sessions by matching the term against title, session ID, or directory.

### Important notes

- Use **only** the Read and Glob tools. Do NOT use Bash.
- Read multiple files in parallel when possible for speed.
- Do not include the currently active session's ID in the output — note it as "(current session)" instead.