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.
Files changed (29) hide show
  1. devin_history-0.1.0/LICENSE +21 -0
  2. devin_history-0.1.0/PKG-INFO +247 -0
  3. devin_history-0.1.0/README.md +233 -0
  4. devin_history-0.1.0/pyproject.toml +27 -0
  5. devin_history-0.1.0/setup.cfg +4 -0
  6. devin_history-0.1.0/src/devin_history/__init__.py +1 -0
  7. devin_history-0.1.0/src/devin_history/audit.py +256 -0
  8. devin_history-0.1.0/src/devin_history/cli.py +240 -0
  9. devin_history-0.1.0/src/devin_history/export.py +306 -0
  10. devin_history-0.1.0/src/devin_history/format.py +490 -0
  11. devin_history-0.1.0/src/devin_history/identity.py +126 -0
  12. devin_history-0.1.0/src/devin_history/messages.py +93 -0
  13. devin_history-0.1.0/src/devin_history/paths.py +92 -0
  14. devin_history-0.1.0/src/devin_history/times.py +34 -0
  15. devin_history-0.1.0/src/devin_history/vscdb.py +124 -0
  16. devin_history-0.1.0/src/devin_history.egg-info/PKG-INFO +247 -0
  17. devin_history-0.1.0/src/devin_history.egg-info/SOURCES.txt +27 -0
  18. devin_history-0.1.0/src/devin_history.egg-info/dependency_links.txt +1 -0
  19. devin_history-0.1.0/src/devin_history.egg-info/entry_points.txt +2 -0
  20. devin_history-0.1.0/src/devin_history.egg-info/requires.txt +4 -0
  21. devin_history-0.1.0/src/devin_history.egg-info/top_level.txt +1 -0
  22. devin_history-0.1.0/tests/test_audit.py +130 -0
  23. devin_history-0.1.0/tests/test_cli.py +109 -0
  24. devin_history-0.1.0/tests/test_export.py +138 -0
  25. devin_history-0.1.0/tests/test_export_gui.py +274 -0
  26. devin_history-0.1.0/tests/test_helpers.py +78 -0
  27. devin_history-0.1.0/tests/test_offline_core.py +70 -0
  28. devin_history-0.1.0/tests/test_paths.py +31 -0
  29. 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,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"