Claude Code Manager — manage Claude Code projects, sessions, and memory
Project description
Claude Code Manager — a CLI + TUI for everything Claude Code stores under ~/.claude/projects/.
List projects, browse sessions, view / delete / export them, inspect memory
files, see disk-usage stats — without cd-ing into a directory full of
URL-encoded path names.
Quick start
uv tool install claudecm
ccm # launches the TUI
ccm ls # subcommand mode
ccm stats # disk-usage dashboard
Requires Python 3.10+ and uv (or
pipx/pipif you prefer). The PyPI distribution is namedclaudecm(the unqualifiedccmwas already taken). The console command staysccm.
Why ccm
~/.claude/projects/ accumulates fast: every Claude Code session writes a
JSONL file, every project keeps its own memory directory, and the folder names
are a one-way path encoding (/home/q/my_projects/foo →
-home-q-my-projects-foo). Going in with ls and rm is painful.
- One pane to navigate them all — projects on the left, sessions on the right, Claude-style spinner up top.
- Subcommands for scripting —
ccm ls --sort size -n 10,ccm export <project> -f md,ccm stats. - Decodes folder names correctly — by reading the real
cwdfrom inside each session's JSONL, not by replacing-with/and hoping. - Knows about memory and PRs — surfaces
memory/*.md, counts messages by type, picks up custom session titles. - No daemon, no config — operates directly on the on-disk layout Claude Code already uses.
Installation
From PyPI (recommended)
uv tool install claudecm # global, exposes `ccm`
# alternatives:
pipx install claudecm
pip install --user claudecm
Run without installing (one-off)
uvx --from claudecm ccm ls
From source (latest main)
git clone https://github.com/QuocTang/ccm
cd ccm
uv tool install . # global
# or for dev work:
uv sync --extra dev
uv run ccm --help
From a GitHub commit/branch
uv tool install git+https://github.com/QuocTang/ccm
Usage
ccm # launch TUI (default when no args)
ccm ls # list projects (sorted by recent activity)
ccm ls -s size -n 10 # sort by size, top 10
ccm show <project> # detail for one project
ccm sessions <project> # list sessions of a project
ccm view <project> <sess> # render messages of a session
ccm rm <project> # delete a project directory (with confirm)
ccm rm-session <p> <s> # delete one session
ccm export <p> [<s>] -f md # export to markdown (or -f json | raw)
ccm memory <project> # view memory files
ccm memory <p> --show NAME # print one memory file
ccm memory <p> --rm NAME # delete one memory file
ccm stats # disk usage dashboard
ccm tui # launch TUI explicitly
<project> accepts an encoded dir name, the real cwd path, the basename
(e.g. my-project), or any unique substring of either.
<session> accepts the full UUID or a unique prefix (the 8-char head shown
by ccm sessions is usually enough).
TUI keys
| Key | Action |
|---|---|
↑/↓ j/k |
Move cursor |
h/l ←/→ |
Focus projects / sessions pane |
Tab |
Switch panes |
Enter |
Drill in (project → sessions → view) |
m |
Show memory for highlighted project |
d |
Delete focused project / session |
r |
Refresh |
q Ctrl+C |
Quit (or back inside a sub-screen) |
Inside a delete-confirm modal: y / Enter to confirm, n / Esc to cancel.
Architecture
Three layers, deliberately separated so domain code stays UI-agnostic.
flowchart LR
User([Terminal user])
subgraph ccm
direction TB
CLI["cli/<br/><sub>typer subcommands</sub>"]
TUI["tui/<br/><sub>textual app</sub>"]
CORE["core/<br/><sub>projects · sessions · memory · stats · export</sub>"]
SHARED["palette.py · paths.py<br/><sub>shared theme & path helpers</sub>"]
end
Disk[("~/.claude/projects/<br/>JSONL sessions + memory/")]
User -- "ccm <subcommand>" --> CLI
User -- "ccm (no args)" --> TUI
CLI --> CORE
TUI --> CORE
CLI -.-> SHARED
TUI -.-> SHARED
CORE --> Disk
The lossy folder-name encoding is the one bit that requires care: Claude Code
replaces both / and _ with -, so paths.real_cwd_from_sessions() reads
the actual cwd field from the first session JSONL inside each directory.
The naive - → / replacement is only a fallback for empty projects.
Development
uv sync --extra dev # install + pytest
uv run pytest -q # run all tests
uv run pytest tests/core/test_paths.py -k naive_decode # one test
uv tool install . --force --reinstall # rebuild global `ccm`
See CLAUDE.md for architecture notes and the textual / typer
gotchas we hit (lossy path encoding, Widget._size shadowing, markup escaping,
etc).
Contributing
PRs welcome. Keep the three-layer split (core stays UI-agnostic), run
uv run pytest -q before pushing, and follow the gotchas in CLAUDE.md if you
touch tui/.
Contributors
License
MIT © QuocTang
Star history
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file claudecm-0.1.2.tar.gz.
File metadata
- Download URL: claudecm-0.1.2.tar.gz
- Upload date:
- Size: 56.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ead01bc3a95f180fee525c6c679d64e623441326de5e129478c0b8e1699e1b89
|
|
| MD5 |
c2c74ab3bddd32e09a1234c36811bd4f
|
|
| BLAKE2b-256 |
00462b80cb5642cc4451c71e2c2b2f3a2eea70fdabe32bd5f35b7db220b85a96
|
Provenance
The following attestation bundles were made for claudecm-0.1.2.tar.gz:
Publisher:
release.yml on QuocTang/ccm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
claudecm-0.1.2.tar.gz -
Subject digest:
ead01bc3a95f180fee525c6c679d64e623441326de5e129478c0b8e1699e1b89 - Sigstore transparency entry: 1532398149
- Sigstore integration time:
-
Permalink:
QuocTang/ccm@3833e5f3be9cc3d926373117d9c9e08ba3cb5058 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/QuocTang
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3833e5f3be9cc3d926373117d9c9e08ba3cb5058 -
Trigger Event:
push
-
Statement type:
File details
Details for the file claudecm-0.1.2-py3-none-any.whl.
File metadata
- Download URL: claudecm-0.1.2-py3-none-any.whl
- Upload date:
- Size: 26.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
af87750df29358279f8ca3edcfe261c9e074ce2e0492154e4128ccb6f994f9d6
|
|
| MD5 |
2b4a572cf70f80a96a7548999e8ee75a
|
|
| BLAKE2b-256 |
2c7a3f97e01891669f0c14e1ff2cadd924ff32cae68e460c4e218c9c36e8667f
|
Provenance
The following attestation bundles were made for claudecm-0.1.2-py3-none-any.whl:
Publisher:
release.yml on QuocTang/ccm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
claudecm-0.1.2-py3-none-any.whl -
Subject digest:
af87750df29358279f8ca3edcfe261c9e074ce2e0492154e4128ccb6f994f9d6 - Sigstore transparency entry: 1532398205
- Sigstore integration time:
-
Permalink:
QuocTang/ccm@3833e5f3be9cc3d926373117d9c9e08ba3cb5058 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/QuocTang
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3833e5f3be9cc3d926373117d9c9e08ba3cb5058 -
Trigger Event:
push
-
Statement type: