Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
dc3fd23
chore: update Go version and dependencies in go.mod and go.sum
hoangsvit Jun 26, 2026
621363a
Merge remote-tracking branch 'origin/main' into develop
hoangsvit Jun 26, 2026
1d7b23e
chore: update Go version to 1.25 in workflows and documentation
hoangsvit Jun 26, 2026
03dbce2
docs: enhance usage instructions and key bindings in help output
hoangsvit Jun 26, 2026
33168a8
chore: optimize sleep durations and add environment variables in demo…
hoangsvit Jun 26, 2026
a517702
chore: add screenshot.tape for demo GIF generation and update artifac…
hoangsvit Jun 26, 2026
9564387
chore: remove height settings from demo scripts for consistency
hoangsvit Jun 26, 2026
65cbe0b
chore: update width setting in demo script for improved layout
hoangsvit Jun 26, 2026
ef038f8
chore: remove width settings from demo scripts for consistency
hoangsvit Jun 26, 2026
9b14177
test: update boundary navigation tests to reflect cursor wrapping beh…
hoangsvit Jun 26, 2026
46edf10
fix: update display name to show only the base project path
hoangsvit Jun 26, 2026
aace6e8
feat: enhance token usage aggregation and fallback mechanism in sessi…
hoangsvit Jun 26, 2026
f759960
feat: add screenshot GIF generation and update README with demo scree…
hoangsvit Jun 26, 2026
92f130c
feat: add features demo GIF and update README with new demo section
hoangsvit Jun 26, 2026
77872d0
1.1.0
hoangsvit Jun 26, 2026
75ae946
feat: add SCREENSHOTS.md for scenario walkthroughs and demo previews
hoangsvit Jun 26, 2026
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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ jobs:
- macos-latest
- windows-latest
go:
- "1.23"
- "1.24"
- "1.25"
- "1.26"

steps:
- uses: actions/checkout@v5
Expand Down
20 changes: 17 additions & 3 deletions .github/workflows/demo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:

- uses: actions/setup-go@v6
with:
go-version: "1.24"
go-version: "1.25"
cache: true

- name: Cache VHS binary
Expand Down Expand Up @@ -74,6 +74,8 @@ jobs:
vhs demo/full.tape
vhs demo/cancel.tape
vhs demo/update.tape
vhs demo/features.tape
vhs demo/screenshot.tape

