- Rust 85.2%
- JavaScript 8.9%
- CSS 3.1%
- Shell 2.2%
- HTML 0.6%
| docs | ||
| gpt-search | ||
| public | ||
| src | ||
| systemd | ||
| .gitignore | ||
| Cargo.toml | ||
| CONVENTIONS.md | ||
| example.json | ||
| FEATURES.md | ||
| install | ||
| README.md | ||
| test | ||
| uninstall | ||
LLM Thread Navigator (Rust)
A small Rust web app for browsing your LLM chat history, grouped by thread IDs spread across timestamped JSON files. It’s optimized for phones, supports swipe gestures to move between threads, and lets you mark threads as “todo”, “pending”, or “done” using a simple plain-text JSON status store.
Features
- Scans a history root directory for
*.jsonfiles like:<root>/<device>/YYYY/MM/DD/HH-MM-SS.json - Groups messages by
threadID across files and sorts by last activity - Mobile-friendly UI with swipe left/right to go next/previous thread
- Marks threads as
todo,pending, ordonevia a plain JSON file - Zero templating: UI is plain HTML/CSS/JS lintable assets
- Fast API built with axum
System messages (role = system) are hidden in the UI; only user and assistant entries are shown.
Requirements
- Rust (cargo) to build
- A history directory on disk with JSON arrays of messages like
example.jsonin this repo
Quick start (without systemd)
# From the repo root
export HISTORY_ROOT=/path/to/your/history
export BIND_ADDR=0.0.0.0:8000 # or 127.0.0.1:8000 for local-only
cargo run --release
Then open http://0.0.0.0:8000/ (or http://127.0.0.1:8000/ for local-only).
Installation as a user service (systemd)
You can install and run as a per-user systemd service:
./install /path/to/history 8047 0.0.0.0
- The third arg is optional; default bind host is
0.0.0.0(LAN). - Use
127.0.0.1if you want local-only access.
After install:
- Status:
systemctl --user status llm-thread-nav.service - Logs:
journalctl --user -u llm-thread-nav.service -f - Open:
http://<host>:<port>/
Where files are installed
- Binary:
~/.local/bin/llm_thread_nav - Static assets:
~/.local/share/llm-thread-nav/public - Systemd unit:
~/.config/systemd/user/llm-thread-nav.service - Environment vars:
~/.config/llm-thread-nav/env
The env file contains:
HISTORY_ROOT– your history dirBIND_ADDR– host:port the server binds to
You can edit ~/.config/llm-thread-nav/env and then run:
systemctl --user restart llm-thread-nav.service
Data and state
- Source of truth: your history root directory with JSON arrays of messages. See
example.jsonfor the expected structure. The app treats these as read-only. - Thread status store (plain text JSON):
<HISTORY_ROOT>/.thread_status.json- This is a simple JSON object mapping thread_id -> "todo" | "pending" | "done"
- Safe to manually edit with any text editor
- The app writes to this file atomically to avoid corruption
Example .thread_status.json:
{
"abc-123": "done",
"xyz-456": "pending",
"cool-thread": "todo"
}
Backups
To back up your state:
- Copy your entire history root (includes all source JSON files)
- At minimum, back up
<HISTORY_ROOT>/.thread_status.json
To back up the user service configuration (optional):
~/.config/llm-thread-nav/env~/.config/systemd/user/llm-thread-nav.service
Uninstall
systemctl --user disable --now llm-thread-nav.service
rm -f ~/.config/systemd/user/llm-thread-nav.service
rm -rf ~/.local/share/llm-thread-nav
rm -f ~/.local/bin/llm_thread_nav
rm -rf ~/.config/llm-thread-nav
systemctl --user daemon-reload
API
- GET
/api/threads?status=all|todo|pending|done&q=substring- Returns a list of thread summaries, sorted by last activity (desc)
- GET
/api/thread/:thread_id- Returns full details; messages exclude
systemrole
- Returns full details; messages exclude
- POST
/api/statuswith JSON{ "thread_id": "...", "status": "todo"|"pending"|"done" } - POST
/api/rescan- Forces a rescan of the history root
Notes
- If you bind to
0.0.0.0, ensure your firewall allows access (or restrict via your router/VLAN). - The app does not modify your history JSON files, only reads them.
- System messages are omitted from the detail view to reduce noise. If you need them for auditing, they still exist in your history files.
TUI (gpt-todo) — CLI Usage and Keys
The gpt-todo TUI lets you browse threads, update statuses, and read full threads in a detail view, similar to the web app. You can now open a specific thread and go back to the list.
Build
- cargo build --release
- Binary: target/release/gpt_todo (installed as ~/.local/bin/gpt-todo by ./install)
Run
- HISTORY_ROOT=/path/to/history target/release/gpt_todo
- Or: gpt-todo --root /path/to/history
- Optional filters:
- --status all|pending|todo|study|done (default: pending)
- --order desc|asc (default: desc)
- Jump straight to a specific thread’s detail view:
- --open <THREAD_ID>
List View Keys
- j / k or Down / Up: move selection
- g / G: top / bottom
- Ctrl-d / Ctrl-u: page down / up
- Space: cycle filter between Pending only → Done only → Others (todo + study)
- t / s / p / d (or x): set status to todo / study / pending / done
- 1..5: filter status (1=all, 2=pending, 3=todo, 4=study, 5=done)
- Tab: toggle sort (desc/asc)
- /: search (type to filter by thread id; Enter applies; Esc cancels)
- P: toggle preview panel (shows detail alongside list)
- V: cycle preview position (Right → Bottom → Top)
- h: focus thread list
- l: focus preview panel (then use j/k or Up/Down to move between cards)
- v: toggle “card-like” list rendering
- r: reload
- Enter/Return or o: open detail view for the selected thread
- q: quit
Detail View Keys
- j / k or Down / Up: scroll
- Ctrl-d / Ctrl-u or PgDown / PgUp: page scroll
- Left / Right: go to previous/next thread (within current filter/order)
- t / s / p / d (or x): set status while viewing the thread
- Esc or Backspace: go back to the list
- q: quit
Notes
- Status updates persist to <HISTORY_ROOT>/.thread_status.json immediately.
- Sorting and filtering determine which threads appear and how prev/next behaves.
- The “card-like” list view is a cosmetic toggle to make each item resemble the web app’s cards.
Build and test
- cargo build --release
- Example: HISTORY_ROOT=~/llm-history target/release/gpt_todo --status pending --open my-thread-123
- In the list, press Enter to read a thread; press Esc/Backspace to go back; press Left/Right to move between threads while in detail.