perplexity-cli
🧠 A simple command-line client for the Perplexity API. Ask questions and receive answers directly from the terminal! 🚀🚀🚀
Open-source private logbook with a local agentic layer. Long-living AI agents read what you record and propose what to…
A private logbook for the work you actually did.
Lotti records what you meant to do and what actually happened, and keeps them as separate facts. Tasks, planned blocks, tracked time, voice notes, journal entries, habits, and health data live in a local database on your own devices. There is no Lotti account and no Lotti server. AI is optional, and when you do set it up, the route Lotti recommends is European infrastructure running open-weight models. Nothing reaches your history without your approval.
macOS · Linux · Windows · iOS · Android. Flutter and Dart, GPL-3.0, in development since 2016.
I have tracked around 11,000 hours of my own work in it since 2022.
Read the manual · Install · Blog series
Intent and reality are separate records. A task describes an outcome you want. A time record describes what actually happened, with the notes, photos, recordings, and measurements that explain it attached to it. Most tools flatten the two into a single list and then ask you to pretend the day went to plan. Lotti keeps them apart, so the record stays honest when the week gets noisy.
Agents propose, you decide. An agent can read a task, form an opinion, summarise a mess, and suggest a next change. Its report is an opinion with provenance, not a new fact in your history. Task, checklist, status, and date changes wait for you to confirm or dismiss them. The only exception is an initial title or language for an otherwise empty task. This is enforced by the storage layout rather than by careful prompting — see Two databases.
There is no Lotti server. Your logbook lives on your devices. Sync is self-hosted and end-to-end encrypted, so the relay only ever handles ciphertext. No account, no telemetry, and nothing uploaded to Lotti.
You choose the brain, and you can see what it cost. Route each category of your life to the compute you are willing to stand behind: a local model for the private things, a frontier model for work, or the European option Lotti recommends. The usage view reports tokens and requests for every cloud call, and spend, energy and CO₂e for the providers that report them — today that means Melious. Local inference is not measured at all, because the cost moves onto your own hardware and grid.
| Platform | Where to get it |
|---|---|
| Linux | Flathub (recommended) or tar.gz on Releases |
| macOS | Signed and notarized DMG on Releases |
| iOS / iPadOS / macOS | TestFlight (limited; invitation only), with broader availability planned |
| Android | APK on Releases, or Play Store internal testing (limited; invitation only) |
| Windows | Build from source for now |
tools/matrix_provisioner CLI, which creates the
sync account and encrypted room and writes a single-use pairing bundle.Lotti keeps what you said and did and what an agent thinks in different databases on disk.
The user database is the system of record: tasks, notes, audio, time recordings, journal entries. It is treated with care, and agents do not write into it freely.
The agentic database is agent working memory: definitions, memories, wake history, reasoning traces, intermediate results. It may grow and it may be pruned. It can be thrown away and rebuilt without losing anything that matters about you.
flowchart LR
subgraph Agentic["Agentic DB (prunable, recreatable)"]
A[Agent state & memories]
W[Wake cycle reports]
S[Suggestions]
end
subgraph User["User DB (system of record)"]
T[Tasks]
J[Journal & audio]
M[Metrics & habits]
end
A --> W --> S
S -->|requires user approval| T
S -.->|exception: initial title & language only| T
Loading
The rule matters because of how it is enforced. Agent-authored content sits in a different file on disk and reaches the user database only through a code path that requires your approval. A misbehaving agent has no path to any other field in the user database.
The two narrow exceptions both concern fields that are still empty: an agent may set the initial title of an untitled task, and the initial language of a task that has none. Every subsequent edit needs your approval.
Three different claims get flattened into the word "private." Lotti makes all three. They are worth separating, because they fail in different ways.
There is no Lotti server. No account, no telemetry, no analytics, and nothing uploaded to Lotti. Entries live in local SQLite on each of your devices, with attachments beside it on the filesystem. That is structural rather than a policy commitment: there is nowhere for the data to go, and you can confirm it by reading the source or watching the traffic. Two things do leave, both because you configured them: ciphertext to the homeserver you chose, and inference requests to the provider you chose.
The other side of that: there is no server-side backup and no account recovery, because there is no account. Sync is the redundancy story — but it is not automatic history. Pairing a device gives it everything written from then on; your existing settings and back catalogue arrive only when you run Send settings and Send message history from the device that already has them. Until you do, the new device is a live peer, not a backup. Do that early, and a second device means losing one costs you nothing.
Keep an ordinary backup as well, since replication covers hardware loss and a
backup covers everything else. There is no export feature, because there is
nothing to export from. Your logbook is a SQLite database sitting on your own
disk with a documented schema, so reading it takes a query rather than
permission. Take a consistent copy with VACUUM INTO while the app is running,
and bring the attachments directory along with it, because audio and images
live on the filesystem rather than in the database.
On a phone the database sits inside the app sandbox, so the practical route there is to pair a desktop and take the copy from that peer.
Deleting works the other way round, and the order matters: delete entries in the app rather than deleting the database files. Purging removes an attachment by walking the deleted rows that still point at it, so a database removed first leaves its audio and images orphaned on disk. Paired devices and ordinary backups keep their own copies either way, and anything already sent to a provider is subject to that provider's retention, not yours.
What this does not protect against: a compromised device. The on-device SQLite files live inside your OS user account and are not separately encrypted by Lotti today. App-level at-rest encryption is a candidate for the roadmap; until it lands, give Lotti's on-device data the same care you would give any personal app on the same machine, and weigh that before putting your most sensitive categories in it.
Sync runs over Matrix with Vodozemac for end-to-end encryption, against a Synapse homeserver you or someone you trust operates. The relay only ever handles ciphertext. Encryption keys are shared only with devices you have verified through an emoji comparison, so a device that joins the account without completing verification receives data it cannot read. Both databases sync this way.
What this does not protect against: metadata. Whoever runs the homeserver can observe that a device synced, when, and roughly how much. Not what.
Lotti has no inference backend. Every AI call goes to a provider you configured, under your own account and API key, and you choose per category which provider that is. Work can go to a frontier model while a journal stays on a local one. That granularity is the entire point.
Onboarding highlights a European route. Melious.ai is a German company routing open-weight models across a network of EU infrastructure providers, independently verified at staysin.eu. They state that requests are not used for training and that data stays under European jurisdiction. Those are their claims, on their terms, and worth reading in full before you rely on them.
Mistral, Google, Alibaba, OpenAI, Anthropic, OpenRouter, and any other OpenAI-compatible endpoint work equally well. Lotti does not rank them, does not summarise their terms, and cannot verify anyone's claims about jurisdiction, retention, or training. Picking a provider is your decision and the due diligence is yours.
What Lotti does instead is refuse to let the decision be invisible:
A LAN endpoint is worth the same scrutiny. "Local" means it did not go to a hosted provider, not that no network hop occurred.
What this does not protect against: a provider that does not do what its terms say. Nothing in Lotti can verify that, and neither can anyone else from the outside. What Lotti can do is show you every request it made, where it went, and what it cost.
Local inference is finally good enough to drive the agents. Qwen 3.6 35B A3B is the model validated in daily use here — 35B parameters with roughly 3B active per token, which is what makes it practical on a personal machine while still being smart enough for the agentic loop. Others probably work too.
It is power-hungry. Tested extensively on an M4 Max with 128 GB of RAM, the laptop is audible under sustained agent load and the battery drains noticeably faster than during normal work. Feasible, not free.
Hybrid is the realistic answer, and it is how I run it: a local model for the private categories, a cheap cloud model such as Gemini Flash for open-source work and everyday task management. Speech is fully offline via Whisper or Voxtral either way. Image generation is the one thing with no local path yet — cover art goes through Gemini or Alibaba.
Inference runs in a physical building on a specific grid. The Usage & Impact view reports tokens and requests for every cloud call, broken down by category and by model, so "what did my thinking cost" has an answer rather than a vibe.
How complete that answer is depends on the provider. Cost, energy, CO₂e and water are recorded when the provider returns them with the response, which today means Melious; every other provider reports token counts only, and those columns stay empty rather than being filled with an estimate. That is a real limit on the dashboard: route your work through a provider that discloses nothing, and the impact of that work is not something Lotti can show you.
The route highlighted in onboarding publishes power usage effectiveness per datacenter and carries Green Web Foundation verification, which is more than most disclose. Running a model locally moves the cost onto your own hardware and your own grid, which is a different trade rather than a free one, and the dashboard does not measure it.
Choosing a renewable-powered route avoids outsourcing the health and climate cost of fossil-powered compute, gas turbine generation in particular, to communities with less power to refuse it. That is a reason to care where your tokens get processed even if you do not care who reads them.
Turn AI off. Configure no provider at all, or point every category at Ollama with local Whisper for speech. Lotti is a complete task manager, time tracker, and journal without a single inference call leaving the machine.
Built and documented, but not enabled in a default build. Turn it on under Settings → Advanced → Flags, and expect it to change.
Next agent types on the roadmap: week planners, long-term commitment monitors, and effort-against-goals balancers — same building blocks, different jobs. Designed but not yet built: learning quizzes and relationship check-ins. See the roadmap.
Linux is and will always be free, with maximum functionality. No paywalls, no upsells. The same promise extends to any future fully open-source mobile operating system. The one thing it does not include is hosted sync infrastructure — running a homeserver is a real cost, so you either self-host Matrix or bring your own.
On other platforms, the basics stay free too. Task and journal capture, the task agent, voice transcription, the everyday loop.
More advanced agent features may eventually be in-app purchases on platforms where IAP is the norm (iOS/macOS, Android, Windows). The candidates: day- and week-planner agents, overarching project-management agents, longer-horizon commitment monitors. The exact split is not set yet.
Building it yourself: install Flutter via FVM (the repo
includes .fvmrc), then make deps, make analyze, make test,
fvm flutter run -d <device>. Full setup, including the Linux audio-codec and
emoji-font packages, is in docs/DEVELOPMENT.md.
Currently 0.9.x, working toward 1.0. The application is in active daily use and the agentic layer is real, working, and shipping. Development happens in the open, and the changelog is the honest version of what changed.
Worth knowing if you are picking it up now: the design-system rollout is partway through, so some screens are polished and others are not. The agentic layer is young — soul and template ergonomics, grievance handling, and pruning strategies are all under active development, and feedback there is especially useful. Local image generation and at-rest database encryption do not exist yet.
The manual, including every screenshot in all 11 languages, is generated from a deterministic fixture workspace, so the documentation cannot quietly drift from the build it documents.
Stack: Flutter and Dart across five platforms, local SQLite via Drift with ObjectBox for embeddings, Whisper and Voxtral for on-device speech recognition, Matrix and Vodozemac for the encrypted sync transport, Glados for property-based tests.
Two things genuinely help, and one thing to know up front.
Welcome:
Not accepted: code pull requests. Review capacity is the binding constraint, Lotti holds people's personal data on their own devices, and AI-generated code now arrives far faster than it can be reviewed carefully. An unsolicited code PR will be closed unmerged, with thanks and without review — so please open an issue instead of writing the patch. It is more useful to me and cheaper for you.
Lotti is GPL-3.0: fork it and build whatever you like on top for yourself.
CONTRIBUTING.md has the details, including what makes a translation PR mergeable.
GPL-3.0. See LICENSE.
Thanks to the Flutter team, the Qwen and Mistral teams for their open-weights models, OpenAI for the Whisper weights, the Ollama project, the Matrix.org community, the Vodozemac authors, and everyone contributing translations, issues, and ideas.
more like this
🧠 A simple command-line client for the Perplexity API. Ask questions and receive answers directly from the terminal! 🚀🚀🚀
Habit Tracker helps you build positive habits and keeps track of your day-to-day habits and routines. Made with Clean a…
search projects, people, and tags