# On PRs: upload as artifact for preview — cannot commit to fork branches
- name: Upload GIFs as artifact (PR preview)
Expand All @@ -82,7 +84,9 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: demo-gifs
path: demo/*.gif
path: |
demo/*.gif
demo/*.png
retention-days: 7

- name: Publish GIFs for inline PR preview
Expand Down Expand Up @@ -134,11 +138,13 @@ jobs:
full_markdown="$(publish_markdown demo/full.gif)"
cancel_markdown="$(publish_markdown demo/cancel.gif)"
update_markdown="$(publish_markdown demo/update.gif)"
features_markdown="$(publish_markdown demo/features.gif)"

set_output help "$help_markdown"
set_output full "$full_markdown"
set_output cancel "$cancel_markdown"
set_output update "$update_markdown"
set_output features "$features_markdown"

- name: Comment demo GIF preview on PR
if: github.event_name == 'pull_request'
Expand All @@ -148,6 +154,8 @@ jobs:
FULL_GIF: ${{ steps.publish-gifs.outputs.full }}
CANCEL_GIF: ${{ steps.publish-gifs.outputs.cancel }}
UPDATE_GIF: ${{ steps.publish-gifs.outputs.update }}
FEATURES_GIF: ${{ steps.publish-gifs.outputs.features }}
ARTIFACT_URL: ${{ steps.upload-gifs.outputs.artifact-url }}
with:
script: |
const marker = '<!-- claude-cleaner-demo-gifs -->';
Expand All @@ -157,6 +165,12 @@ jobs:
'',
'The newest generated terminal GIFs for this pull request are shown below:',
'',
'### Screenshot',
`[Download screenshot.png](${process.env.ARTIFACT_URL})`,
'',
'### Search, sort, filter, category',
process.env.FEATURES_GIF,
'',
'### Help',
process.env.HELP_GIF,
'',
Expand Down Expand Up @@ -202,4 +216,4 @@ jobs:
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "chore: update demo GIFs [skip ci]"
file_pattern: demo/*.gif
file_pattern: demo/*.gif demo/*.png
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:

- uses: actions/setup-go@v6
with:
go-version: "1.24"
go-version: "1.25"
cache: true

- name: Run GoReleaser
Expand Down
33 changes: 33 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Architecture

## Session discovery

```mermaid
flowchart TD
A([Start scan]) --> B{"~/.claude.json\nexists?"}
B -- Yes --> C{"Has projects\nmap?"}
B -- No / unreadable --> D[scanFromDir\nenumerate subdirs]
C -- Yes --> E[deduplicateProjects\ncase-insensitive merge]
C -- "No / malformed" --> D
E --> F[["For each project path\n(concurrent goroutines)"]]
D --> F
F --> G["encodePath → dir name\ne.g. d--laragon-www-g-front"]
G --> H["projectStats\nsize + mtime"]
H --> I[Resolve tokens]
I --> J([Session list])
```

## Token resolution

```mermaid
flowchart TD
A([Project entry]) --> B{"claude.json has\nlastTotal* fields?"}
B -- Yes --> C["Sum all 4 fields\ninput + output +\ncache_creation +\ncache_read"]
B -- No --> D["Scan .jsonl files\nbufio line-by-line"]
D --> E{"assistant message\nwith usage found?"}
E -- Yes --> F["Sum tokens\nacross all sessions"]
E -- No --> G(["HasTokenData = false\nDisplay —"])
C --> H(["HasTokenData = true"])
F --> H
H --> I["formatTokens\n→ 108.6K / 9.9M / ..."]
```
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@

## Unreleased

- Token column now falls back to summing `message.usage` from session `.jsonl` files when `~/.claude.json` does not contain `lastTotal*` token fields (common on newer Claude Code installs).
- UI Project column shows only the last folder name (e.g. `g-front`) instead of the full path; full path is still used internally for correct deletion.
- Bumped minimum Go version to 1.25 (go.mod).
- Updated CI matrix to Go 1.25 / 1.26 across Windows, macOS, and Linux.
- Updated all workflows (ci, demo, release) to Go 1.25.
- Added Snyk security scanning workflow (push / PR + weekly schedule).
- Upgraded dependencies to fix HIGH/MEDIUM Snyk findings:
- `golang.org/x/text` v0.3.8 → v0.38.0 (CWE-1327)
- `golang.org/x/sys` v0.27.0 → v0.46.0 (CWE-190)
- `github.com/charmbracelet/bubbletea` v1.2.4 → v1.3.10
- `github.com/charmbracelet/bubbles` v0.20.0 → v1.0.0
- `github.com/charmbracelet/lipgloss` v1.0.0 → v1.1.0
- Restructured README: install section promoted, dev content moved to CONTRIBUTING.md.
- Improved asynchronous directory scanning and deletion safety.
- Added automated tests on Windows, macOS, and Linux.
- Added OIDC-based npm publishing and tag-based GitHub Release automation.
Expand Down
15 changes: 4 additions & 11 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ Thank you for your interest in contributing!

| Layer | Tool |
| --- | --- |
| CLI / TUI | Go 1.22+, [Bubble Tea](https://github.com/charmbracelet/bubbletea), [Lip Gloss](https://github.com/charmbracelet/lipgloss) |
| CLI / TUI | Go 1.25+, [Bubble Tea](https://github.com/charmbracelet/bubbletea), [Lip Gloss](https://github.com/charmbracelet/lipgloss) |
| npm wrapper | Node.js 20+ (thin shim — downloads Go binary on install) |
| Releases | [GoReleaser](https://goreleaser.com) + GitHub Actions |
| Demo GIFs | [VHS](https://github.com/charmbracelet/vhs) |

## Prerequisites

- [Go 1.22+](https://go.dev/dl/)
- [Go 1.25+](https://go.dev/dl/)
- [Node.js 20+](https://nodejs.org/) (for npm wrapper scripts)
- Git

Expand Down Expand Up @@ -65,14 +65,6 @@ go run . --claude-dir $env:TEMP\claude-demo

Creates 5 fake project sessions of various sizes — enough to test all TUI flows (navigate, select, delete, cancel) without touching real Claude data.

### Simulate an update prompt

```bash
go run . --mock-update
```

Injects fake `v99.0.0` — triggers the update prompt on startup. Press `n` to skip into the list.

## Tests

```bash
Expand Down Expand Up @@ -116,9 +108,10 @@ demo/
*.tape — VHS scripts for demo GIFs

.github/workflows/
ci.yml — Go tests on every push / PR
ci.yml — Go tests (1.25 / 1.26 × Windows / macOS / Linux) on push / PR
release.yml — GoReleaser (binaries) + npm publish (wrapper)
demo.yml — regenerate demo GIFs on change
snyk.yml — dependency vulnerability scan (push / PR + weekly)
```

### Key data flow
Expand Down
17 changes: 6 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
[![Go version](https://img.shields.io/github/go-mod/go-version/ePlus-DEV/claude-cleaner)](go.mod)
[![Go Report Card](https://goreportcard.com/badge/github.com/ePlus-DEV/claude-cleaner)](https://goreportcard.com/report/github.com/ePlus-DEV/claude-cleaner)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Known Vulnerabilities](https://snyk.io/test/github/ePlus-DEV/claude-cleaner/badge.svg)](https://snyk.io/test/github/ePlus-DEV/claude-cleaner)

**Claude Cleaner** is an interactive terminal UI — built with [Bubble Tea](https://github.com/charmbracelet/bubbletea) and [Lip Gloss](https://github.com/charmbracelet/lipgloss) — that inspects Claude Code project session history, displays disk usage, and safely deletes only the sessions you select.

Runs on Windows, macOS, and Linux. No runtime required when using a pre-built binary.

![Full demo](demo/full.gif)

> See [SCREENSHOTS.md](SCREENSHOTS.md) for all scenario walkthroughs.

## Install

### Run without installing
Expand Down Expand Up @@ -62,6 +65,7 @@ claude-cleaner --version

```text
--claude-dir <path> Custom Claude config directory (default: ~/.claude)
--mock-update Simulate a newer version available (for testing the update flow)
-h, --help Show help
-v, --version Show version
```
Expand All @@ -84,7 +88,7 @@ claude-cleaner --version
## Features

- Reads project list from `~/.claude.json` — shows all projects Claude Code knows about, even those with no local session files.
- Displays **token usage** per project (from `lastTotal*` fields in `~/.claude.json`), formatted as K / M / B / T / P / E.
- Displays **token usage** per project — reads `lastTotal*` fields from `~/.claude.json` when available, otherwise aggregates `message.usage` from session `.jsonl` files. Formatted as K / M / B / T / P / E.
- Status column `●` (session files on disk) / `○` (config only, no local data).
- Windows path dedup — `d:/foo` and `D:/foo` treated as the same project; higher-token entry wins.
- Multi-select with `space`, select all with `a`, confirm with `enter`.
Expand Down Expand Up @@ -132,15 +136,6 @@ $env:CLAUDE_CONFIG_DIR = "D:\ClaudeData"
claude-cleaner
```

## Demos

| Scenario | Preview |
| --- | --- |
| `--help` | ![Help](demo/help.gif) |
| Delete a session | ![Full flow](demo/full.gif) |
| Cancel confirmation | ![Cancel](demo/cancel.gif) |
| In-place update | ![Update](demo/update.gif) |

## Troubleshooting

**Claude directory not found** — Run Claude Code at least once so the directory is created, or point to the correct path:
Expand All @@ -166,7 +161,7 @@ go build -o claude-cleaner.exe .

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, build, test, and release instructions.
See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, build, test, and release instructions. For internal data flow diagrams see [ARCHITECTURE.md](ARCHITECTURE.md).

## License

Expand Down
15 changes: 15 additions & 0 deletions SCREENSHOTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Screenshots & Demos

## Quick look

![Full demo](demo/full.gif)

## Scenario walkthroughs

| Scenario | Preview |
| --- | --- |
| `--help` | ![Help](demo/help.gif) |
| Delete a session | ![Full flow](demo/full.gif) |
| Cancel confirmation | ![Cancel](demo/cancel.gif) |
| In-place update | ![Update](demo/update.gif) |
| Search, sort, filter, category | ![Features](demo/full.gif) |
15 changes: 9 additions & 6 deletions demo/cancel.tape
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,31 @@ Set Framerate 12
Set Margin 0
Set PlaybackSpeed 1

Env COLORTERM truecolor
Env TERM xterm-256color

Type `PATH="$PWD/demo/mock-bin:$PATH" ./claude-cleaner --claude-dir /tmp/claude-demo`
Enter
Sleep 3s
Sleep 1500ms

# Skip update prompt if present (n = skip; harmless in list state)
Type "n"
Sleep 500ms
Sleep 200ms

# Select two items
Space
Down
Sleep 300ms
Sleep 150ms
Space
Sleep 500ms
Sleep 250ms

# Proceed to confirm screen
Enter
Sleep 800ms
Sleep 400ms

# Default is No (safe default) — press Enter to cancel back to list
Enter
Sleep 500ms
Sleep 250ms

# Quit
Type "q"
Loading
Loading