devin-history
Unofficial community project. Not affiliated with, endorsed by, or sponsored by Cognition AI. "Devin" is a trademark of Cognition AI.
Linux · Personal Windows · Corporate Windows
Part of the awesome-devin ecosystem: the curated hub for the devin-* tools.
Export and audit Devin Desktop session history — turns the local
sessions.db into Obsidian-ready Markdown notes, a searchable JSON dump,
and an audit report. GUI session metadata (state.vscdb) exports as
metadata notes too.
The problem
Devin Desktop keeps your session history in a local SQLite database
(%APPDATA%/devin/cli/sessions.db on Windows, or
$XDG_DATA_HOME/devin/cli/sessions.db on Linux; default
~/.local/share/devin/cli/sessions.db) — and nowhere else. There is no export
button: once a session scrolls out of the UI (or is pruned by the app), the
prompts, replies and tool calls are effectively gone. You can't search old
sessions, can't answer "what did I ask Devin to do last month", and can't
audit how the agent has been used across projects.
Prior art
- tokmesh and UniSessions document/parse
sessions.db; the schema itself is tracked bydevin-internals-spec. - This project ports two proven scripts that lived in the orchestrator
workspace (
legacy/):devin-history-export.py(DB → Obsidian notes) andaudit_sessions.py(lifetime audit → CSV + report). They are rewritten as library modules — same logic, real tests. - You can also just run
sqlite3queries by hand — but then you guess the schema on every Devin update.
What makes it Devin-native
It understands Devin's real stores instead of raw-SQL guessing: it opens
sessions.db through devin-internals-spec's typed parsers and refuses
loudly when the schema version is one it has never seen (the store has
had 17 migrations already). The export knows about hidden sessions,
interrupted threads (last node = user), tool_call_state failures and
epoch-millisecond timestamps — details a generic SQLite dump misses.
Install
Python ≥ 3.10 and pipx are required. Windows (PowerShell): install pipx with py -m pip install --user pipx, run py -m pipx ensurepath, then reopen the terminal. Linux (Debian/Ubuntu): run sudo apt install pipx python3-venv and pipx ensurepath; reopen the terminal. Other Linux distributions should install pipx using their package manager.
pipx install "devin-history @ git+https://github.com/Icaro0310/devin-history.git"
(PyPI release is on the M2 roadmap; Python ≥ 3.10 required.)
Usage
# quick session table (auto-detects %APPDATA%/devin/cli/sessions.db)
devin-history list
# one Obsidian note per session + index.md — safe to re-run (incremental)
devin-history export --out ~/ObsidianVault/Sessions
# searchable JSON dump instead of Markdown
devin-history export --out dump/ --format json
# audit: status/type/project/period groupings + anomalies, optional CSV
devin-history audit --csv audit.csv
# GUI sessions: metadata notes (slug, workspace, folders, lastUpdated) +
# index.json — the GUI keeps no local transcript, so metadata is all there is
devin-history export-gui --out ~/ObsidianVault/Sessions/gui
# everything has --json; point at a specific DB with --sessions-db/--vscdb
devin-history audit --sessions-db path/to/sessions.db --json
devin-history export-gui --vscdb path/to/state.vscdb --out gui-notes/
No Devin installed? Try it on a synthetic fixture (stdlib-only, no Devin data involved):
pipx install "devin-internals-spec==0.3.0"
devin-inspect make-fixture /tmp/fx
devin-history export --sessions-db /tmp/fx/cli/sessions.db --out /tmp/notes
Notes are idempotent: each file embeds the session's last_activity
marker, so re-runs skip unchanged sessions (--all forces a rewrite,
--dry-run previews). The index.md/index.json at the root carries a
stats block — total sessions, date span, per-project and user/assistant/tool
message totals — alongside the grouped links.
export-gui reads the Electron state.vscdb store (auto-detected under
User/globalStorage/ of the Devin config dir, override with --vscdb)
and writes one note per windsurfSpace.sessionWorkspace/* binding: slug,
label, backend, workspaceId, folders, lastUpdated, and lastAccessed
when derivable via windsurfSpace.resourceToSpace + windsurfSpace.metadata.
It is read-only on state.vscdb, embeds the same provenance
(machine_id/profile), and writes an index.json index.
Works with Devin alone (Devin-only mode)
Everything devin-history does happens on your machine: it reads
sessions.db and writes Markdown/JSON exports to a folder you choose. No
network, no external service — the Obsidian-style note layout is just a
format, Obsidian itself is not required.
One caution for restricted machines: exports contain raw prompts, paths and
commands, which may include secrets. Keep the export folder private, define a
retention rule, and run
devin-redact before sharing an
export.
Platform support
Tested on Windows and Linux (windows-latest + ubuntu-latest in CI).
The CLI session database is auto-detected: %APPDATA%/devin/cli/sessions.db
on Windows and $XDG_DATA_HOME/devin/cli/sessions.db on Linux (default
~/.local/share/devin/cli/sessions.db). A legacy ~/.config/devin location
is also checked. macOS uses ~/Library/Application Support/devin/. Override
with --sessions-db (see Usage). The GUI state.vscdb is auto-detected
under <config>/User/globalStorage/state.vscdb (Devin/devin dir names);
override with --vscdb.
Incremental export from a hook (HI-2 — no daemon)
export --session-id ID exports a single session (unique prefix ok) and
merges its entry into the existing index instead of rebuilding it.
export --from-hook reads {"session_id": ...} from the stdin payload a
SessionEnd hook pipes in — fail-soft (no payload → exit 0, nothing
written). Register once via the hooks dispatcher:
python tools/hooks_dispatch.py register SessionEnd history-export \
"devin-history export --out ~/notes/devin-history --from-hook"
Each ended session then lands as a note automatically; a periodic full
export keeps the index complete.
Limitations
- Schema-gated. Only
sessions.dbschema v15–v17 is accepted; anything newer fails loudly rather than misreading (updatedevin-internals-specfirst). - Opaque payloads.
chat_messageandtool_call_*_jsoninner formats are undocumented and unstable — decoding is best-effort and tolerant, not contractual. - Inferred status. The DB has no final-state column; "completed" /
"interrupted" / "abandoned" are heuristics (see
docs/SPEC.md§4). - No billing. Token/cost data is not stored locally; only
num_tokens_preceding(context size) exists. - GUI sessions are metadata-only.
export-guiexports the session↔workspace bindings kept instate.vscdb(slug, label, folders, timestamps) — the GUI stores no transcript locally. GUI transcripts underUser/acp-messages/*.db, session locks and log correlation are planned for M2. - Read-only by design — the tool never writes to Devin's stores.
Development
pip install -e ".[dev]"
pytest
Fixtures are generated at test time by devin_internals.fixtures (real v17
DDL, synthetic rows) — no binary fixtures are committed.
When to use this
- You want your Devin session history out of the app before sessions scroll away or are pruned — there is no built-in export button.
- You keep an Obsidian vault (or any Markdown folder) and want one note per
session plus an
index.md, idempotent across re-runs. - You need a lifetime audit: groupings by status, task type, project and period, plus anomaly detection (empty, orphan, long-running sessions).
- You want a deterministic, read-only export you can schedule — nothing is ever written back to Devin's stores.
When NOT to use this
- You need instant ranked search rather than a static export — use
devin-searchon top of the same database. - You need GUI session transcripts —
export-guiexports the metadata bindings instate.vscdb; theacp-messages/*.dbtranscript stores are M2. - Your
sessions.dbschema is newer than v17 — the tool refuses loudly instead of misreading it; updatedevin-internals-specfirst.
FAQ
What is devin-history? A CLI that exports Devin's local sessions.db
into Obsidian-ready Markdown notes, a JSON dump, or an audit report. It
auto-detects the database on Windows, Linux and macOS and never writes to
Devin's stores.
Is it safe to re-run the export? Yes. Each note embeds the session's
last_activity marker, so unchanged sessions are skipped on re-runs.
--all forces a rewrite and --dry-run previews without writing.
Does it send my session data anywhere? No. Everything happens on your
machine: it reads the local database and writes files to a folder you
choose. Note that exports contain raw prompts and paths — keep the output
folder private or run devin-redact before sharing.
Why does it refuse to read my database? Because the schema version is outside the supported v15–v17 range. The store has had 17 migrations already; devin-history fails loudly on unknown versions rather than silently misparsing your history.
License
MIT — see LICENSE.
Metadata
Release files for devin-history 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| devin_history-0.1.0.tar.gz | 35.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| devin_history-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 63.1 kB
Release files / devin_history-0.1.0.tar.gz
| Download URL | devin_history-0.1.0.tar.gz |
|---|---|
| Size | 35.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
20ea332f91a33862e5e097eecf7ef1c2fb58965996f6c46673ec6bd821bc72e7
|
|
BLAKE2b-256 checksum How to use checksums |
31f75f69710d10c42b6c8010c2c25fa90a0afc7dda7f044e68cebe1938497690
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.2
|
Release files / devin_history-0.1.0-py3-none-any.whl
| Download URL | devin_history-0.1.0-py3-none-any.whl |
|---|---|
| Size | 27.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
25669ad3d60aa40115a763a51d16fba5260979b7e4bccfa77b4318d380c59080
|
|
BLAKE2b-256 checksum How to use checksums |
7b7a416f0425b85c3f304e401353d1456d2c4ba4361c6c458752d014d274974d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.2
|