Multi-CLI AI coding session tracer and normalizer
Project description
QuickCall OpenTrace
Multi-CLI AI coding session tracer. Normalize, store, and browse sessions from Claude Code, Codex CLI, Gemini CLI, Cursor, and pi.dev — in one PostgreSQL database with a web UI.
|
Session Browser — Search, filter, and inspect messages |
Parallel Session View — Side-by-side comparison of related sessions |
Supported CLIs
| CLI | Data source | Notes |
|---|---|---|
| Claude Code | ~/.claude/projects/**/*.jsonl |
Full message + tool history |
| Codex CLI | ~/.codex/sessions/*/*/*/rollout-*.jsonl |
Token usage, tool calls |
| Gemini CLI | ~/.gemini/tmp/*/chats/session-*.json |
Shell commands, file edits |
| Cursor | ~/.cursor/projects/*/agent-transcripts/*.txt + state.vscdb |
Agent transcripts, composer data |
| pi.dev | ~/.pi/agent/sessions/**/*.jsonl |
Kimi model, thinking blocks |
Quick Start
Full experience (with web UI)
git clone https://github.com/quickcall-dev/opentrace.git
cd opentrace
docker compose up -d
open http://localhost:3000 # macOS
# xdg-open http://localhost:3000 # Linux
quickcall up is a convenience wrapper for docker compose up -d. Both require Docker.
Backend only (no UI)
pip install quickcall-opentrace
export QUICKCALL_OPENTRACE_DSN="postgresql://user:pass@localhost:5432/quickcall"
quickcall init # creates ~/.quickcall-opentrace/config.json
quickcall-server # ingest API on :19777
quickcall-daemon # file watcher + normalizer
The daemon watches local session directories and pushes normalized batches to the ingest server automatically.
Note: pip install gives you the Python backend only (server + daemon CLIs). The web frontend is available only via Docker Compose.
See Bring Your Own Postgres guide for full details — bring your own Postgres, multiple machines, background mode, troubleshooting.
Not sure what's wrong? Run quickcall doctor — it checks Docker, Postgres, server, daemon, and session dirs, then prints next steps.
Architecture
Full architecture document: docs/architecture/README.md
flowchart LR
subgraph Host["Host Machine"]
A[Claude Code] --> D
B[Codex CLI] --> D
C1[Cursor] --> D
C2[pi.dev] --> D
C3[Gemini CLI] --> D
end
D["Daemon<br/>(file watcher + normalizer)"] -->|"HTTP batches"| S["Ingest Server<br/>(port 19777)"]
S -->|"COPY writes"| P[("PostgreSQL")]
P -->|"API queries"| F["Frontend<br/>(Next.js 15, port 3000)"]
style Host fill:#f5f5f5,stroke:#999
style D fill:#e3f2fd,stroke:#1976d2
style S fill:#fff3e0,stroke:#f57c00
style P fill:#e8f5e9,stroke:#388e3c
style F fill:#f3e5f5,stroke:#7b1fa2
- Daemon polls
~/.claude,~/.codex,~/.gemini,~/.cursor,~/.pifor new session files - Collector normalizes each CLI's format into
NormalizedMessage - Pusher batches messages to the ingest server over HTTP
- Server validates, deduplicates, and writes to PostgreSQL via
COPY - Frontend queries the API and renders sessions with sidebar gantt, messages, minimap
Installation
Docker (recommended)
git clone https://github.com/quickcall-dev/opentrace.git
cd opentrace
quickcall up
# Or directly: docker compose up -d
From source
uv sync --extra dev
uv run pytest
PyPI (backend only)
pip install quickcall-opentrace
This installs the quickcall-server and quickcall-daemon CLIs. For the full stack with the web UI, clone the repo and use quickcall up.
For running with your own PostgreSQL database (no Docker), see the Bring Your Own Postgres guide.
Configuration
All runtime environment variables use the QUICKCALL_OPENTRACE_ prefix.
| Variable | Used by | Default | Description |
|---|---|---|---|
QUICKCALL_OPENTRACE_DSN |
server | postgresql://quickcall:quickcall@db:5432/quickcall |
PostgreSQL connection string |
QUICKCALL_OPENTRACE_HOST |
server | 0.0.0.0 |
Server bind interface |
QUICKCALL_OPENTRACE_ADMIN_KEYS |
server | admin_dev |
Comma-separated admin API keys |
QUICKCALL_OPENTRACE_PUSH_KEYS |
server | push_dev |
Comma-separated ingest API keys |
QUICKCALL_OPENTRACE_INGEST_URL |
daemon | http://localhost:19777/ingest |
Daemon push endpoint |
QUICKCALL_OPENTRACE_API_KEY |
daemon | — | API key for daemon pushes |
See .env.example for a complete reference.
API Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /health |
— | Health check |
| POST | /ingest |
Push | Submit normalized messages |
| GET | /api/sessions |
Admin | List sessions with filters |
| GET | /api/messages |
Admin | Messages for a session |
| GET | /api/stats |
Admin | Aggregate stats |
| GET | /api/sync |
Admin | File sync state |
Development
Prerequisites
- uv — Python package manager
- Docker — for Postgres and optional full-stack
- Node.js 20+ — for frontend development
1. Clone and install
git clone https://github.com/quickcall-dev/opentrace.git
cd opentrace
uv sync --extra dev
2. Start PostgreSQL
# Using Docker (recommended)
docker compose up -d db
# Or use your own Postgres — create database "quickcall" and set DSN:
# export QUICKCALL_OPENTRACE_DSN=postgresql://user:pass@localhost:5432/quickcall
Schema is applied automatically on server startup (ensure_schema).
3. Run backend natively
Terminal 1 — Ingest server:
uv run python -m opentrace.server
# Server starts on http://localhost:19777
Terminal 2 — Daemon:
uv run python -m opentrace.daemon
# Watches ~/.claude, ~/.codex, ~/.gemini, ~/.cursor, ~/.pi
Or use the CLI wrapper:
uv run quickcall-daemon
4. Run frontend natively
cd frontend
npm install
npm run dev
# Opens on http://localhost:3000
The frontend proxies API calls to localhost:19777 in development.
5. Run tests
# All tests (requires local Postgres running)
uv run pytest
# Specific module
uv run pytest tests/daemon/
# With coverage
uv run pytest --cov=opentrace
6. Lint and format
uv run ruff check opentrace/ tests/
uv run ruff format opentrace/ tests/
7. Rebuild Docker after changes
# Backend changes (Python)
docker compose up -d --build server daemon
# Frontend changes (TypeScript/React)
docker compose up -d --build frontend
8. Pre-push validation
Run the e2e smoke tests before pushing to main:
# PyPI package path (BYOP)
./scripts/e2e-pypi-smoke-test.sh
# Docker Compose path (full stack)
./scripts/e2e-docker-smoke-test.sh
Both auto-clean on exit. They catch packaging and entry-point issues that unit tests miss.
9. Git hooks
The repo includes a pre-commit hook that enforces conventional commits:
git config core.hooksPath .githooks
Commits must include a Why: section with 2+ bullets.
10. Wipe and re-ingest
# Truncate DB and reset daemon state
PGPASSWORD=quickcall psql -h localhost -p 15433 -U quickcall -d quickcall -c \
"TRUNCATE TABLE tool_calls, tool_results, token_usage, messages, file_progress, sessions, schema_version RESTART IDENTITY CASCADE; INSERT INTO schema_version (version) VALUES (1);"
rm ~/.quickcall-opentrace/state.json ~/.quickcall-opentrace/backfilled_sessions.json 2>/dev/null
docker compose restart daemon
Adding a new CLI source
- Schema — Add transform in
opentrace/schemas/<source>/transform.py - Collector — Add
_collect_<source>inopentrace/daemon/collector.py - Tests — Add fixtures in
tests/fixtures/and tests intests/schemas/,tests/daemon/ - Watcher — Add glob pattern in
opentrace/daemon/config.pyif needed
License
Apache 2.0 — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quickcall_opentrace-1.2.0.tar.gz.
File metadata
- Download URL: quickcall_opentrace-1.2.0.tar.gz
- Upload date:
- Size: 1.6 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f519ad69466cdbd77eadd48f46e735066b26bddc1d79d590f2a83b6ff9d78d5
|
|
| MD5 |
2e159f78df85f7e0be3317d476ca6a6f
|
|
| BLAKE2b-256 |
064440adf9f646892c9758cff63695de6928f171964ab13fe6bd3c507caac33e
|
File details
Details for the file quickcall_opentrace-1.2.0-py3-none-any.whl.
File metadata
- Download URL: quickcall_opentrace-1.2.0-py3-none-any.whl
- Upload date:
- Size: 111.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
997551ca95ca30a3dac1a27d690a2da985e20cf7c61e311212a4acc070c31990
|
|
| MD5 |
c85de1052260bb08397c6b1d35708bbe
|
|
| BLAKE2b-256 |
5ba6d0a05df37fab10975ec5ed6f0c96c1720e7286dcc9f0b895467b58a5dbf9
|