diff options
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..4252071 --- /dev/null +++ b/README.md @@ -0,0 +1,203 @@ +# claude-sesiones + +Browse every [Claude Code](https://claude.com/claude-code) conversation stored on +your machine — as a table in your terminal, or as a single self-contained HTML +page you open with a double click. + +**[Español](README.es.md)** · English · No dependencies, standard library only. + +> **The CLI, its output and its help text are in Spanish.** Only this README is +> translated. The command reads local files and never sends anything anywhere. + +``` + # SESIÓN RUTA FECHA CUÁNDO MSG DUR ID + 1 | Migrar el pool de conexiones a … /home/ana/api 16 ago hoy 4 9m 5d10f1ee + 2 | Timeouts intermitentes en el he… /home/ana/api 16 ago hoy 2 3m 0f60f37a + 3 | Reescribir el buscador con Fuse… /home/ana/web 15 ago ayer 7 18m b69c1fc2 + 4 | por qué tarda tanto npm ci /home/ana/web 13 ago hace 3d 1 <1m d4d2a5be + 5 | sesión abierta sin mens… [vacía] /home/ana/infra 08 ago hace 1sem — <1m e0a4300e + +5 sesiones · 3 proyectos · -s <nº> para leer una +``` + +## ⚠️ Your transcripts are private + +`--json` and `--html` write out **the full text of your conversations**: prompts, +answers, file paths, branch names. The generated `sesiones.html` is a complete, +readable copy of everything you ever typed into Claude Code. + +Do not commit it, do not upload it, do not paste it into a bug report. The +repository's `.gitignore` already excludes `sesiones.html` and `data.json`, but +the file itself is yours to look after. + +## Install + +Requires Python 3.9 or newer. Nothing else. + +```bash +pipx install git+https://github.com/ElvisClaros/claude-sesiones +``` + +Or with pip, or straight from a clone: + +```bash +pip install git+https://github.com/ElvisClaros/claude-sesiones + +git clone https://github.com/ElvisClaros/claude-sesiones && cd claude-sesiones +python3 -m claude_sesiones # no install needed +``` + +## Usage + +```bash +claude-sesiones # table of every session +claude-sesiones docker # filter by title, path or branch +claude-sesiones -s 3 # read conversation #3 from the table +claude-sesiones -s 5d10f1ee # same, by UUID prefix +claude-sesiones -g "port already" # search inside the conversations +claude-sesiones -r 3 # print the command that resumes it +eval "$(claude-sesiones -r 3)" # …or resume it right away +claude-sesiones --html --open # build sesiones.html and open it +``` + +The number is the row's position **in the table you are looking at**, so if you +filtered, repeat the filter to read that row: + +```bash +claude-sesiones docker # shows 3 results +claude-sesiones docker -s 2 # reads the 2nd of those three +``` + +### Options + +| Flag | What it does | +| --- | --- | +| `-s`, `--show REF` | Print a conversation (table index or UUID prefix). | +| `-r`, `--resume REF` | Print `cd <project> && claude --resume <uuid>`. | +| `-g`, `--grep TEXT` | Keep sessions whose transcript contains `TEXT`. | +| `-p`, `--project PATH` | Keep sessions whose project path contains `PATH`. | +| `-n`, `--limit N` | Only the N most recent. | +| `-E`, `--hide-empty` | Hide sessions with no messages. | +| `--no-tools` | Hide tool calls when printing a conversation. | +| `--no-pager` | Do not pipe the conversation through `$PAGER`. | +| `--no-color` | Plain output (`NO_COLOR` is honoured too). | +| `--json` | Dump every session as JSON on stdout. | +| `--html [FILE]` | Build the standalone page (default `sesiones.html`). | +| `--template FILE` | Use your own template for `--html`. | +| `--open` | Open whatever `--html` produced in your browser. | +| `--no-cache` | Ignore the cache and re-parse everything. | + +### Deleting sessions + +Irreversible, and it asks first unless you pass `-y`: + +```bash +claude-sesiones --delete-empty --dry-run # what it would delete +claude-sesiones --delete-empty # delete the empty ones +claude-sesiones -D 101 -D e0a4300e # delete specific sessions +claude-sesiones -p /tmp --delete-empty # only the empty ones of that project +``` + +It warns you about any file written in the last five minutes: that is very +likely a session Claude Code still has open, and it will write it back on exit. + +## The HTML page + +`claude-sesiones --html` produces one file with the data embedded inside it. No +server, no network, no build step — copy it to another machine and it still +works. + +- Search by title, path, branch or UUID, and optionally inside the transcripts, + with the matching snippet shown under the row. +- Filter by project, sort by any column, hide empty sessions. +- Click a row to read the conversation in a side panel, with code fences, + headings and one line per tool call. +- Copy the `cd … && claude --resume …` command for any session. +- Light and dark themes, with a toggle that remembers your choice. +- Each session gets its own URL fragment, so `sesiones.html#5d10f1ee-…` opens + that conversation directly. +- Keyboard: `/` or `Ctrl`+`K` focuses the search box, `Esc` clears it or closes + the reader. + +Dates are relative to **when the data was read**, not to your clock, so "today" +keeps meaning what it meant when you generated the page. + +## How it works + +Claude Code writes one JSON Lines file per conversation: + +``` +~/.claude/projects/<url-encoded-project-path>/<uuid>.jsonl +``` + +(`CLAUDE_CONFIG_DIR` is honoured if you moved that directory.) + +Every line is an event. `claude-sesiones` walks them and keeps the conversation +itself — your messages, Claude's replies, and a one-line summary per tool call +such as `Bash: git status`. It deliberately **drops tool results**, which are +about 95% of the bytes on disk and almost none of the meaning. + +A few details worth knowing: + +- **Titles.** Claude generates one during the session (`ai-title` events); the + most recent wins. Without one, the first thing you typed is used instead — + which is visible, because it starts in lowercase or reads like a loose + question. +- **Empty sessions** were opened but never received a message: a cancelled + `/resume`, a `/login`. +- **Non-interactive** sessions are `claude -p` with something piped into stdin — + typically a `git diff` to write a commit message. They are detected as a + single very long message with no back and forth. +- **Inferred paths.** A cancelled `/resume` never records a `cwd`, and the + directory name cannot be reversed reliably (both `/` and `.` encode as `-`), + so the path is borrowed from another session of the same project and flagged. +- **Sidechains** (subagent transcripts) are skipped. +- **Cache.** Parsed sessions are cached in + `$XDG_CACHE_HOME/claude-sesiones/cache.json`, keyed by size and mtime. It is + only an optimisation: if it is missing, stale or corrupt, everything is + re-parsed. `--no-cache` skips it entirely. + +### JSON schema + +`--json` prints an array, most recently active first. Keys are one letter +because the same records are embedded in the HTML, where the cost is paid once +per session: + +| Key | Meaning | +| --- | --- | +| `id` | Session UUID (the file name). | +| `p` | Project path (`cwd`). | +| `b` | Git branch. | +| `t` | Title. | +| `ai` | `true` if Claude generated the title. | +| `n` | `true` if it looks like a non-interactive `claude -p`. | +| `e` | `true` if the session has no messages. | +| `i` | `true` if `p` was inferred from a sibling session. | +| `f` / `l` | First and last event timestamps (ISO 8601). | +| `d` | Duration in minutes. | +| `u` / `a` | Message counts, yours / Claude's. | +| `k` | File size in KB. | +| `v` | Claude Code version. | +| `c` | Transcript: `[{"r": "u"|"a"|"t", "x": text}]`. | + +## Development + +```bash +git clone https://github.com/ElvisClaros/claude-sesiones && cd claude-sesiones +python3 -m unittest discover -s tests -t . +``` + +The tests build fake `.jsonl` trees in a temporary directory and never touch +`~/.claude`. There is nothing to install: no test runner, no dependencies. + +| Module | Responsibility | +| --- | --- | +| `claude_sesiones/sessions.py` | Parsing the `.jsonl` files, the cache, filters. | +| `claude_sesiones/terminal.py` | ANSI colours, the table, printing a conversation. | +| `claude_sesiones/webpage.py` | Embedding the data into the template. | +| `claude_sesiones/cli.py` | Argument parsing and the commands. | +| `claude_sesiones/template.html` | The page: markup, styles and the browser-side code. | + +## License + +[Apache-2.0](LICENSE). |