What lives where
| Path | Holds |
|---|---|
~/.config/titah/titah.json | Global config |
./titah.json | Project config, merged over the global one |
~/.local/share/titah/ | Everything mutable |
~/.local/share/titah/titah.db | The sessions database |
~/.local/share/titah/auth.json | Provider credentials, mode 0600 |
~/.local/share/titah/account.json | Your Titah account token, mode 0600 |
~/.local/share/titah/tool-output/ | Tool results over 32 KB, and external agent transcripts |
~/.local/share/titah/snapshot/ | The shadow git repo used by undo |
~/.local/share/titah/log/ | Logs, including background turn output |
The two 0600 files are deliberately separate from each other. auth.json
holds your provider keys; account.json holds your identity. Mixing them would
let titah auth remove anthropic take your login with it.
Everything honours XDG_CONFIG_HOME and XDG_DATA_HOME; titah config path
prints the real locations.
The sessions database is SQLite, through node:sqlite. Metadata and messages go
in the database; large blobs go to disk, with the database keeping a pointer
and a summary.
Why blobs are separated
Agent transcripts are dominated by tool output — file contents, grep results, build logs — that nobody reads again after the turn ends.
The opencode install on the development machine had a 580 MB opencode.db
while every other directory held hundreds of kilobytes. Titah separates blobs
from the start, and ships retention in v1, because adding retention after
someone already has a 600 MB database is too late.
Output larger than 32 KB is written to tool-output/ and only the head
plus a pointer enters the context — which is a context-window decision as much as
a disk one.
Sessions belong to a folder
titah sessions list # this folder, newest first
titah sessions list --all # every project, with each session's path
A conversation is nearly always tied to the code being worked on, so a list mixing every project on the machine buries the one you actually want.
The match is on the exact directory: ~/proj and ~/proj/src are separate
projects. Paths are normalised first, so a trailing slash or a relative path
finds the same sessions — losing your history to a stray / would be
indefensible.
Empty sessions are never kept
The TUI has to create a session when it starts, not when you send the first
prompt, because the event stream needs an id up front. So titah opened and
closed again would otherwise leave an (untitled) row behind every time.
Instead the session is discarded on exit, on /new, and when you switch away
from it — and a session with no messages is never listed even if a crash left
one behind.
Discarding always goes through a check on the server that the session really is empty. The caller is throwing away a session it believes is unused, and one miscount must never cost a real conversation.
Pruning
titah sessions prune --older-than 30d
4 sessions deleted (older than 30d).
12 orphaned tool-output blobs and 1 snapshots swept.
Space reclaimed: 8.4 MB.
prune sweeps all three at once: database rows, orphaned blobs in
tool-output/, and orphaned snapshots. Deleting database rows alone is not
enough — it just moves the growth into the directory next door.
It also sweeps stragglers: empty sessions older than an hour. The grace period is there because a freshly empty session is probably open in another window, waiting for its first prompt.
Backing up
There is nothing to back up that you would miss for long — sessions are a transcript, not a source of truth. If you want them anyway:
tar czf titah-backup.tar.gz ~/.config/titah ~/.local/share/titah
!!! warning “That archive contains auth.json and account.json”
They hold your API keys and your account token in plaintext, which is why
both files are mode 0600. Treat the archive with the same care, or exclude
them: --exclude='auth.json' --exclude='account.json'.
Reclaiming everything
rm -rf ~/.local/share/titah
Sessions, snapshots, tool output, logs — and your credentials and account
token, since those live here too. Your config in ~/.config/titah survives,
and nothing in your projects is touched: the shadow git repo is a separate git
dir, so removing it cannot affect your own .git.
To reclaim disk without signing out and re-entering every API key, prune instead, or delete the three directories by name:
rm -rf ~/.local/share/titah/tool-output ~/.local/share/titah/snapshot ~/.local/share/titah/log