devin-history 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- devin_history-0.1.0/LICENSE +21 -0
- devin_history-0.1.0/PKG-INFO +247 -0
- devin_history-0.1.0/README.md +233 -0
- devin_history-0.1.0/pyproject.toml +27 -0
- devin_history-0.1.0/setup.cfg +4 -0
- devin_history-0.1.0/src/devin_history/__init__.py +1 -0
- devin_history-0.1.0/src/devin_history/audit.py +256 -0
- devin_history-0.1.0/src/devin_history/cli.py +240 -0
- devin_history-0.1.0/src/devin_history/export.py +306 -0
- devin_history-0.1.0/src/devin_history/format.py +490 -0
- devin_history-0.1.0/src/devin_history/identity.py +126 -0
- devin_history-0.1.0/src/devin_history/messages.py +93 -0
- devin_history-0.1.0/src/devin_history/paths.py +92 -0
- devin_history-0.1.0/src/devin_history/times.py +34 -0
- devin_history-0.1.0/src/devin_history/vscdb.py +124 -0
- devin_history-0.1.0/src/devin_history.egg-info/PKG-INFO +247 -0
- devin_history-0.1.0/src/devin_history.egg-info/SOURCES.txt +27 -0
- devin_history-0.1.0/src/devin_history.egg-info/dependency_links.txt +1 -0
- devin_history-0.1.0/src/devin_history.egg-info/entry_points.txt +2 -0
- devin_history-0.1.0/src/devin_history.egg-info/requires.txt +4 -0
- devin_history-0.1.0/src/devin_history.egg-info/top_level.txt +1 -0
- devin_history-0.1.0/tests/test_audit.py +130 -0
- devin_history-0.1.0/tests/test_cli.py +109 -0
- devin_history-0.1.0/tests/test_export.py +138 -0
- devin_history-0.1.0/tests/test_export_gui.py +274 -0
- devin_history-0.1.0/tests/test_helpers.py +78 -0
- devin_history-0.1.0/tests/test_offline_core.py +70 -0
- devin_history-0.1.0/tests/test_paths.py +31 -0
- devin_history-0.1.0/tests/test_smoke.py +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Icaro0310
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: devin-history
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Export, audit and search Devin Desktop session history — Obsidian-ready markdown, JSON and SQLite-aware.
|
|
5
|
+
Author: Icaro0310
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: devin-internals-spec<0.4.0,>=0.3.0
|
|
11
|
+
Provides-Extra: dev
|
|
12
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
13
|
+
Dynamic: license-file
|
|
14
|
+
|
|
15
|
+
<div align="center">
|
|
16
|
+
|
|
17
|
+
<img src="assets/banner.svg" alt="devin-history" width="100%"/>
|
|
18
|
+
|
|
19
|
+
<a href="https://github.com/Icaro0310/devin-history/actions/workflows/tests.yml"><img src="https://github.com/Icaro0310/devin-history/actions/workflows/tests.yml/badge.svg" alt="tests"/></a>
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
<a href="https://github.com/Icaro0310/devin-history/actions/workflows/ci.yml"><img src="https://github.com/Icaro0310/devin-history/actions/workflows/ci.yml/badge.svg" alt="ci"/></a>
|
|
23
|
+
<a href="https://scorecard.dev/viewer/?uri=github.com/Icaro0310/devin-history"><img src="https://api.scorecard.dev/projects/github.com/Icaro0310/devin-history/badge" alt="OpenSSF Scorecard"/></a>
|
|
24
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="License: MIT"/></a>
|
|
25
|
+
<a href="https://www.python.org/"><img src="https://img.shields.io/badge/python-3.10%2B-blue" alt="Python 3.10+"/></a>
|
|
26
|
+
<a href="https://github.com/Icaro0310/devin-history"><img src="https://img.shields.io/github/stars/Icaro0310/devin-history" alt="GitHub stars"/></a>
|
|
27
|
+
<a href="https://github.com/Icaro0310/devin-history/commits/main"><img src="https://img.shields.io/github/last-commit/Icaro0310/devin-history" alt="Last commit"/></a>
|
|
28
|
+
<a href="https://github.com/Icaro0310/awesome-devin"><img src="https://img.shields.io/badge/part%20of-devin--*-ecosystem-7c3aed" alt="devin-* ecosystem"/></a>
|
|
29
|
+
<a href="https://github.com/Icaro0310/devin-history/issues"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen" alt="PRs welcome"/></a>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
# devin-history
|
|
33
|
+
|
|
34
|
+
> **Unofficial community project.** Not affiliated with, endorsed by, or
|
|
35
|
+
> sponsored by Cognition AI. "Devin" is a trademark of Cognition AI.
|
|
36
|
+
|
|
37
|
+
**[Linux](README.linux.md)** · **[Personal Windows](README.windows.md)** · **[Corporate Windows](README.corporate-windows.md)**
|
|
38
|
+
|
|
39
|
+
Part of the [awesome-devin](https://github.com/Icaro0310/awesome-devin) ecosystem: the curated hub for the devin-* tools.
|
|
40
|
+
|
|
41
|
+
Export and audit Devin Desktop session history — turns the local
|
|
42
|
+
`sessions.db` into Obsidian-ready Markdown notes, a searchable JSON dump,
|
|
43
|
+
and an audit report. GUI session metadata (`state.vscdb`) exports as
|
|
44
|
+
metadata notes too.
|
|
45
|
+
|
|
46
|
+
## The problem
|
|
47
|
+
|
|
48
|
+
Devin Desktop keeps your session history in a local SQLite database
|
|
49
|
+
(`%APPDATA%/devin/cli/sessions.db` on Windows, or
|
|
50
|
+
`$XDG_DATA_HOME/devin/cli/sessions.db` on Linux; default
|
|
51
|
+
`~/.local/share/devin/cli/sessions.db`) — and nowhere else. There is no export
|
|
52
|
+
button: once a session scrolls out of the UI (or is pruned by the app), the
|
|
53
|
+
prompts, replies and tool calls are effectively gone. You can't search old
|
|
54
|
+
sessions, can't answer "what did I ask Devin to do last month", and can't
|
|
55
|
+
audit how the agent has been used across projects.
|
|
56
|
+
|
|
57
|
+
## Prior art
|
|
58
|
+
|
|
59
|
+
- **tokmesh** and **UniSessions** document/parse `sessions.db`; the schema
|
|
60
|
+
itself is tracked by [`devin-internals-spec`](https://github.com/Icaro0310/devin-internals-spec).
|
|
61
|
+
- This project ports two proven scripts that lived in the orchestrator
|
|
62
|
+
workspace (`legacy/`): `devin-history-export.py` (DB → Obsidian notes) and
|
|
63
|
+
`audit_sessions.py` (lifetime audit → CSV + report). They are rewritten
|
|
64
|
+
as library modules — same logic, real tests.
|
|
65
|
+
- You can also just run `sqlite3` queries by hand — but then you guess the
|
|
66
|
+
schema on every Devin update.
|
|
67
|
+
|
|
68
|
+
## What makes it Devin-native
|
|
69
|
+
|
|
70
|
+
It understands Devin's real stores instead of raw-SQL guessing: it opens
|
|
71
|
+
`sessions.db` through `devin-internals-spec`'s typed parsers and **refuses
|
|
72
|
+
loudly** when the schema version is one it has never seen (the store has
|
|
73
|
+
had 17 migrations already). The export knows about `hidden` sessions,
|
|
74
|
+
interrupted threads (last node = user), `tool_call_state` failures and
|
|
75
|
+
epoch-millisecond timestamps — details a generic SQLite dump misses.
|
|
76
|
+
|
|
77
|
+
## Install
|
|
78
|
+
|
|
79
|
+
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.
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pipx install "devin-history @ git+https://github.com/Icaro0310/devin-history.git"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
(PyPI release is on the M2 roadmap; Python ≥ 3.10 required.)
|
|
86
|
+
|
|
87
|
+
## Usage
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# quick session table (auto-detects %APPDATA%/devin/cli/sessions.db)
|
|
91
|
+
devin-history list
|
|
92
|
+
|
|
93
|
+
# one Obsidian note per session + index.md — safe to re-run (incremental)
|
|
94
|
+
devin-history export --out ~/ObsidianVault/Sessions
|
|
95
|
+
|
|
96
|
+
# searchable JSON dump instead of Markdown
|
|
97
|
+
devin-history export --out dump/ --format json
|
|
98
|
+
|
|
99
|
+
# audit: status/type/project/period groupings + anomalies, optional CSV
|
|
100
|
+
devin-history audit --csv audit.csv
|
|
101
|
+
|
|
102
|
+
# GUI sessions: metadata notes (slug, workspace, folders, lastUpdated) +
|
|
103
|
+
# index.json — the GUI keeps no local transcript, so metadata is all there is
|
|
104
|
+
devin-history export-gui --out ~/ObsidianVault/Sessions/gui
|
|
105
|
+
|
|
106
|
+
# everything has --json; point at a specific DB with --sessions-db/--vscdb
|
|
107
|
+
devin-history audit --sessions-db path/to/sessions.db --json
|
|
108
|
+
devin-history export-gui --vscdb path/to/state.vscdb --out gui-notes/
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
No Devin installed? Try it on a synthetic fixture (stdlib-only, no Devin
|
|
112
|
+
data involved):
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
pipx install "devin-internals-spec==0.3.0"
|
|
116
|
+
devin-inspect make-fixture /tmp/fx
|
|
117
|
+
devin-history export --sessions-db /tmp/fx/cli/sessions.db --out /tmp/notes
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Notes are idempotent: each file embeds the session's `last_activity`
|
|
121
|
+
marker, so re-runs skip unchanged sessions (`--all` forces a rewrite,
|
|
122
|
+
`--dry-run` previews). The `index.md`/`index.json` at the root carries a
|
|
123
|
+
stats block — total sessions, date span, per-project and user/assistant/tool
|
|
124
|
+
message totals — alongside the grouped links.
|
|
125
|
+
|
|
126
|
+
`export-gui` reads the Electron `state.vscdb` store (auto-detected under
|
|
127
|
+
`User/globalStorage/` of the Devin config dir, override with `--vscdb`)
|
|
128
|
+
and writes one note per `windsurfSpace.sessionWorkspace/*` binding: slug,
|
|
129
|
+
label, backend, workspaceId, folders, `lastUpdated`, and `lastAccessed`
|
|
130
|
+
when derivable via `windsurfSpace.resourceToSpace` + `windsurfSpace.metadata`.
|
|
131
|
+
It is read-only on `state.vscdb`, embeds the same provenance
|
|
132
|
+
(`machine_id`/`profile`), and writes an `index.json` index.
|
|
133
|
+
|
|
134
|
+
## Works with Devin alone (Devin-only mode)
|
|
135
|
+
|
|
136
|
+
Everything devin-history does happens on your machine: it reads
|
|
137
|
+
`sessions.db` and writes Markdown/JSON exports to a folder you choose. No
|
|
138
|
+
network, no external service — the Obsidian-style note layout is just a
|
|
139
|
+
format, Obsidian itself is not required.
|
|
140
|
+
|
|
141
|
+
One caution for restricted machines: exports contain raw prompts, paths and
|
|
142
|
+
commands, which may include secrets. Keep the export folder private, define a
|
|
143
|
+
retention rule, and run
|
|
144
|
+
[`devin-redact`](https://github.com/Icaro0310/devin-redact) before sharing an
|
|
145
|
+
export.
|
|
146
|
+
|
|
147
|
+
## Platform support
|
|
148
|
+
|
|
149
|
+
Tested on **Windows and Linux** (`windows-latest` + `ubuntu-latest` in CI).
|
|
150
|
+
The CLI session database is auto-detected: `%APPDATA%/devin/cli/sessions.db`
|
|
151
|
+
on Windows and `$XDG_DATA_HOME/devin/cli/sessions.db` on Linux (default
|
|
152
|
+
`~/.local/share/devin/cli/sessions.db`). A legacy `~/.config/devin` location
|
|
153
|
+
is also checked. macOS uses `~/Library/Application Support/devin/`. Override
|
|
154
|
+
with `--sessions-db` (see Usage). The GUI `state.vscdb` is auto-detected
|
|
155
|
+
under `<config>/User/globalStorage/state.vscdb` (`Devin`/`devin` dir names);
|
|
156
|
+
override with `--vscdb`.
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
### Incremental export from a hook (HI-2 — no daemon)
|
|
160
|
+
|
|
161
|
+
`export --session-id ID` exports a single session (unique prefix ok) and
|
|
162
|
+
merges its entry into the existing index instead of rebuilding it.
|
|
163
|
+
`export --from-hook` reads `{"session_id": ...}` from the stdin payload a
|
|
164
|
+
SessionEnd hook pipes in — fail-soft (no payload → exit 0, nothing
|
|
165
|
+
written). Register once via the hooks dispatcher:
|
|
166
|
+
|
|
167
|
+
python tools/hooks_dispatch.py register SessionEnd history-export \
|
|
168
|
+
"devin-history export --out ~/notes/devin-history --from-hook"
|
|
169
|
+
|
|
170
|
+
Each ended session then lands as a note automatically; a periodic full
|
|
171
|
+
`export` keeps the index complete.
|
|
172
|
+
|
|
173
|
+
## Limitations
|
|
174
|
+
|
|
175
|
+
- **Schema-gated.** Only `sessions.db` schema v15–v17 is accepted; anything
|
|
176
|
+
newer fails loudly rather than misreading (update `devin-internals-spec`
|
|
177
|
+
first).
|
|
178
|
+
- **Opaque payloads.** `chat_message` and `tool_call_*_json` inner formats
|
|
179
|
+
are undocumented and unstable — decoding is best-effort and tolerant, not
|
|
180
|
+
contractual.
|
|
181
|
+
- **Inferred status.** The DB has no final-state column; "completed" /
|
|
182
|
+
"interrupted" / "abandoned" are heuristics (see `docs/SPEC.md` §4).
|
|
183
|
+
- **No billing.** Token/cost data is not stored locally; only
|
|
184
|
+
`num_tokens_preceding` (context size) exists.
|
|
185
|
+
- **GUI sessions are metadata-only.** `export-gui` exports the
|
|
186
|
+
session↔workspace bindings kept in `state.vscdb` (slug, label, folders,
|
|
187
|
+
timestamps) — the GUI stores no transcript locally. GUI transcripts under
|
|
188
|
+
`User/acp-messages/*.db`, session locks and log correlation are planned
|
|
189
|
+
for M2.
|
|
190
|
+
- **Read-only by design** — the tool never writes to Devin's stores.
|
|
191
|
+
|
|
192
|
+
## Development
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
pip install -e ".[dev]"
|
|
196
|
+
pytest
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Fixtures are generated at test time by `devin_internals.fixtures` (real v17
|
|
200
|
+
DDL, synthetic rows) — no binary fixtures are committed.
|
|
201
|
+
|
|
202
|
+
## When to use this
|
|
203
|
+
|
|
204
|
+
- You want your Devin session history out of the app before sessions scroll
|
|
205
|
+
away or are pruned — there is no built-in export button.
|
|
206
|
+
- You keep an Obsidian vault (or any Markdown folder) and want one note per
|
|
207
|
+
session plus an `index.md`, idempotent across re-runs.
|
|
208
|
+
- You need a lifetime audit: groupings by status, task type, project and
|
|
209
|
+
period, plus anomaly detection (empty, orphan, long-running sessions).
|
|
210
|
+
- You want a deterministic, read-only export you can schedule — nothing is
|
|
211
|
+
ever written back to Devin's stores.
|
|
212
|
+
|
|
213
|
+
## When NOT to use this
|
|
214
|
+
|
|
215
|
+
- You need instant ranked search rather than a static export — use
|
|
216
|
+
[`devin-search`](https://github.com/Icaro0310/devin-search) on top of the
|
|
217
|
+
same database.
|
|
218
|
+
- You need GUI session *transcripts* — `export-gui` exports the metadata
|
|
219
|
+
bindings in `state.vscdb`; the `acp-messages/*.db` transcript stores are
|
|
220
|
+
M2.
|
|
221
|
+
- Your `sessions.db` schema is newer than v17 — the tool refuses loudly
|
|
222
|
+
instead of misreading it; update `devin-internals-spec` first.
|
|
223
|
+
|
|
224
|
+
## FAQ
|
|
225
|
+
|
|
226
|
+
**What is devin-history?** A CLI that exports Devin's local `sessions.db`
|
|
227
|
+
into Obsidian-ready Markdown notes, a JSON dump, or an audit report. It
|
|
228
|
+
auto-detects the database on Windows, Linux and macOS and never writes to
|
|
229
|
+
Devin's stores.
|
|
230
|
+
|
|
231
|
+
**Is it safe to re-run the export?** Yes. Each note embeds the session's
|
|
232
|
+
`last_activity` marker, so unchanged sessions are skipped on re-runs.
|
|
233
|
+
`--all` forces a rewrite and `--dry-run` previews without writing.
|
|
234
|
+
|
|
235
|
+
**Does it send my session data anywhere?** No. Everything happens on your
|
|
236
|
+
machine: it reads the local database and writes files to a folder you
|
|
237
|
+
choose. Note that exports contain raw prompts and paths — keep the output
|
|
238
|
+
folder private or run `devin-redact` before sharing.
|
|
239
|
+
|
|
240
|
+
**Why does it refuse to read my database?** Because the schema version is
|
|
241
|
+
outside the supported v15–v17 range. The store has had 17 migrations
|
|
242
|
+
already; devin-history fails loudly on unknown versions rather than
|
|
243
|
+
silently misparsing your history.
|
|
244
|
+
|
|
245
|
+
## License
|
|
246
|
+
|
|
247
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<img src="assets/banner.svg" alt="devin-history" width="100%"/>
|
|
4
|
+
|
|
5
|
+
<a href="https://github.com/Icaro0310/devin-history/actions/workflows/tests.yml"><img src="https://github.com/Icaro0310/devin-history/actions/workflows/tests.yml/badge.svg" alt="tests"/></a>
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
<a href="https://github.com/Icaro0310/devin-history/actions/workflows/ci.yml"><img src="https://github.com/Icaro0310/devin-history/actions/workflows/ci.yml/badge.svg" alt="ci"/></a>
|
|
9
|
+
<a href="https://scorecard.dev/viewer/?uri=github.com/Icaro0310/devin-history"><img src="https://api.scorecard.dev/projects/github.com/Icaro0310/devin-history/badge" alt="OpenSSF Scorecard"/></a>
|
|
10
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="License: MIT"/></a>
|
|
11
|
+
<a href="https://www.python.org/"><img src="https://img.shields.io/badge/python-3.10%2B-blue" alt="Python 3.10+"/></a>
|
|
12
|
+
<a href="https://github.com/Icaro0310/devin-history"><img src="https://img.shields.io/github/stars/Icaro0310/devin-history" alt="GitHub stars"/></a>
|
|
13
|
+
<a href="https://github.com/Icaro0310/devin-history/commits/main"><img src="https://img.shields.io/github/last-commit/Icaro0310/devin-history" alt="Last commit"/></a>
|
|
14
|
+
<a href="https://github.com/Icaro0310/awesome-devin"><img src="https://img.shields.io/badge/part%20of-devin--*-ecosystem-7c3aed" alt="devin-* ecosystem"/></a>
|
|
15
|
+
<a href="https://github.com/Icaro0310/devin-history/issues"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen" alt="PRs welcome"/></a>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
# devin-history
|
|
19
|
+
|
|
20
|
+
> **Unofficial community project.** Not affiliated with, endorsed by, or
|
|
21
|
+
> sponsored by Cognition AI. "Devin" is a trademark of Cognition AI.
|
|
22
|
+
|
|
23
|
+
**[Linux](README.linux.md)** · **[Personal Windows](README.windows.md)** · **[Corporate Windows](README.corporate-windows.md)**
|
|
24
|
+
|
|
25
|
+
Part of the [awesome-devin](https://github.com/Icaro0310/awesome-devin) ecosystem: the curated hub for the devin-* tools.
|
|
26
|
+
|
|
27
|
+
Export and audit Devin Desktop session history — turns the local
|
|
28
|
+
`sessions.db` into Obsidian-ready Markdown notes, a searchable JSON dump,
|
|
29
|
+
and an audit report. GUI session metadata (`state.vscdb`) exports as
|
|
30
|
+
metadata notes too.
|
|
31
|
+
|
|
32
|
+
## The problem
|
|
33
|
+
|
|
34
|
+
Devin Desktop keeps your session history in a local SQLite database
|
|
35
|
+
(`%APPDATA%/devin/cli/sessions.db` on Windows, or
|
|
36
|
+
`$XDG_DATA_HOME/devin/cli/sessions.db` on Linux; default
|
|
37
|
+
`~/.local/share/devin/cli/sessions.db`) — and nowhere else. There is no export
|
|
38
|
+
button: once a session scrolls out of the UI (or is pruned by the app), the
|
|
39
|
+
prompts, replies and tool calls are effectively gone. You can't search old
|
|
40
|
+
sessions, can't answer "what did I ask Devin to do last month", and can't
|
|
41
|
+
audit how the agent has been used across projects.
|
|
42
|
+
|
|
43
|
+
## Prior art
|
|
44
|
+
|
|
45
|
+
- **tokmesh** and **UniSessions** document/parse `sessions.db`; the schema
|
|
46
|
+
itself is tracked by [`devin-internals-spec`](https://github.com/Icaro0310/devin-internals-spec).
|
|
47
|
+
- This project ports two proven scripts that lived in the orchestrator
|
|
48
|
+
workspace (`legacy/`): `devin-history-export.py` (DB → Obsidian notes) and
|
|
49
|
+
`audit_sessions.py` (lifetime audit → CSV + report). They are rewritten
|
|
50
|
+
as library modules — same logic, real tests.
|
|
51
|
+
- You can also just run `sqlite3` queries by hand — but then you guess the
|
|
52
|
+
schema on every Devin update.
|
|
53
|
+
|
|
54
|
+
## What makes it Devin-native
|
|
55
|
+
|
|
56
|
+
It understands Devin's real stores instead of raw-SQL guessing: it opens
|
|
57
|
+
`sessions.db` through `devin-internals-spec`'s typed parsers and **refuses
|
|
58
|
+
loudly** when the schema version is one it has never seen (the store has
|
|
59
|
+
had 17 migrations already). The export knows about `hidden` sessions,
|
|
60
|
+
interrupted threads (last node = user), `tool_call_state` failures and
|
|
61
|
+
epoch-millisecond timestamps — details a generic SQLite dump misses.
|
|
62
|
+
|
|
63
|
+
## Install
|
|
64
|
+
|
|
65
|
+
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.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pipx install "devin-history @ git+https://github.com/Icaro0310/devin-history.git"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
(PyPI release is on the M2 roadmap; Python ≥ 3.10 required.)
|
|
72
|
+
|
|
73
|
+
## Usage
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# quick session table (auto-detects %APPDATA%/devin/cli/sessions.db)
|
|
77
|
+
devin-history list
|
|
78
|
+
|
|
79
|
+
# one Obsidian note per session + index.md — safe to re-run (incremental)
|
|
80
|
+
devin-history export --out ~/ObsidianVault/Sessions
|
|
81
|
+
|
|
82
|
+
# searchable JSON dump instead of Markdown
|
|
83
|
+
devin-history export --out dump/ --format json
|
|
84
|
+
|
|
85
|
+
# audit: status/type/project/period groupings + anomalies, optional CSV
|
|
86
|
+
devin-history audit --csv audit.csv
|
|
87
|
+
|
|
88
|
+
# GUI sessions: metadata notes (slug, workspace, folders, lastUpdated) +
|
|
89
|
+
# index.json — the GUI keeps no local transcript, so metadata is all there is
|
|
90
|
+
devin-history export-gui --out ~/ObsidianVault/Sessions/gui
|
|
91
|
+
|
|
92
|
+
# everything has --json; point at a specific DB with --sessions-db/--vscdb
|
|
93
|
+
devin-history audit --sessions-db path/to/sessions.db --json
|
|
94
|
+
devin-history export-gui --vscdb path/to/state.vscdb --out gui-notes/
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
No Devin installed? Try it on a synthetic fixture (stdlib-only, no Devin
|
|
98
|
+
data involved):
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
pipx install "devin-internals-spec==0.3.0"
|
|
102
|
+
devin-inspect make-fixture /tmp/fx
|
|
103
|
+
devin-history export --sessions-db /tmp/fx/cli/sessions.db --out /tmp/notes
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Notes are idempotent: each file embeds the session's `last_activity`
|
|
107
|
+
marker, so re-runs skip unchanged sessions (`--all` forces a rewrite,
|
|
108
|
+
`--dry-run` previews). The `index.md`/`index.json` at the root carries a
|
|
109
|
+
stats block — total sessions, date span, per-project and user/assistant/tool
|
|
110
|
+
message totals — alongside the grouped links.
|
|
111
|
+
|
|
112
|
+
`export-gui` reads the Electron `state.vscdb` store (auto-detected under
|
|
113
|
+
`User/globalStorage/` of the Devin config dir, override with `--vscdb`)
|
|
114
|
+
and writes one note per `windsurfSpace.sessionWorkspace/*` binding: slug,
|
|
115
|
+
label, backend, workspaceId, folders, `lastUpdated`, and `lastAccessed`
|
|
116
|
+
when derivable via `windsurfSpace.resourceToSpace` + `windsurfSpace.metadata`.
|
|
117
|
+
It is read-only on `state.vscdb`, embeds the same provenance
|
|
118
|
+
(`machine_id`/`profile`), and writes an `index.json` index.
|
|
119
|
+
|
|
120
|
+
## Works with Devin alone (Devin-only mode)
|
|
121
|
+
|
|
122
|
+
Everything devin-history does happens on your machine: it reads
|
|
123
|
+
`sessions.db` and writes Markdown/JSON exports to a folder you choose. No
|
|
124
|
+
network, no external service — the Obsidian-style note layout is just a
|
|
125
|
+
format, Obsidian itself is not required.
|
|
126
|
+
|
|
127
|
+
One caution for restricted machines: exports contain raw prompts, paths and
|
|
128
|
+
commands, which may include secrets. Keep the export folder private, define a
|
|
129
|
+
retention rule, and run
|
|
130
|
+
[`devin-redact`](https://github.com/Icaro0310/devin-redact) before sharing an
|
|
131
|
+
export.
|
|
132
|
+
|
|
133
|
+
## Platform support
|
|
134
|
+
|
|
135
|
+
Tested on **Windows and Linux** (`windows-latest` + `ubuntu-latest` in CI).
|
|
136
|
+
The CLI session database is auto-detected: `%APPDATA%/devin/cli/sessions.db`
|
|
137
|
+
on Windows and `$XDG_DATA_HOME/devin/cli/sessions.db` on Linux (default
|
|
138
|
+
`~/.local/share/devin/cli/sessions.db`). A legacy `~/.config/devin` location
|
|
139
|
+
is also checked. macOS uses `~/Library/Application Support/devin/`. Override
|
|
140
|
+
with `--sessions-db` (see Usage). The GUI `state.vscdb` is auto-detected
|
|
141
|
+
under `<config>/User/globalStorage/state.vscdb` (`Devin`/`devin` dir names);
|
|
142
|
+
override with `--vscdb`.
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
### Incremental export from a hook (HI-2 — no daemon)
|
|
146
|
+
|
|
147
|
+
`export --session-id ID` exports a single session (unique prefix ok) and
|
|
148
|
+
merges its entry into the existing index instead of rebuilding it.
|
|
149
|
+
`export --from-hook` reads `{"session_id": ...}` from the stdin payload a
|
|
150
|
+
SessionEnd hook pipes in — fail-soft (no payload → exit 0, nothing
|
|
151
|
+
written). Register once via the hooks dispatcher:
|
|
152
|
+
|
|
153
|
+
python tools/hooks_dispatch.py register SessionEnd history-export \
|
|
154
|
+
"devin-history export --out ~/notes/devin-history --from-hook"
|
|
155
|
+
|
|
156
|
+
Each ended session then lands as a note automatically; a periodic full
|
|
157
|
+
`export` keeps the index complete.
|
|
158
|
+
|
|
159
|
+
## Limitations
|
|
160
|
+
|
|
161
|
+
- **Schema-gated.** Only `sessions.db` schema v15–v17 is accepted; anything
|
|
162
|
+
newer fails loudly rather than misreading (update `devin-internals-spec`
|
|
163
|
+
first).
|
|
164
|
+
- **Opaque payloads.** `chat_message` and `tool_call_*_json` inner formats
|
|
165
|
+
are undocumented and unstable — decoding is best-effort and tolerant, not
|
|
166
|
+
contractual.
|
|
167
|
+
- **Inferred status.** The DB has no final-state column; "completed" /
|
|
168
|
+
"interrupted" / "abandoned" are heuristics (see `docs/SPEC.md` §4).
|
|
169
|
+
- **No billing.** Token/cost data is not stored locally; only
|
|
170
|
+
`num_tokens_preceding` (context size) exists.
|
|
171
|
+
- **GUI sessions are metadata-only.** `export-gui` exports the
|
|
172
|
+
session↔workspace bindings kept in `state.vscdb` (slug, label, folders,
|
|
173
|
+
timestamps) — the GUI stores no transcript locally. GUI transcripts under
|
|
174
|
+
`User/acp-messages/*.db`, session locks and log correlation are planned
|
|
175
|
+
for M2.
|
|
176
|
+
- **Read-only by design** — the tool never writes to Devin's stores.
|
|
177
|
+
|
|
178
|
+
## Development
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
pip install -e ".[dev]"
|
|
182
|
+
pytest
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Fixtures are generated at test time by `devin_internals.fixtures` (real v17
|
|
186
|
+
DDL, synthetic rows) — no binary fixtures are committed.
|
|
187
|
+
|
|
188
|
+
## When to use this
|
|
189
|
+
|
|
190
|
+
- You want your Devin session history out of the app before sessions scroll
|
|
191
|
+
away or are pruned — there is no built-in export button.
|
|
192
|
+
- You keep an Obsidian vault (or any Markdown folder) and want one note per
|
|
193
|
+
session plus an `index.md`, idempotent across re-runs.
|
|
194
|
+
- You need a lifetime audit: groupings by status, task type, project and
|
|
195
|
+
period, plus anomaly detection (empty, orphan, long-running sessions).
|
|
196
|
+
- You want a deterministic, read-only export you can schedule — nothing is
|
|
197
|
+
ever written back to Devin's stores.
|
|
198
|
+
|
|
199
|
+
## When NOT to use this
|
|
200
|
+
|
|
201
|
+
- You need instant ranked search rather than a static export — use
|
|
202
|
+
[`devin-search`](https://github.com/Icaro0310/devin-search) on top of the
|
|
203
|
+
same database.
|
|
204
|
+
- You need GUI session *transcripts* — `export-gui` exports the metadata
|
|
205
|
+
bindings in `state.vscdb`; the `acp-messages/*.db` transcript stores are
|
|
206
|
+
M2.
|
|
207
|
+
- Your `sessions.db` schema is newer than v17 — the tool refuses loudly
|
|
208
|
+
instead of misreading it; update `devin-internals-spec` first.
|
|
209
|
+
|
|
210
|
+
## FAQ
|
|
211
|
+
|
|
212
|
+
**What is devin-history?** A CLI that exports Devin's local `sessions.db`
|
|
213
|
+
into Obsidian-ready Markdown notes, a JSON dump, or an audit report. It
|
|
214
|
+
auto-detects the database on Windows, Linux and macOS and never writes to
|
|
215
|
+
Devin's stores.
|
|
216
|
+
|
|
217
|
+
**Is it safe to re-run the export?** Yes. Each note embeds the session's
|
|
218
|
+
`last_activity` marker, so unchanged sessions are skipped on re-runs.
|
|
219
|
+
`--all` forces a rewrite and `--dry-run` previews without writing.
|
|
220
|
+
|
|
221
|
+
**Does it send my session data anywhere?** No. Everything happens on your
|
|
222
|
+
machine: it reads the local database and writes files to a folder you
|
|
223
|
+
choose. Note that exports contain raw prompts and paths — keep the output
|
|
224
|
+
folder private or run `devin-redact` before sharing.
|
|
225
|
+
|
|
226
|
+
**Why does it refuse to read my database?** Because the schema version is
|
|
227
|
+
outside the supported v15–v17 range. The store has had 17 migrations
|
|
228
|
+
already; devin-history fails loudly on unknown versions rather than
|
|
229
|
+
silently misparsing your history.
|
|
230
|
+
|
|
231
|
+
## License
|
|
232
|
+
|
|
233
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "devin-history"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Export, audit and search Devin Desktop session history — Obsidian-ready markdown, JSON and SQLite-aware."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [{ name = "Icaro0310" }]
|
|
13
|
+
dependencies = [
|
|
14
|
+
"devin-internals-spec>=0.3.0,<0.4.0",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[project.optional-dependencies]
|
|
18
|
+
dev = ["pytest>=8"]
|
|
19
|
+
|
|
20
|
+
[project.scripts]
|
|
21
|
+
devin-history = "devin_history.cli:main"
|
|
22
|
+
|
|
23
|
+
[tool.setuptools.packages.find]
|
|
24
|
+
where = ["src"]
|
|
25
|
+
|
|
26
|
+
[tool.pytest.ini_options]
|
|
27
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|