A local second brain that watches how you work and continuously reprograms a website about you.
abraxas runs on your machine and quietly collects the traces of your actual behavior — the commits you push, the prose you write, the screens you look at — then runs a cortex loop: a small local model reads the new activity and rewrites a live dashboard of who you are right now. Your interests, what you're building, what to explore next, and advice grounded in what you actually did. The website changes as abraxas learns. Everything stays on your machine.
your behavior ──▶ collectors ──▶ abraxas.db ──▶ cortex loop ──▶ derived state ──▶ localhost site
commits (SQLite, (a local (the derived (rewrites itself
writing the record, LLM via kaos) "you") as you work)
screens your backup)
- Local and private. Hosted model providers are rejected, Ollama endpoints
must resolve to loopback, and the site binds to
127.0.0.1. Your data never leaves the machine. - Small-model native. The cortex speaks through kaos, an agent orchestrator tuned for small local models: JSON-constrained sampling, lenient parsing, best-of-k draws.
- Backup-able by design. The record is one SQLite file under
~/.abraxas; editable config lives in~/abraxas.yaml.abraxas exportgives you one portable file. - Dependency-light. The website is a std
TcpListener— no async runtime, no web framework. SQLite is bundled, so there's nothing to install.
The name. In gnostic cosmology Abraxas is the archon whose name sums to 365 — the days of the year, the many powers gathered into one figure. This app gathers the scattered traces of your days into a single portrait. The interface carries that register lightly: the gnosis (your portrait), the measure (your rhythm, counted), auguries (where you're heading).
Nine tabs, one manuscript — all served at http://localhost:4477:
- the codex (
/) — the living dashboard the cortex rewrites each pass: a model-written portrait, deterministic statistics (active days, streaks, your by-hour and by-weekday rhythm), weighted interests, recommendations and advice, detected friction (repos heavy with fix/bug/revert commits), predicted next topics, and a live feed of your record. - context (
/context) — the ambient signals as first-class citizens: active windows, browser visits, shell commands, clipboard, notes — broken down by source and on a timeline. - the library (
/library) — every topic abraxas has named, as a weighted, clickable constellation. Each topic page shows what it's bound to (the co-occurrence graph) and the evidence for it in your record. - the graph (
/graph) — one large inspectable map drawing events, topics, derived state, and advice together. - the aeons (
/aeons) — the abstraction ladder: the model gathers your topics and streams into named higher-order pursuits, finds the bridges between them, and names the one thing above them all. - the collider (
/collider) — an expression tool: write parenthesised s-expressions of keywords, get an immediate deterministic correlation analysis of your record plus an optional AI reading. Saved expressions are sigils. - the oracle (
/oracle) — an agent you ask about yourself. It answers by querying your record through read-only tools; conversations are durable threads. - the calendar (
/calendar) — a month heatmap and a per-day recap of everything you did, with pinnable day pages. - settings (
/settings) — every config key, model setup buttons, and full data controls (delete any event, topic, source, or everything).
Plus full-text search across your whole record (SQLite FTS5), from any page.
git clone https://github.com/fmzbl/abraxas
cd abraxas
cargo install --path . # drops `abraxas` on your PATHThe kaos model seam is fetched automatically by cargo. You'll also want a local model runner and two small models:
# https://ollama.com
ollama pull qwen3:4b # default cortex model
ollama pull moondream # default vision model(Or open the settings tab later and click download default models.)
abraxas init # discover repos, write ~/abraxas.yaml, optionally encrypt
abraxas up # start the daemon in the backgroundOpen http://localhost:4477 and just keep working. As you commit, write, and browse, the page fills in and rewrites itself. That's the whole loop.
abraxas doctor checks your setup (ollama reachable, models pulled, a real
trial screen capture) and tells you exactly what's missing.
abraxas init discover your repos, write ~/abraxas.yaml, create ~/.abraxas
abraxas up start the daemon in the background (survives closing the terminal)
abraxas stop stop a server or daemon started by serve, run, or up
abraxas password [status|set|change|disable]
manage SQLCipher database encryption
abraxas run run the daemon in the foreground (collect + reprogram + serve)
abraxas serve [--port N] serve the website only
abraxas collect run the collectors once (commits, writings, one screen)
abraxas note <text> add a manual note event; reads stdin when text is omitted
abraxas cortex run one cortex pass now (reprogram the site)
abraxas screenshot capture + analyze one screen now
abraxas vision <image> describe any image with the vision model (test your setup)
abraxas model [spec] show or set the cortex model
abraxas doctor preflight: check ollama, models, screenshot tool
abraxas status print what the abraxas currently knows
abraxas export [file] bundle config + events + state into one portable JSON
abraxas import <file> restore an export bundle
abraxas compact merge repeated records and reclaim database space
abraxas aeons draw the abstraction ladder (the aeons tab) now
The cortex model is configurable, but hosted providers are rejected. Precedence, highest first:
--model <spec> > $ABRAXAS_MODEL > ~/abraxas.yaml "model"
Specs are kaos form:
abraxas model ollama:qwen3:4b # local, private (default)
abraxas run --model ollama:qwen3:4b # one-off overrideEvery collector is idempotent, secrets are redacted (tokens, passwords, api keys, long digit strings), and each one can be turned off:
| collector | default | what it gathers |
|---|---|---|
| git commits | on | new commits in your configured repos (subject + stat/patch) |
| writings | on | recently modified prose/code files under watch_dirs |
| active window | on | the focused app/window title only — never contents |
| screenshots | off | the screen, described by a local vision model + local OCR |
| shell history | off | your shell commands, noise-filtered and redacted |
| browser history | off | page title/url metadata, allowlisted dev domains only |
| clipboard | off | clipboard text, redacted |
| manual notes | — | whatever you give abraxas note |
Screen capture is opt-in (capture_screenshots). When enabled, abraxas reads
your screen with a local vision model (default moondream) and feeds the
description into the cortex. If Tesseract is installed, abraxas also runs local
OCR and stores the visible screen text as searchable event text. Test vision on
any image:
abraxas vision some-screenshot.pngInstall OCR support with brew install tesseract (macOS) or
sudo apt install tesseract-ocr (Debian/Ubuntu) — or use the settings-tab
button.
Screen capture is cross-platform and auto-detected, best backend first:
| platform | backend | notes |
|---|---|---|
| macOS | screencapture |
built in, nothing to install |
| X11 | scrot · maim · import |
install any one |
| wlroots Wayland (Sway, Hyprland) | grim |
sudo apt install grim |
| GNOME / KDE Wayland | desktop portal via gdbus |
no install on GNOME; grim does not work here |
abraxas doctor runs a real trial capture and tells you exactly what works. If
nothing does, screen reading is skipped and the rest of the abraxas runs
normally.
GNOME rate-limits rapid successive portal screenshots, so two manual captures back-to-back may have one refused. The daemon captures minutes apart, so this never affects normal use.
Small vision models are prompt-sensitive, so the default prompt is a short
caption instruction. On a larger model (llava, qwen2.5vl) set a richer
vision_prompt in ~/abraxas.yaml. Set vision_model to "" to skip
analysis entirely.
Screenshots are deleted unless explicitly kept. After capture, abraxas
keeps the text description and removes the raw PNG, so your literal screen
contents never pile up on disk. Set keep_screenshots: true to retain the
images (e.g. for thumbnails on the site).
Everything lives in ~/abraxas.yaml and is also editable from the settings
tab. The important keys:
| key | default | meaning |
|---|---|---|
model |
ollama:qwen3:4b |
cortex model, kaos spec form |
vision_model |
moondream |
multimodal ollama tag to read screens, "" to skip |
vision_prompt |
built-in | custom vision prompt for larger models |
repos |
discovered | git repos whose new commits become events |
watch_dirs / write_exts |
discovered / broad set | where prose is collected, and which extensions count |
samples |
1 |
best-of-k cortex samples (small models benefit from k>1) |
model_timeout_secs |
360 |
per cortex model call timeout |
oracle_timeout_secs |
900 |
oracle / background job timeout |
capture_screenshots |
false |
whether to grab the screen at all |
keep_screenshots |
false |
keep raw PNGs after analysis |
collect_active_window |
true |
record the focused window title |
collect_shell_history |
false |
import shell history |
collect_browser_history |
false |
import browser history metadata |
browser_allowlist |
dev domains | which domains browser collection may record |
collect_clipboard |
false |
capture clipboard text |
collect_file_diffs |
false |
append working-tree diffs to writing events |
auto_compact_daily |
true |
daemon merges repeated records daily |
collect_interval_secs / cortex_interval_secs / screenshot_interval_secs |
90 / 600 / 300 |
daemon cadence |
port |
4477 |
localhost website port |
expose_state_api |
false |
serve raw state JSON at /api/state |
access_password_hash |
"" |
optional Argon2id password hash for SQLCipher database encryption and website access |
~/abraxas.yaml behavior + models (user-editable)
~/.abraxas/
abraxas.db the record: events, derived state, topic graph, oracle
threads, sigils, pins (SQLite/SQLCipher, FTS5-searchable)
screenshots/ captured PNGs (only when keep_screenshots is on)
The events table is the source of truth; the derived state and topic graph
rebuild from it. A pre-SQLite events.jsonl log is migrated in automatically
on first run. Back up by copying ~/.abraxas (or just abraxas.db), or:
abraxas export my-abraxas.json # config + events + state, portable
abraxas import my-abraxas.json # restore on another machineThe settings tab has full data controls: delete a single event or topic, a whole collector's output, a calendar day/month/year, or everything.
abraxas up already gives you a detached daemon. If you want systemd instead:
# ~/.config/systemd/user/abraxas.service
[Unit]
Description=abraxas — local second brain
[Service]
ExecStart=%h/.cargo/bin/abraxas run
Restart=on-failure
[Install]
WantedBy=default.targetsystemctl --user enable --now abraxascargo build
cargo test
cargo run -- statusTo hack on kaos at the same time, point cargo at a local checkout — see CONTRIBUTING.md.
model.rs the two data shapes: append-only Event, derived BrainState
config.rs config + autonomous repo discovery + local model guard
store.rs SQLite persistence: events (FTS5), state, topics, pins, threads
collect.rs collectors: git, prose, windows, shell, browser, clipboard, screen
vision.rs screenshot description via a local ollama vision model
cortex.rs the loop model: events → interests/advice/aeons via kaos
oracle.rs the oracle agent: read-only tools over your record
collider.rs keyword s-expressions → correlation analysis + AI readings
analytics.rs deterministic behavioral statistics over the whole log
health.rs `abraxas doctor` preflight checks
server.rs a std-only localhost HTTP server (no async runtime, no framework)
web.rs the website, rendered as a pure function of BrainState
main.rs CLI + the daemon loop
Everything is local by default, enforced at every model call site:
- Hosted model providers are rejected — the cortex, the oracle, the collider, the aeons, and tips all refuse a non-local spec.
- Ollama endpoints must resolve to loopback (
localhost,127.0.0.1, or::1), including a user-setOLLAMA_HOST— a remote ollama is refused even for a "local" spec. - The website binds to
127.0.0.1only, checks request origins, and serves a strict CSP. - Optional encrypted mode rewrites
abraxas.dbwith SQLCipher, stores only an Argon2id password hash in the private config file, and requires login before data pages, APIs, or screenshots are served.abraxas initasks whether to enable it; later useabraxas password set,abraxas password change, orabraxas password disable. CLI commands can unlock withABRAXAS_PASSWORD; the website login can unlock a running server process. Encrypted mode adds SQLCipher overhead, so page loads and searches may be slower than plaintext. - The invasive collectors (screen, shell, browser, clipboard) are all opt-in, collected text is redacted for secrets, and everything collected is yours to delete from the settings tab.
The only network activity abraxas can initiate is the one you ask for: the
settings-tab buttons that download models (ollama pull) or install
Tesseract. Nothing it has collected is ever sent anywhere.
GPL-3.0 — see LICENSE.
