A local-first timeline for every prompt you've sent to Claude Code, Codex CLI, and Gemini CLI.
Project description
LLMLinq
A local-first timeline for every prompt you've ever sent to Claude Code, Codex CLI, and Gemini CLI.
LLMLinq reads the prompt history that the three major AI coding CLIs
already keep on your machine and presents it as a beautiful, searchable,
live-updating timeline at http://127.0.0.1:8745.
- ๐ Three tabs โ Claude ยท Codex ยท Gemini, with live prompt counts
- ๐ฐ Timeline view โ day-grouped, newest first, with project context
- ๐ Search โ find any prompt you ever typed
- โก Live โ prompts appear in the timeline seconds after you type them
- ๐ Private by design โ read-only, binds to localhost, zero network egress, zero telemetry
Install
uv tool install llmlinq # or: pipx install llmlinq / pip install llmlinq
llmlinq # scan โ serve โ open http://127.0.0.1:8745
Or try it without installing anything:
uvx llmlinq
Only Python โฅ 3.11 is required โ the web UI ships prebuilt inside the package. The wheel can also be downloaded directly from the PyPI files page.
โ ๏ธ Running from a git clone (
uv run llmlinq) shows a "UI not built" page โ the UI is bundled into released packages, not the repository. Install from PyPI as above, or build the UI first (see Development).
Useful commands:
llmlinq --port 9000 --no-browser # custom port, stay in the terminal
llmlinq paths # doctor: what was detected, where, how many prompts
How it works
| Provider | Reads (read-only) |
|---|---|
| Claude Code | ~/.claude/history.jsonl (or session transcripts as fallback) |
| Codex CLI | ~/.codex/history.jsonl + per-session metadata for project names |
| Gemini CLI | ~/.gemini/tmp/<sha256(project)>/logs.json |
Gemini never stores project paths โ only a SHA-256 hash of them โ so AI Prompt Dock recovers project names by hashing paths it learned from Claude and Codex data and matching them against Gemini's directory names.
A filesystem watcher picks up new prompts as you type them into any of the three CLIs and pushes them to the timeline over Server-Sent Events.
Custom data locations are honored via CLAUDE_CONFIG_DIR and CODEX_HOME.
Project structure
llmlinq-app/
โโโ pyproject.toml # Package metadata, dependencies, tool config (ruff/mypy/pytest)
โโโ uv.lock # Locked dependency versions (reproducible installs)
โโโ Makefile # One-word workflows: make dev / test / lint / build
โโโ .github/workflows/ci.yml # CI: lint + typecheck + tests (Python 3.11โ3.13) + UI build
โโโ src/
โ โโโ llmlinq/ # โโ The Python package โโ
โ โโโ cli.py # Typer CLI entry point (`llmlinq` command)
โ โโโ server.py # FastAPI app factory + production server runner
โ โโโ api/ # HTTP API routes (Phase 2)
โ โโโ core/ # Models, prompt store, file watcher (Phase 1)
โ โโโ providers/ # Claude / Codex / Gemini history adapters (Phase 1)
โ โโโ web/static/ # Built SPA โ generated by `make build-ui`, gitignored,
โ # shipped inside the wheel
โโโ frontend/ # โโ The React app โโ
โ โโโ vite.config.ts # Builds into src/llmlinq/web/static/; dev proxy โ :8745
โ โโโ src/
โ โโโ App.tsx # Root component
โ โโโ styles/index.css # Tailwind CSS v4 entry (sky theme)
โโโ tests/ # pytest suite (synthetic CLI-data fixtures in Phase 1)
The one unusual thing worth knowing: the frontend builds into the Python
package. vite build outputs to src/llmlinq/web/static/, and the
wheel includes that directory (see [tool.hatch.build] in pyproject.toml).
That is why end users need only Python โ never Node.
Local development
Prerequisites: uv and Node.js โฅ 22.
git clone <repo-url> && cd llmlinq-app
make install # uv sync (creates ./.venv + installs Python deps) + npm install
make dev # backend on :8745 + frontend on :5173, hot reload on both
Open http://localhost:5173 during development โ the Vite dev server
proxies /api and /healthz to the FastAPI backend on :8745.
All Python tooling runs inside the project virtualenv at ./.venv
(created by uv sync). Use uv run <cmd> โ or activate it with
source .venv/bin/activate if you prefer.
Run the halves separately when needed:
make dev-api # FastAPI only โ uv run uvicorn --factory llmlinq.server:create_app --reload --port 8745
make dev-ui # Vite only โ cd frontend && npm run dev
To test the production setup (FastAPI serving the built SPA, as end users get it):
make build-ui # build the SPA into the package
uv run llmlinq # serve everything from :8745
Other useful targets:
make test # pytest
make build # build the SPA, then the wheel (dist/llmlinq-*.whl, UI bundled)
make clean # remove build artifacts and caches
make help # list all targets
Linting & formatting
make lint # check everything (what CI runs)
make fmt # auto-fix + format Python code
make lint runs, in order:
| Tool | Command | Checks |
|---|---|---|
| Ruff (lint) | uv run ruff check src tests |
Python lint rules (E,F,W,I,UP,B,SIM,C4,RUF) |
| Ruff (format) | uv run ruff format --check src tests |
Python formatting |
| mypy | uv run mypy src |
Static types, strict = true |
| TypeScript | cd frontend && npm run typecheck |
Frontend types (tsc, strict) |
Configuration lives in pyproject.toml ([tool.ruff], [tool.mypy]) and
frontend/tsconfig.json. CI (.github/workflows/ci.yml) runs the same
checks plus the test suite on Python 3.11, 3.12, and 3.13 โ run
make lint test before pushing and you should match CI exactly.
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 llmlinq-0.1.0.tar.gz.
File metadata
- Download URL: llmlinq-0.1.0.tar.gz
- Upload date:
- Size: 178.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9239baa8d7453fc5e1b38aa7b2f622af29202b7144b2db99dc76cf8848f3e53a
|
|
| MD5 |
445ba7f6ea206bbfe62efa86e22cd0c5
|
|
| BLAKE2b-256 |
84b6bcbb54db42fc7bd7147ed7bb85aa01807cbc1b0bf23a99898a846aa640ff
|
Provenance
The following attestation bundles were made for llmlinq-0.1.0.tar.gz:
Publisher:
release.yml on infoinlet-com/llmlinq-app
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
llmlinq-0.1.0.tar.gz -
Subject digest:
9239baa8d7453fc5e1b38aa7b2f622af29202b7144b2db99dc76cf8848f3e53a - Sigstore transparency entry: 1739366794
- Sigstore integration time:
-
Permalink:
infoinlet-com/llmlinq-app@c6cff9a8cd76fffd3f67184d023afbc71f5ec701 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/infoinlet-com
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c6cff9a8cd76fffd3f67184d023afbc71f5ec701 -
Trigger Event:
push
-
Statement type:
File details
Details for the file llmlinq-0.1.0-py3-none-any.whl.
File metadata
- Download URL: llmlinq-0.1.0-py3-none-any.whl
- Upload date:
- Size: 118.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b986c83bb84685cca1fbf88b10de57ffd195b8665dcba8fe81ff505cf67bff83
|
|
| MD5 |
932ee4b12768dc96530fcde6dd4de22e
|
|
| BLAKE2b-256 |
13d236f010f65a75e889d5916e49bcdb82832f3cabe7805378914fb170064f81
|
Provenance
The following attestation bundles were made for llmlinq-0.1.0-py3-none-any.whl:
Publisher:
release.yml on infoinlet-com/llmlinq-app
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
llmlinq-0.1.0-py3-none-any.whl -
Subject digest:
b986c83bb84685cca1fbf88b10de57ffd195b8665dcba8fe81ff505cf67bff83 - Sigstore transparency entry: 1739366804
- Sigstore integration time:
-
Permalink:
infoinlet-com/llmlinq-app@c6cff9a8cd76fffd3f67184d023afbc71f5ec701 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/infoinlet-com
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c6cff9a8cd76fffd3f67184d023afbc71f5ec701 -
Trigger Event:
push
-
Statement type: