A local-first, perfectly private insight engine for obsessive journalers 🧶
6
stars
590
commits
Python
primary language
Mar 1, 2026
updated
Charlie is an experimental, local-first journaling app that synthesizes a knowledge graph of your memories. Write naturally about your life, and a local LLM finds and connects people, places, groups, and activities so you can explore your memories by browsing connections between entries. It automatically turns your journal entries into Wikipedia-like pages full of links to click on and dig deeper.

Use the Connection Browser to discover related concepts as you journey through space and time.

Can this help you discover conspiracy theories at work or process childhood trauma? That's the dream :)

This ain't another RAG project; it's way more convoluted and less effective BUT it has potential.
Here's how it currently works:
You write a journal entry (or import old ones).
A local LLM (Qwen3-4B-Instruct to be exact) will then extract "connections" (people, groups, places, and activities) that you can click on, or select via the sidebar.
Selecting a connection shows direct quotes, related connections, dates mentioned, and a few other tidbits of information to give you a higher-level overview.
3. That's basically all it can do, for now.
The extraction isn't perfect and it's sloooowwww (all recordings have been sped up), but the foundations work reliably!
Everything runs in a single Python process. No external dependencies. No cloud. No containers.

Instead of writing prompts by hand like a pleb from 2023, I over-engineered the hell out of this so I could justify paying $100/mo for a Claude Pro plan I used the most advanced technology available in the Fall of 2025 to build an automated pipeline that uses genetic algorithms to find the best prompt for the task at hand.
Here's how it currently works:

I created a "gold standard" set of examples showing ideal connection extraction to feed them into a local prompt optimizer script.
On HuggingFace's Inference Endpoints service, I spin up the same model (Qwen3-4B-Instruct) on an L4 GPU so I can run 20-30 evaluations in parallel instead of waiting hours for the local model to process everything (the llama.cpp runtime only permits serial requests for inference).
DSPy's GEPA optimizer orchestrates two models working together over ~128 iterations:
Behold; Digital Darwinism! Bad prompts die, good ones survive and get mutated by GPT-4o-mini based on performance feedback.
After an hour of automated trial-and-error, GEPA returns the best-performing prompt which gets saved to backend/prompts/extract_nodes.json and loaded at runtime.
For just a few dollars, this pipeline spits out prompts that work way better than anything I'd write manually, optimized specifically for extracting connections from journal entries. Neat huh? See backend/optimizers/README.md for the GPU & endpoint configuration details.
Charlie waits for you to finish writing before loading the model in memory to keep things snappy. When all the work is finished, it unloads the model to avoid hogging up all your precious RAM. All the orchestration is handled for you, including queuing entries, processing your most recent entry before tending to the backlog of jobs, and many other conveniences. Just focus on writing and exploring, everything else is automated.
System Requirements:
ldd --version./setup.sh
The setup script handles everything:
uv package manager (if needed)Setup prompts you to import, or run importers manually:
# Day One export
python importers/dayone.py ~/Downloads/DayOneExport.zip
# Text files directory
python importers/files.py ~/journals/ --recursive
# Dry run (preview without importing)
python importers/files.py ~/journals/ --dry-run
See importers/IMPORTING.md for all options.
./charlie.sh
Or manually activate the virtual environment:
source .venv/bin/activate
python charlie.py
Python
99.1%
A local-first, perfectly private insight engine for obsessive journalers 🧶
6
stars
590
commits
Python
primary language
Mar 1, 2026
updated
Charlie is an experimental, local-first journaling app that synthesizes a knowledge graph of your memories. Write naturally about your life, and a local LLM finds and connects people, places, groups, and activities so you can explore your memories by browsing connections between entries. It automatically turns your journal entries into Wikipedia-like pages full of links to click on and dig deeper.

Use the Connection Browser to discover related concepts as you journey through space and time.

Can this help you discover conspiracy theories at work or process childhood trauma? That's the dream :)

This ain't another RAG project; it's way more convoluted and less effective BUT it has potential.
Here's how it currently works:
You write a journal entry (or import old ones).
A local LLM (Qwen3-4B-Instruct to be exact) will then extract "connections" (people, groups, places, and activities) that you can click on, or select via the sidebar.
Selecting a connection shows direct quotes, related connections, dates mentioned, and a few other tidbits of information to give you a higher-level overview.
3. That's basically all it can do, for now.
The extraction isn't perfect and it's sloooowwww (all recordings have been sped up), but the foundations work reliably!
Everything runs in a single Python process. No external dependencies. No cloud. No containers.

Instead of writing prompts by hand like a pleb from 2023, I over-engineered the hell out of this so I could justify paying $100/mo for a Claude Pro plan I used the most advanced technology available in the Fall of 2025 to build an automated pipeline that uses genetic algorithms to find the best prompt for the task at hand.
Here's how it currently works:

I created a "gold standard" set of examples showing ideal connection extraction to feed them into a local prompt optimizer script.
On HuggingFace's Inference Endpoints service, I spin up the same model (Qwen3-4B-Instruct) on an L4 GPU so I can run 20-30 evaluations in parallel instead of waiting hours for the local model to process everything (the llama.cpp runtime only permits serial requests for inference).
DSPy's GEPA optimizer orchestrates two models working together over ~128 iterations:
Behold; Digital Darwinism! Bad prompts die, good ones survive and get mutated by GPT-4o-mini based on performance feedback.
After an hour of automated trial-and-error, GEPA returns the best-performing prompt which gets saved to backend/prompts/extract_nodes.json and loaded at runtime.
For just a few dollars, this pipeline spits out prompts that work way better than anything I'd write manually, optimized specifically for extracting connections from journal entries. Neat huh? See backend/optimizers/README.md for the GPU & endpoint configuration details.
Charlie waits for you to finish writing before loading the model in memory to keep things snappy. When all the work is finished, it unloads the model to avoid hogging up all your precious RAM. All the orchestration is handled for you, including queuing entries, processing your most recent entry before tending to the backlog of jobs, and many other conveniences. Just focus on writing and exploring, everything else is automated.
System Requirements:
ldd --version./setup.sh
The setup script handles everything:
uv package manager (if needed)Setup prompts you to import, or run importers manually:
# Day One export
python importers/dayone.py ~/Downloads/DayOneExport.zip
# Text files directory
python importers/files.py ~/journals/ --recursive
# Dry run (preview without importing)
python importers/files.py ~/journals/ --dry-run
See importers/IMPORTING.md for all options.
./charlie.sh
Or manually activate the virtual environment:
source .venv/bin/activate
python charlie.py
Python
99.1%