llmlinq 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- llmlinq-0.1.0/.claude/skills/local-app-monitor/SKILL.md +17 -0
- llmlinq-0.1.0/.github/workflows/ci.yml +40 -0
- llmlinq-0.1.0/.github/workflows/release.yml +51 -0
- llmlinq-0.1.0/.gitignore +34 -0
- llmlinq-0.1.0/.python-version +1 -0
- llmlinq-0.1.0/CHANGELOG.md +27 -0
- llmlinq-0.1.0/LICENSE +21 -0
- llmlinq-0.1.0/Makefile +42 -0
- llmlinq-0.1.0/PKG-INFO +183 -0
- llmlinq-0.1.0/README.md +155 -0
- llmlinq-0.1.0/frontend/index.html +14 -0
- llmlinq-0.1.0/frontend/package-lock.json +1418 -0
- llmlinq-0.1.0/frontend/package.json +29 -0
- llmlinq-0.1.0/frontend/public/favicon.svg +35 -0
- llmlinq-0.1.0/frontend/src/App.tsx +113 -0
- llmlinq-0.1.0/frontend/src/api/client.ts +116 -0
- llmlinq-0.1.0/frontend/src/api/types.ts +34 -0
- llmlinq-0.1.0/frontend/src/components/AppIcon.tsx +45 -0
- llmlinq-0.1.0/frontend/src/components/CloudSyncPanel.tsx +204 -0
- llmlinq-0.1.0/frontend/src/components/EmptyState.tsx +31 -0
- llmlinq-0.1.0/frontend/src/components/LiveBadge.tsx +15 -0
- llmlinq-0.1.0/frontend/src/components/PromptCard.tsx +108 -0
- llmlinq-0.1.0/frontend/src/components/ProviderTabs.tsx +51 -0
- llmlinq-0.1.0/frontend/src/components/RevisePanel.tsx +232 -0
- llmlinq-0.1.0/frontend/src/components/SearchBar.tsx +29 -0
- llmlinq-0.1.0/frontend/src/components/Timeline.tsx +77 -0
- llmlinq-0.1.0/frontend/src/hooks/usePrompts.ts +32 -0
- llmlinq-0.1.0/frontend/src/main.tsx +19 -0
- llmlinq-0.1.0/frontend/src/styles/index.css +1 -0
- llmlinq-0.1.0/frontend/tsconfig.json +21 -0
- llmlinq-0.1.0/frontend/vite.config.ts +19 -0
- llmlinq-0.1.0/pyproject.toml +80 -0
- llmlinq-0.1.0/skill/monitoring.md +146 -0
- llmlinq-0.1.0/src/llmlinq/__init__.py +8 -0
- llmlinq-0.1.0/src/llmlinq/__main__.py +6 -0
- llmlinq-0.1.0/src/llmlinq/api/__init__.py +1 -0
- llmlinq-0.1.0/src/llmlinq/api/routes.py +159 -0
- llmlinq-0.1.0/src/llmlinq/cli.py +82 -0
- llmlinq-0.1.0/src/llmlinq/core/__init__.py +1 -0
- llmlinq-0.1.0/src/llmlinq/core/cloud.py +165 -0
- llmlinq-0.1.0/src/llmlinq/core/config.py +23 -0
- llmlinq-0.1.0/src/llmlinq/core/events.py +42 -0
- llmlinq-0.1.0/src/llmlinq/core/models.py +95 -0
- llmlinq-0.1.0/src/llmlinq/core/paths.py +21 -0
- llmlinq-0.1.0/src/llmlinq/core/reviser.py +48 -0
- llmlinq-0.1.0/src/llmlinq/core/revisions.py +66 -0
- llmlinq-0.1.0/src/llmlinq/core/store.py +114 -0
- llmlinq-0.1.0/src/llmlinq/core/watcher.py +67 -0
- llmlinq-0.1.0/src/llmlinq/providers/__init__.py +34 -0
- llmlinq-0.1.0/src/llmlinq/providers/base.py +74 -0
- llmlinq-0.1.0/src/llmlinq/providers/claude.py +143 -0
- llmlinq-0.1.0/src/llmlinq/providers/codex.py +128 -0
- llmlinq-0.1.0/src/llmlinq/providers/gemini.py +106 -0
- llmlinq-0.1.0/src/llmlinq/server.py +140 -0
- llmlinq-0.1.0/src/llmlinq/web/static/assets/index-CJvy84g1.js +10 -0
- llmlinq-0.1.0/src/llmlinq/web/static/assets/index-Dba8tGzm.css +2 -0
- llmlinq-0.1.0/src/llmlinq/web/static/favicon.svg +35 -0
- llmlinq-0.1.0/src/llmlinq/web/static/index.html +15 -0
- llmlinq-0.1.0/tests/__init__.py +0 -0
- llmlinq-0.1.0/tests/conftest.py +213 -0
- llmlinq-0.1.0/tests/test_api.py +183 -0
- llmlinq-0.1.0/tests/test_cli.py +20 -0
- llmlinq-0.1.0/tests/test_cloud.py +201 -0
- llmlinq-0.1.0/tests/test_providers.py +93 -0
- llmlinq-0.1.0/tests/test_revisions.py +41 -0
- llmlinq-0.1.0/tests/test_store.py +92 -0
- llmlinq-0.1.0/tests/test_watcher.py +41 -0
- llmlinq-0.1.0/uv.lock +690 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: local-app-monitor
|
|
3
|
+
description: Monitor the locally running llmlinq app — probe the API endpoints, scan logs, detect errors/problems, and file deduplicated bug issues in infoinlet-com/llmlinq-app. Use when asked to monitor the local app, check app health, or via /local-app-monitor. One invocation is one pass; combine with /loop for continuous monitoring.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Execute one monitoring pass by following the complete procedure in
|
|
7
|
+
`skill/monitoring.md` at the repository root (read that file first — it
|
|
8
|
+
defines the checks, severity rules, log sources, issue dedupe/cap policy,
|
|
9
|
+
and the required summary format).
|
|
10
|
+
|
|
11
|
+
Hard rules, even if the procedure file is unavailable:
|
|
12
|
+
- Read-only checks only; never call paid endpoints (`/api/v1/revise`) unless
|
|
13
|
+
the user explicitly asked for a deep pass.
|
|
14
|
+
- App not running = report in chat, never a GitHub issue.
|
|
15
|
+
- Before creating any issue, search open issues for a matching
|
|
16
|
+
`[monitor] …` title; cap new issues at 3 per pass.
|
|
17
|
+
- Always end with a pass/warn/fail summary table in chat.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
backend:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: astral-sh/setup-uv@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: ${{ matrix.python-version }}
|
|
19
|
+
enable-cache: true
|
|
20
|
+
- run: uv sync --frozen
|
|
21
|
+
- run: uv run ruff check src tests
|
|
22
|
+
- run: uv run ruff format --check src tests
|
|
23
|
+
- run: uv run mypy src
|
|
24
|
+
- run: uv run pytest
|
|
25
|
+
|
|
26
|
+
frontend:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
defaults:
|
|
29
|
+
run:
|
|
30
|
+
working-directory: frontend
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v4
|
|
33
|
+
- uses: actions/setup-node@v4
|
|
34
|
+
with:
|
|
35
|
+
node-version: 22
|
|
36
|
+
cache: npm
|
|
37
|
+
cache-dependency-path: frontend/package-lock.json
|
|
38
|
+
- run: npm ci
|
|
39
|
+
- run: npm run typecheck
|
|
40
|
+
- run: npm run build
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Tag-driven release: pushing a tag like v0.1.0 builds the UI, packs it into
|
|
4
|
+
# the wheel, and publishes to PyPI via trusted publishing (no API tokens).
|
|
5
|
+
#
|
|
6
|
+
# One-time setup: add a trusted publisher for the `llmlinq` project at
|
|
7
|
+
# https://pypi.org/manage/account/publishing/ with:
|
|
8
|
+
# owner: infoinlet-com · repo: llmlinq-app
|
|
9
|
+
# workflow: release.yml · environment: pypi
|
|
10
|
+
|
|
11
|
+
on:
|
|
12
|
+
push:
|
|
13
|
+
tags: ["v*"]
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
build:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
- uses: actions/setup-node@v4
|
|
21
|
+
with:
|
|
22
|
+
node-version: 22
|
|
23
|
+
cache: npm
|
|
24
|
+
cache-dependency-path: frontend/package-lock.json
|
|
25
|
+
- name: Build the web UI into the package
|
|
26
|
+
working-directory: frontend
|
|
27
|
+
run: |
|
|
28
|
+
npm ci
|
|
29
|
+
npm run build
|
|
30
|
+
- uses: astral-sh/setup-uv@v5
|
|
31
|
+
- name: Build sdist and wheel (UI bundled)
|
|
32
|
+
run: uv build
|
|
33
|
+
- name: Verify the wheel contains the UI
|
|
34
|
+
run: unzip -l dist/*.whl | grep -q "llmlinq/web/static/index.html"
|
|
35
|
+
- uses: actions/upload-artifact@v4
|
|
36
|
+
with:
|
|
37
|
+
name: dist
|
|
38
|
+
path: dist/
|
|
39
|
+
|
|
40
|
+
publish:
|
|
41
|
+
needs: build
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
environment: pypi
|
|
44
|
+
permissions:
|
|
45
|
+
id-token: write # trusted publishing
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/download-artifact@v4
|
|
48
|
+
with:
|
|
49
|
+
name: dist
|
|
50
|
+
path: dist/
|
|
51
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
llmlinq-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
.venv/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
*.egg-info/
|
|
8
|
+
.pytest_cache/
|
|
9
|
+
.mypy_cache/
|
|
10
|
+
.ruff_cache/
|
|
11
|
+
.coverage
|
|
12
|
+
htmlcov/
|
|
13
|
+
|
|
14
|
+
# Node
|
|
15
|
+
frontend/node_modules/
|
|
16
|
+
npm-debug.log*
|
|
17
|
+
*.tsbuildinfo
|
|
18
|
+
|
|
19
|
+
# Built frontend (generated by `make build-ui`, shipped inside the wheel)
|
|
20
|
+
src/aipromptdock/web/static/
|
|
21
|
+
|
|
22
|
+
# OS / editor
|
|
23
|
+
.DS_Store
|
|
24
|
+
.idea/
|
|
25
|
+
.vscode/
|
|
26
|
+
|
|
27
|
+
# Local AI-assistant artifacts and working notes (but ship shared skills)
|
|
28
|
+
.claude/*
|
|
29
|
+
!.claude/skills/
|
|
30
|
+
.context/
|
|
31
|
+
|
|
32
|
+
# Env
|
|
33
|
+
.env
|
|
34
|
+
.env.*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.0] - 2026-06-06
|
|
11
|
+
|
|
12
|
+
First release under the **LLMLinq** name. LLMLinq links prompts, contexts,
|
|
13
|
+
tools, validators, and LLMs — starting with everything previously published
|
|
14
|
+
as `aipromptdock` (0.1.0–0.2.4):
|
|
15
|
+
|
|
16
|
+
- Local timeline for Claude Code, Codex CLI, and Gemini CLI prompts —
|
|
17
|
+
day-grouped, searchable, live-updating at `http://127.0.0.1:8745`.
|
|
18
|
+
- AI prompt revision via the hosted LLMLinq API (`api.llmlinq.com`).
|
|
19
|
+
- Cloud sync: sign in and push your prompts (with revisions) to your account,
|
|
20
|
+
viewable on any device at `llmlinq.com`.
|
|
21
|
+
- Privacy: read-only access to CLI history, localhost-only, no telemetry.
|
|
22
|
+
|
|
23
|
+
### Changed (vs aipromptdock 0.2.4)
|
|
24
|
+
|
|
25
|
+
- Renamed everywhere: install `llmlinq`, run `llmlinq`, data in `~/.llmlinq`
|
|
26
|
+
(migrated automatically from `~/.aipromptdock` on first run), env vars
|
|
27
|
+
`LLMLINQ_*` (old `AIPROMPTDOCK_*` honored as fallback for one cycle).
|
llmlinq-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 odyssey
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
llmlinq-0.1.0/Makefile
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
.DEFAULT_GOAL := help
|
|
2
|
+
MAKEFLAGS += --no-print-directory
|
|
3
|
+
|
|
4
|
+
help: ## List available targets
|
|
5
|
+
@grep -E '^[a-zA-Z_-]+:.*?## ' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-12s\033[0m %s\n", $$1, $$2}'
|
|
6
|
+
|
|
7
|
+
install: ## Install backend (uv) + frontend (npm) dependencies
|
|
8
|
+
uv sync
|
|
9
|
+
cd frontend && npm install
|
|
10
|
+
|
|
11
|
+
dev: ## Run backend (:8745) + frontend (:5173) with hot reload
|
|
12
|
+
$(MAKE) -j2 dev-api dev-ui
|
|
13
|
+
|
|
14
|
+
dev-api: ## Run the FastAPI backend only (hot reload)
|
|
15
|
+
uv run uvicorn --factory llmlinq.server:create_app --reload --port 8745
|
|
16
|
+
|
|
17
|
+
dev-ui: ## Run the Vite dev server only
|
|
18
|
+
cd frontend && npm run dev
|
|
19
|
+
|
|
20
|
+
build-ui: ## Build the SPA into src/llmlinq/web/static/
|
|
21
|
+
cd frontend && npm run build
|
|
22
|
+
|
|
23
|
+
build: build-ui ## Build the distributable wheel (UI bundled inside)
|
|
24
|
+
uv build
|
|
25
|
+
|
|
26
|
+
test: ## Run the Python test suite
|
|
27
|
+
uv run pytest
|
|
28
|
+
|
|
29
|
+
lint: ## ruff + mypy + tsc
|
|
30
|
+
uv run ruff check src tests
|
|
31
|
+
uv run ruff format --check src tests
|
|
32
|
+
uv run mypy src
|
|
33
|
+
cd frontend && npm run typecheck
|
|
34
|
+
|
|
35
|
+
fmt: ## Auto-format Python code
|
|
36
|
+
uv run ruff check --fix src tests
|
|
37
|
+
uv run ruff format src tests
|
|
38
|
+
|
|
39
|
+
clean: ## Remove build artifacts and caches
|
|
40
|
+
rm -rf dist src/llmlinq/web/static .pytest_cache .mypy_cache .ruff_cache
|
|
41
|
+
|
|
42
|
+
.PHONY: help install dev dev-api dev-ui build-ui build test lint fmt clean
|
llmlinq-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: llmlinq
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A local-first timeline for every prompt you've sent to Claude Code, Codex CLI, and Gemini CLI.
|
|
5
|
+
Author-email: odyssey <odyssey.unheard@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Keywords: claude,cli,codex,gemini,history,localhost,prompt,timeline
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Environment :: Web Environment
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Software Development
|
|
18
|
+
Classifier: Topic :: Utilities
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Requires-Dist: fastapi>=0.115
|
|
21
|
+
Requires-Dist: httpx2>=0.1
|
|
22
|
+
Requires-Dist: rich>=13
|
|
23
|
+
Requires-Dist: sse-starlette>=2.2
|
|
24
|
+
Requires-Dist: typer>=0.15
|
|
25
|
+
Requires-Dist: uvicorn>=0.32
|
|
26
|
+
Requires-Dist: watchdog>=6.0
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# <img src="frontend/public/favicon.svg" width="26" alt="LLMLinq icon"> LLMLinq
|
|
30
|
+
|
|
31
|
+
> A local-first timeline for every prompt you've ever sent to **Claude Code**,
|
|
32
|
+
> **Codex CLI**, and **Gemini CLI**.
|
|
33
|
+
|
|
34
|
+
LLMLinq reads the prompt history that the three major AI coding CLIs
|
|
35
|
+
already keep on your machine and presents it as a beautiful, searchable,
|
|
36
|
+
live-updating timeline at `http://127.0.0.1:8745`.
|
|
37
|
+
|
|
38
|
+
- 🗂 **Three tabs** — Claude · Codex · Gemini, with live prompt counts
|
|
39
|
+
- 🕰 **Timeline view** — day-grouped, newest first, with project context
|
|
40
|
+
- 🔍 **Search** — find any prompt you ever typed
|
|
41
|
+
- ⚡ **Live** — prompts appear in the timeline seconds after you type them
|
|
42
|
+
- 🔒 **Private by design** — read-only, binds to localhost, zero network egress, zero telemetry
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
## Install
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
uv tool install llmlinq # or: pipx install llmlinq / pip install llmlinq
|
|
49
|
+
llmlinq # scan → serve → open http://127.0.0.1:8745
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Or try it without installing anything:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
uvx llmlinq
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Only Python ≥ 3.11 is required — the web UI ships prebuilt inside the package.
|
|
59
|
+
The wheel can also be downloaded directly from the
|
|
60
|
+
[PyPI files page](https://pypi.org/project/llmlinq/#files).
|
|
61
|
+
|
|
62
|
+
> ⚠️ Running from a git clone (`uv run llmlinq`) shows a "UI not built"
|
|
63
|
+
> page — the UI is bundled into released packages, not the repository.
|
|
64
|
+
> Install from PyPI as above, or build the UI first (see Development).
|
|
65
|
+
|
|
66
|
+
Useful commands:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
llmlinq --port 9000 --no-browser # custom port, stay in the terminal
|
|
70
|
+
llmlinq paths # doctor: what was detected, where, how many prompts
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## How it works
|
|
74
|
+
|
|
75
|
+
| Provider | Reads (read-only) |
|
|
76
|
+
|---|---|
|
|
77
|
+
| Claude Code | `~/.claude/history.jsonl` (or session transcripts as fallback) |
|
|
78
|
+
| Codex CLI | `~/.codex/history.jsonl` + per-session metadata for project names |
|
|
79
|
+
| Gemini CLI | `~/.gemini/tmp/<sha256(project)>/logs.json` |
|
|
80
|
+
|
|
81
|
+
Gemini never stores project paths — only a SHA-256 hash of them — so AI Prompt
|
|
82
|
+
Dock recovers project names by hashing paths it learned from Claude and Codex
|
|
83
|
+
data and matching them against Gemini's directory names.
|
|
84
|
+
|
|
85
|
+
A filesystem watcher picks up new prompts as you type them into any of the
|
|
86
|
+
three CLIs and pushes them to the timeline over Server-Sent Events.
|
|
87
|
+
|
|
88
|
+
Custom data locations are honored via `CLAUDE_CONFIG_DIR` and `CODEX_HOME`.
|
|
89
|
+
|
|
90
|
+
## Project structure
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
llmlinq-app/
|
|
94
|
+
├── pyproject.toml # Package metadata, dependencies, tool config (ruff/mypy/pytest)
|
|
95
|
+
├── uv.lock # Locked dependency versions (reproducible installs)
|
|
96
|
+
├── Makefile # One-word workflows: make dev / test / lint / build
|
|
97
|
+
├── .github/workflows/ci.yml # CI: lint + typecheck + tests (Python 3.11–3.13) + UI build
|
|
98
|
+
├── src/
|
|
99
|
+
│ └── llmlinq/ # ── The Python package ──
|
|
100
|
+
│ ├── cli.py # Typer CLI entry point (`llmlinq` command)
|
|
101
|
+
│ ├── server.py # FastAPI app factory + production server runner
|
|
102
|
+
│ ├── api/ # HTTP API routes (Phase 2)
|
|
103
|
+
│ ├── core/ # Models, prompt store, file watcher (Phase 1)
|
|
104
|
+
│ ├── providers/ # Claude / Codex / Gemini history adapters (Phase 1)
|
|
105
|
+
│ └── web/static/ # Built SPA — generated by `make build-ui`, gitignored,
|
|
106
|
+
│ # shipped inside the wheel
|
|
107
|
+
├── frontend/ # ── The React app ──
|
|
108
|
+
│ ├── vite.config.ts # Builds into src/llmlinq/web/static/; dev proxy → :8745
|
|
109
|
+
│ └── src/
|
|
110
|
+
│ ├── App.tsx # Root component
|
|
111
|
+
│ └── styles/index.css # Tailwind CSS v4 entry (sky theme)
|
|
112
|
+
└── tests/ # pytest suite (synthetic CLI-data fixtures in Phase 1)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The one unusual thing worth knowing: **the frontend builds into the Python
|
|
116
|
+
package**. `vite build` outputs to `src/llmlinq/web/static/`, and the
|
|
117
|
+
wheel includes that directory (see `[tool.hatch.build]` in `pyproject.toml`).
|
|
118
|
+
That is why end users need only Python — never Node.
|
|
119
|
+
|
|
120
|
+
## Local development
|
|
121
|
+
|
|
122
|
+
Prerequisites: [uv](https://docs.astral.sh/uv/) and Node.js ≥ 22.
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
git clone <repo-url> && cd llmlinq-app
|
|
126
|
+
make install # uv sync (creates ./.venv + installs Python deps) + npm install
|
|
127
|
+
make dev # backend on :8745 + frontend on :5173, hot reload on both
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Open **http://localhost:5173** during development — the Vite dev server
|
|
131
|
+
proxies `/api` and `/healthz` to the FastAPI backend on `:8745`.
|
|
132
|
+
|
|
133
|
+
All Python tooling runs inside the project virtualenv at `./.venv`
|
|
134
|
+
(created by `uv sync`). Use `uv run <cmd>` — or activate it with
|
|
135
|
+
`source .venv/bin/activate` if you prefer.
|
|
136
|
+
|
|
137
|
+
Run the halves separately when needed:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
make dev-api # FastAPI only → uv run uvicorn --factory llmlinq.server:create_app --reload --port 8745
|
|
141
|
+
make dev-ui # Vite only → cd frontend && npm run dev
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
To test the production setup (FastAPI serving the built SPA, as end users get it):
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
make build-ui # build the SPA into the package
|
|
148
|
+
uv run llmlinq # serve everything from :8745
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Other useful targets:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
make test # pytest
|
|
155
|
+
make build # build the SPA, then the wheel (dist/llmlinq-*.whl, UI bundled)
|
|
156
|
+
make clean # remove build artifacts and caches
|
|
157
|
+
make help # list all targets
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Linting & formatting
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
make lint # check everything (what CI runs)
|
|
164
|
+
make fmt # auto-fix + format Python code
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
`make lint` runs, in order:
|
|
168
|
+
|
|
169
|
+
| Tool | Command | Checks |
|
|
170
|
+
|---|---|---|
|
|
171
|
+
| Ruff (lint) | `uv run ruff check src tests` | Python lint rules (`E,F,W,I,UP,B,SIM,C4,RUF`) |
|
|
172
|
+
| Ruff (format) | `uv run ruff format --check src tests` | Python formatting |
|
|
173
|
+
| mypy | `uv run mypy src` | Static types, `strict = true` |
|
|
174
|
+
| TypeScript | `cd frontend && npm run typecheck` | Frontend types (`tsc`, strict) |
|
|
175
|
+
|
|
176
|
+
Configuration lives in `pyproject.toml` (`[tool.ruff]`, `[tool.mypy]`) and
|
|
177
|
+
`frontend/tsconfig.json`. CI (`.github/workflows/ci.yml`) runs the same
|
|
178
|
+
checks plus the test suite on Python 3.11, 3.12, and 3.13 — run
|
|
179
|
+
`make lint test` before pushing and you should match CI exactly.
|
|
180
|
+
|
|
181
|
+
## License
|
|
182
|
+
|
|
183
|
+
[MIT](LICENSE)
|
llmlinq-0.1.0/README.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# <img src="frontend/public/favicon.svg" width="26" alt="LLMLinq icon"> LLMLinq
|
|
2
|
+
|
|
3
|
+
> A local-first timeline for every prompt you've ever sent to **Claude Code**,
|
|
4
|
+
> **Codex CLI**, and **Gemini CLI**.
|
|
5
|
+
|
|
6
|
+
LLMLinq reads the prompt history that the three major AI coding CLIs
|
|
7
|
+
already keep on your machine and presents it as a beautiful, searchable,
|
|
8
|
+
live-updating timeline at `http://127.0.0.1:8745`.
|
|
9
|
+
|
|
10
|
+
- 🗂 **Three tabs** — Claude · Codex · Gemini, with live prompt counts
|
|
11
|
+
- 🕰 **Timeline view** — day-grouped, newest first, with project context
|
|
12
|
+
- 🔍 **Search** — find any prompt you ever typed
|
|
13
|
+
- ⚡ **Live** — prompts appear in the timeline seconds after you type them
|
|
14
|
+
- 🔒 **Private by design** — read-only, binds to localhost, zero network egress, zero telemetry
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
uv tool install llmlinq # or: pipx install llmlinq / pip install llmlinq
|
|
21
|
+
llmlinq # scan → serve → open http://127.0.0.1:8745
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or try it without installing anything:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
uvx llmlinq
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Only Python ≥ 3.11 is required — the web UI ships prebuilt inside the package.
|
|
31
|
+
The wheel can also be downloaded directly from the
|
|
32
|
+
[PyPI files page](https://pypi.org/project/llmlinq/#files).
|
|
33
|
+
|
|
34
|
+
> ⚠️ Running from a git clone (`uv run llmlinq`) shows a "UI not built"
|
|
35
|
+
> page — the UI is bundled into released packages, not the repository.
|
|
36
|
+
> Install from PyPI as above, or build the UI first (see Development).
|
|
37
|
+
|
|
38
|
+
Useful commands:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
llmlinq --port 9000 --no-browser # custom port, stay in the terminal
|
|
42
|
+
llmlinq paths # doctor: what was detected, where, how many prompts
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## How it works
|
|
46
|
+
|
|
47
|
+
| Provider | Reads (read-only) |
|
|
48
|
+
|---|---|
|
|
49
|
+
| Claude Code | `~/.claude/history.jsonl` (or session transcripts as fallback) |
|
|
50
|
+
| Codex CLI | `~/.codex/history.jsonl` + per-session metadata for project names |
|
|
51
|
+
| Gemini CLI | `~/.gemini/tmp/<sha256(project)>/logs.json` |
|
|
52
|
+
|
|
53
|
+
Gemini never stores project paths — only a SHA-256 hash of them — so AI Prompt
|
|
54
|
+
Dock recovers project names by hashing paths it learned from Claude and Codex
|
|
55
|
+
data and matching them against Gemini's directory names.
|
|
56
|
+
|
|
57
|
+
A filesystem watcher picks up new prompts as you type them into any of the
|
|
58
|
+
three CLIs and pushes them to the timeline over Server-Sent Events.
|
|
59
|
+
|
|
60
|
+
Custom data locations are honored via `CLAUDE_CONFIG_DIR` and `CODEX_HOME`.
|
|
61
|
+
|
|
62
|
+
## Project structure
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
llmlinq-app/
|
|
66
|
+
├── pyproject.toml # Package metadata, dependencies, tool config (ruff/mypy/pytest)
|
|
67
|
+
├── uv.lock # Locked dependency versions (reproducible installs)
|
|
68
|
+
├── Makefile # One-word workflows: make dev / test / lint / build
|
|
69
|
+
├── .github/workflows/ci.yml # CI: lint + typecheck + tests (Python 3.11–3.13) + UI build
|
|
70
|
+
├── src/
|
|
71
|
+
│ └── llmlinq/ # ── The Python package ──
|
|
72
|
+
│ ├── cli.py # Typer CLI entry point (`llmlinq` command)
|
|
73
|
+
│ ├── server.py # FastAPI app factory + production server runner
|
|
74
|
+
│ ├── api/ # HTTP API routes (Phase 2)
|
|
75
|
+
│ ├── core/ # Models, prompt store, file watcher (Phase 1)
|
|
76
|
+
│ ├── providers/ # Claude / Codex / Gemini history adapters (Phase 1)
|
|
77
|
+
│ └── web/static/ # Built SPA — generated by `make build-ui`, gitignored,
|
|
78
|
+
│ # shipped inside the wheel
|
|
79
|
+
├── frontend/ # ── The React app ──
|
|
80
|
+
│ ├── vite.config.ts # Builds into src/llmlinq/web/static/; dev proxy → :8745
|
|
81
|
+
│ └── src/
|
|
82
|
+
│ ├── App.tsx # Root component
|
|
83
|
+
│ └── styles/index.css # Tailwind CSS v4 entry (sky theme)
|
|
84
|
+
└── tests/ # pytest suite (synthetic CLI-data fixtures in Phase 1)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The one unusual thing worth knowing: **the frontend builds into the Python
|
|
88
|
+
package**. `vite build` outputs to `src/llmlinq/web/static/`, and the
|
|
89
|
+
wheel includes that directory (see `[tool.hatch.build]` in `pyproject.toml`).
|
|
90
|
+
That is why end users need only Python — never Node.
|
|
91
|
+
|
|
92
|
+
## Local development
|
|
93
|
+
|
|
94
|
+
Prerequisites: [uv](https://docs.astral.sh/uv/) and Node.js ≥ 22.
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
git clone <repo-url> && cd llmlinq-app
|
|
98
|
+
make install # uv sync (creates ./.venv + installs Python deps) + npm install
|
|
99
|
+
make dev # backend on :8745 + frontend on :5173, hot reload on both
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Open **http://localhost:5173** during development — the Vite dev server
|
|
103
|
+
proxies `/api` and `/healthz` to the FastAPI backend on `:8745`.
|
|
104
|
+
|
|
105
|
+
All Python tooling runs inside the project virtualenv at `./.venv`
|
|
106
|
+
(created by `uv sync`). Use `uv run <cmd>` — or activate it with
|
|
107
|
+
`source .venv/bin/activate` if you prefer.
|
|
108
|
+
|
|
109
|
+
Run the halves separately when needed:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
make dev-api # FastAPI only → uv run uvicorn --factory llmlinq.server:create_app --reload --port 8745
|
|
113
|
+
make dev-ui # Vite only → cd frontend && npm run dev
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
To test the production setup (FastAPI serving the built SPA, as end users get it):
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
make build-ui # build the SPA into the package
|
|
120
|
+
uv run llmlinq # serve everything from :8745
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Other useful targets:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
make test # pytest
|
|
127
|
+
make build # build the SPA, then the wheel (dist/llmlinq-*.whl, UI bundled)
|
|
128
|
+
make clean # remove build artifacts and caches
|
|
129
|
+
make help # list all targets
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Linting & formatting
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
make lint # check everything (what CI runs)
|
|
136
|
+
make fmt # auto-fix + format Python code
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`make lint` runs, in order:
|
|
140
|
+
|
|
141
|
+
| Tool | Command | Checks |
|
|
142
|
+
|---|---|---|
|
|
143
|
+
| Ruff (lint) | `uv run ruff check src tests` | Python lint rules (`E,F,W,I,UP,B,SIM,C4,RUF`) |
|
|
144
|
+
| Ruff (format) | `uv run ruff format --check src tests` | Python formatting |
|
|
145
|
+
| mypy | `uv run mypy src` | Static types, `strict = true` |
|
|
146
|
+
| TypeScript | `cd frontend && npm run typecheck` | Frontend types (`tsc`, strict) |
|
|
147
|
+
|
|
148
|
+
Configuration lives in `pyproject.toml` (`[tool.ruff]`, `[tool.mypy]`) and
|
|
149
|
+
`frontend/tsconfig.json`. CI (`.github/workflows/ci.yml`) runs the same
|
|
150
|
+
checks plus the test suite on Python 3.11, 3.12, and 3.13 — run
|
|
151
|
+
`make lint test` before pushing and you should match CI exactly.
|
|
152
|
+
|
|
153
|
+
## License
|
|
154
|
+
|
|
155
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<meta name="description" content="A local timeline for your Claude Code, Codex CLI, and Gemini CLI prompts." />
|
|
8
|
+
<title>LLMLinq</title>
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|