CLI tool to search and resume Claude Code conversations using a bubbletea TUI.
go build
go test -v -cover- Target: 60%+ statement coverage
- Current: ~69%
- All new features must include tests
- Break logic into testable functions when possible
- Refactor for testability (e.g., use variables instead of functions for dependency injection)
./ccs # search recent (60 days, <1GB files)
./ccs <query> # search with initial query
./ccs --max-age=7 # last 7 days only
./ccs --all # include everything
./ccs -- --plan # pass flags to claude-
Update version in
main.go:const version = "X.Y.Z"
-
Commit changes:
git add -A && git commit -m "feat/fix: description"
-
Push and tag:
git push git tag vX.Y.Z git push origin vX.Y.Z
-
CI will run tests, then release via GoReleaser and update Homebrew tap
- Patch (0.0.X): Bug fixes, minor tweaks
- Minor (0.X.0): New features, backwards compatible
- Major (X.0.0): Breaking changes
main.go- Single file containing all logicmain_test.go- Unit tests.goreleaser.yaml- Release configuration.github/workflows/test.yaml- CI test workflow (reusable).github/workflows/release.yaml- Release workflow (calls test.yaml)
github.com/charmbracelet/bubbletea- TUI frameworkgithub.com/charmbracelet/bubbles/textinput- Text input componentgithub.com/charmbracelet/lipgloss- Styling
Conversation- Parsed conversation with messages, timestamps, cwdMessage- Single message (role, text, timestamp)listItem- Display item with conversation and search textmodel- Bubbletea application state (includes delete confirmation state)
getConversations(cutoff, maxSize)- Loads conversations from~/.claude/projects/with filtersparseConversationFile(path, cutoff, maxSize)- Parses JSONL files, skips by mtime/sizebuildItems()- Creates list items with searchable textinitialModel()- Sets up bubbletea TUIUpdate()- Handles keyboard/mouse input, including delete confirmationView()- Renders the TUI with delete confirmation promptrenderPreview()- Renders conversation preview with highlightsformatListItem()- Formats a single list rowdeleteConversation()- Removes conversation file and updates UI stategetTopic()- Extracts first user message as topic
ccs · claude code search Resume:Enter Delete:Ctrl+D Scroll:Ctrl+J/K Exit:Esc
> type to search... (N/total)
DATE PROJECT TOPIC MSGS HITS
────────────────────────────────────────────────────────────────────────────
2024-01-08 15:04 project-name First user message 42 3
> 2024-01-08 14:30 selected This one is selected 28 1
────────────────────────────────────────────────────────────────────────────
Project: /path/to/project
Session: abc123...
2024-01-08 12:00 User:
message text here...
2024-01-08 12:01 Claude:
response text here...
- Use conventional commits (feat:, fix:, docs:, etc.)
- Run tests before releasing
- Keep it simple - single file is fine for this project