Metadata-Version: 2.4
Name: claude-peek
Version: 0.1.0
Summary: Inspect and tail Claude Code session transcripts — list sessions, slice conversations, watch live.
Project-URL: Homepage, https://github.com/frapercan/claude-peek
Project-URL: Issues, https://github.com/frapercan/claude-peek/issues
Project-URL: Changelog, https://github.com/frapercan/claude-peek/blob/main/CHANGELOG.md
Author-email: Francisco Miguel Pérez Canales <frapercan1@gmail.com>
License: MIT
License-File: LICENSE
Keywords: claude,claude-code,cli,observability,transcript,tui
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development
Classifier: Topic :: Terminals
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Requires-Dist: rich>=13.7
Requires-Dist: typer>=0.12
Requires-Dist: watchfiles>=0.21
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pre-commit>=3.7; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# claude-peek

[![CI](https://github.com/frapercan/claude-peek/actions/workflows/ci.yml/badge.svg)](https://github.com/frapercan/claude-peek/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/claude-peek.svg)](https://pypi.org/project/claude-peek/)
[![Python](https://img.shields.io/pypi/pyversions/claude-peek.svg)](https://pypi.org/project/claude-peek/)
[![License](https://img.shields.io/github/license/frapercan/claude-peek.svg)](LICENSE)

Inspect and tail **Claude Code** session transcripts from the terminal. List every session, slice any conversation, and watch another window **live** as it works.

Claude Code persists every session to disk as a streaming JSONL file under `~/.claude/projects/<cwd>/<session-id>.jsonl`. `claude-peek` turns that raw stream into something a human can read, diff, and follow.

---

## Why

- **Two windows at once.** See what the other Claude is doing without switching terminals.
- **Reconstruct the arc.** Re-read a long session by user prompts only, strip tool noise, or tail the last 20 %.
- **Observability.** Track context token usage over a session, spot auto-compactions, audit what was asked.
- **Zero friction.** No MCP server, no DB, no cloud — just the files Claude already wrote.

---

## Install

```bash
pip install claude-peek
# or, from source:
git clone https://github.com/frapercan/claude-peek && cd claude-peek && pip install -e .
```

Python 3.10+. Works on Linux, macOS, and Windows.

---

## Quick start

```bash
# List the 25 most recent sessions with context size
claude-peek list

# Peek at a session by session-id prefix
claude-peek show 7cba6520

# Last 30 % of a session
claude-peek show 7cba6520 --percent 30

# Only the user prompts (strip tool calls and thinking)
claude-peek show 7cba6520 --prompts-only

# Follow another session in real time
claude-peek follow 7cba6520

# Token / context trajectory
claude-peek stats 7cba6520
```

---

## Commands

### `list`

```
claude-peek list [--limit N] [--cwd PATTERN] [--active] [--json]
```

Lists recent sessions with:
- age (human-readable)
- context size at last turn (`input + cache_read + cache_creation` tokens)
- working directory
- session id prefix
- last user prompt preview

Flags:
- `--active` — only sessions modified in the last 5 minutes (probably live).
- `--cwd Thesis` — substring match on the working directory.
- `--json` — machine-readable output for piping.

### `show`

```
claude-peek show <session> [--percent N | --tail N | --before-prompt K | --full]
                           [--prompts-only] [--no-thinking] [--no-tools]
                           [--format pretty|markdown|json]
```

Render a slice of a session:
- `--percent 30` — last 30 % of events.
- `--tail 50` — last 50 events.
- `--before-prompt 5` — everything up to and including the 5th user prompt.
- `--full` — entire transcript.

Filters:
- `--prompts-only` — only user prompts + assistant text, no tool calls.
- `--no-thinking` — hide `[thinking]` blocks.
- `--no-tools` — hide tool calls and tool results.

Output formats:
- `pretty` (default) — ANSI-coloured terminal output via `rich`.
- `markdown` — portable, copy-pasteable into docs.
- `json` — structured events, one per line.

### `follow`

```
claude-peek follow <session> [--from-start] [--prompts-only]
```

Tail the session live using filesystem notifications (`watchfiles`). Cheap — no polling spin. `Ctrl-C` to exit.

### `stats`

```
claude-peek stats <session> [--json]
```

Shows the context trajectory, prompt count, auto-compaction events, total output tokens and average response time.

### `search`

```
claude-peek search "regex" [--in-cwd PATTERN] [--limit N]
```

Grep across **all** sessions and print matching prompts with their session id, timestamp, and context size.

---

## Session identifiers

Anywhere a `<session>` is expected you can pass:

- An absolute path to the `.jsonl`.
- Just the session id (`7cba6520-cb8b-4bd2-b246-b1617433c4c5`).
- A **prefix** (`7cba6520`) — unambiguous prefixes resolve automatically.
- `-` to read from stdin (for pipelines).

---

## Output format

Every rendered event carries a timestamp, a direction, and the content:

```
00:40:25 ▶ user
    es optimo?
00:40:33 ◀ claude
    [thinking]
00:40:34 ◀ claude
    [→ Read] {"file_path": ".../go_prediction.py"}
00:40:34 ▶ user
    [← tool_result] 1  from __future__ import annotations...
```

With `--format markdown`:

```markdown
### 00:40:25 — user

es optimo?

### 00:40:33 — claude

_[thinking]_

### 00:40:34 — claude (tool use)

**Read** `{"file_path": ".../go_prediction.py"}`
```

---

## Performance

- **Streaming parser.** Large JSONLs (100 MB+) are read line-by-line — memory footprint is O(1) in file size for most operations.
- **Indexed discovery.** `list` reads only the metadata needed to rank sessions and never loads message bodies it doesn't need to display.
- **`follow` uses filesystem notifications** (via `watchfiles` → inotify / FSEvents / ReadDirectoryChangesW), not a sleep loop.

---

## Configuration

An optional config at `$XDG_CONFIG_HOME/claude-peek/config.toml` (defaults to `~/.config/claude-peek/config.toml`) can set:

```toml
# Where Claude Code stores sessions. Normally auto-detected.
projects_dir = "~/.claude/projects"

[list]
limit = 25
show_cwd = true

[show]
default_slice = "tail:50"
hide_thinking = false
```

Any flag on the CLI overrides the config.

---

## Development

```bash
git clone https://github.com/frapercan/claude-peek
cd claude-peek
pip install -e ".[dev]"
pre-commit install
pytest
```

Quality gates:

```bash
ruff check .
ruff format --check .
mypy src
pytest --cov
```

---

## License

MIT © 2026 Francisco Miguel Pérez Canales
