Skip to main content

Claude Code Manager — manage Claude Code projects, sessions, and memory

Project description

ccm

Claude Code Manager — a CLI + TUI for everything Claude Code stores under ~/.claude/projects/.

PyPI Downloads License: MIT Python uv Stars

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/pip if you prefer). The PyPI distribution is named claudecm (the unqualified ccm was already taken). The console command stays ccm.

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 scriptingccm ls --sort size -n 10, ccm export <project> -f md, ccm stats.
  • Decodes folder names correctly — by reading the real cwd from 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

Contributors

License

MIT © QuocTang

Star history

Star History Chart

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

claudecm-0.1.1.tar.gz (56.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

claudecm-0.1.1-py3-none-any.whl (26.1 kB view details)

Uploaded Python 3

File details

Details for the file claudecm-0.1.1.tar.gz.

File metadata

  • Download URL: claudecm-0.1.1.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

Hashes for claudecm-0.1.1.tar.gz
Algorithm Hash digest
SHA256 9a5d491ced762baa9a262e22f167881f2abebf06ef64e3cd90a3f055492869b7
MD5 5d3d3866606473f814b06a5eac0da41b
BLAKE2b-256 d72cede842609088d3dd30eb113ab52d2f4e0d05d2cc3a16bd62fce0f6012037

See more details on using hashes here.

Provenance

The following attestation bundles were made for claudecm-0.1.1.tar.gz:

Publisher: release.yml on QuocTang/ccm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file claudecm-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: claudecm-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 26.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for claudecm-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 62ade9a71d80719400bb67dae6117d8e5e22e4a551ca2382d13f7569d466ac57
MD5 e557ad7378dba0e7fd435db4aa00f436
BLAKE2b-256 9056288b6a386609250e0d009017ababd9842834ae183af841b28a7b9e9e853d

See more details on using hashes here.

Provenance

The following attestation bundles were made for claudecm-0.1.1-py3-none-any.whl:

Publisher: release.yml on QuocTang/ccm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page