Skip to content

echochamber/chaimber-cliutils

Repository files navigation

chaimber-cliutils

Standalone CLI tools for Claude Code: session log search, worktree management, and worktree leasing.

claudegrep

Search your Claude Code conversation logs (~/.claude/projects/**/*.jsonl) with rich, session-grouped output — or plain, parse-friendly output for agents and pipes. Built for the real job: find which session something happened in and go back to it.

claudegrep "inngest"                 # search conversation text (user + assistant)
claudegrep -u "bulk price"           # user messages only
claudegrep -a "auth flow"            # assistant/agent messages only
claudegrep -p manapool "auth"        # filter to a project (dir-name substring)
claudegrep -m 5 "TODO"               # cap to 5 results (-n is an alias)
claudegrep --all-content "redactSecrets"   # also search tool calls + tool output
claudegrep --last "error"            # only the most recent session
claudegrep --session <id> "deploy"   # one session
claudegrep --days 7 "incident"       # only the last 7 days
claudegrep                           # no pattern → recent-sessions dashboard
claudegrep --list-projects           # list projects

Every result carries a claude --resume <id> handle and the file path, so a search is one copy-paste away from re-opening the session.

Output modes (human vs agent)

claudegrep auto-detects how to render:

  • rich — colorized, session-grouped boxes. Default on a terminal (TTY).
  • plain — readable, ANSI-free, session-grouped, token-efficient. Default when piped or run by an agent (non-TTY).

Override the auto-detection with --rich / --plain, or set CLAUDEGREP_MODE=rich|plain. Structured modes are explicit:

claudegrep --json "x"     # JSON array (for scripts/agents)
claudegrep --jsonl "x"    # JSON lines
claudegrep --grep "x"     # path:line:text (editor / fzf integration)
claudegrep --count "x"    # match counts per project

NO_COLOR (or --no-color) disables color; color is also auto-disabled off a TTY.

Matching

Smart-case by default (case-insensitive unless your pattern has an uppercase letter). -s forces case-sensitive, -i forces insensitive, -F treats the pattern as a literal string, -w matches whole words. Patterns are regex by default and one engine (Python re) decides matches and highlighting, so what lights up is exactly what matched.

By default the search surface is conversation prose (user + assistant text). Most of a transcript is tool calls and tool output; pass --all-content to search those too (and --include-subagents to include subagent transcripts). If a term is found only in tool content, the no-match message says so.

Performance

Sub-second on a ~1 GB corpus. rg narrows candidate files; matches are read straight from rg's output (no re-reading transcripts); only the handful of displayed sessions are fully parsed to compute the depth index and time span. Very common patterns are bounded by recency-ordered early-stop. rg is optional — without it, claudegrep falls back to a pure-Python scan.

Dependencies: rg (ripgrep) recommended; Python 3.10+ (stdlib only).

Run the tests

pytest claudegrep/test_claudegrep.py

wtutils

Git worktree management functions. Creates worktrees as sibling directories with automatic setup:

  • Symlinks .env, .claude/settings.local.json, etc. from the main worktree
  • Creates beads redirects for shared issue tracking
  • Links Claude Code project directories for shared session history
  • Runs post-create hooks (e.g. pnpm install)
wt-add feature-branch          # fetch base, create new worktree + branch
wt-add feature-branch dev      # branch from specific base
wt-open existing-branch        # worktree for existing branch
wt-cd feature-branch           # cd to worktree
wt-go feature-branch           # cd or create if missing
wt-list                        # list all worktrees
wt-remove feature-branch       # remove worktree
wt-prune                       # bulk-remove worktrees stale > 7d
wt-prune --merged              # bulk-remove worktrees whose PR is merged (gh)
wt-prune --dry-run             # preview; add --yes to skip prompt, --force for dirty
wtutils-init                   # interactive setup (requires gum)

wt-add fetches the base branch from origin before creating, so the new branch starts from current upstream tip (non-fatal if offline). wt-prune --merged requires gh and uses the base branch from chamber.config (or origin/HEAD) to filter PRs — squash-merge friendly.

Per-project configuration via .claude/chamber.config (JSON). Run wtutils-init to set up interactively.

wt-tenancy

A pooled "lease" layer on top of worktrees. Where wtutils creates one worktree per branch, wt-tenancy manages a fixed pool of generic slots ({reponame}_tenant_N) that Claude Code sessions claim on demand, release after merge, and reuse later. State lives in ~/.claude/worktree-tenancy.json (flock-guarded for concurrent hooks).

wt-tenancy list                       # show all leases + status
wt-tenancy claim PATH BRANCH          # claim a slot for a branch
wt-tenancy release PATH               # release a lease (--force if dirty)
wt-tenancy adopt PATH                 # bring an existing worktree into the pool
wt-tenancy stale --days N             # list leases idle longer than N days
wt-tenancy gc                         # reap leases whose PR is merged (needs gh)

Two SessionStart/SessionEnd hooks (installed into ~/.claude/hooks/) link the active session to its lease and refresh last_session_at. The installer prints the settings.json hook block to merge, plus optional launchd templates for the background gc poller (every 30m) and a daily stale-lease notifier.

This is the engine behind the worktree-tenancy skill — see that skill for the verbs agents use. It coexists with plain branch-named worktrees; tenancy is opt-in.

Run the tests:

bash wt-tenancy/test-wt-tenancy.sh

Install

Standalone

git clone https://github.com/echochamber/chaimber-cliutils.git
cd chaimber-cliutils
./install.sh

This symlinks tools into ~/.claude/scripts/ (and the wt-tenancy hooks into ~/.claude/hooks/, printing the settings.json block to register them). Ensure the scripts directory is on your PATH:

export PATH="$HOME/.claude/scripts:$PATH"

Source wtutils in your shell profile:

[ -f "$HOME/.claude/scripts/wtutils.sh" ] && source "$HOME/.claude/scripts/wtutils.sh"

As a submodule

git submodule add https://github.com/echochamber/chaimber-cliutils.git dev/cliutils
dev/cliutils/install.sh

Options

./install.sh              # install (updates existing symlinks)
./install.sh --dry-run    # show what would happen
./install.sh --force      # overwrite existing files (not just symlinks)

About

Standalone CLI tools for Claude Code: worktree management and session log search

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages