Skip to main content
devin-history

tests

ci OpenSSF Scorecard License: MIT Python 3.10+ GitHub stars Last commit devin-* ecosystem PRs welcome

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 by devin-internals-spec.
  • This project ports two proven scripts that lived in the orchestrator workspace (legacy/): devin-history-export.py (DB → Obsidian notes) and audit_sessions.py (lifetime audit → CSV + report). They are rewritten as library modules — same logic, real tests.
  • You can also just run sqlite3 queries 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.db schema v15–v17 is accepted; anything newer fails loudly rather than misreading (update devin-internals-spec first).
  • Opaque payloads. chat_message and tool_call_*_json inner 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-gui exports the session↔workspace bindings kept in state.vscdb (slug, label, folders, timestamps) — the GUI stores no transcript locally. GUI transcripts under User/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-search on top of the same database.
  • You need GUI session transcripts — export-gui exports the metadata bindings in state.vscdb; the acp-messages/*.db transcript stores are M2.
  • Your sessions.db schema is newer than v17 — the tool refuses loudly instead of misreading it; update devin-internals-spec first.

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)

Source distribution for devin-history 0.1.0
File Size Uploaded
devin_history-0.1.0.tar.gz 35.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for devin-history 0.1.0
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page