This repository was absorbed into the
devin-explore monorepo.
The code now lives at packages/pm/ and the CLI is unchanged:
pip install devin-pm / uv tool install devin-pm still
installs the same package, now released from devin-explore.
# development moved
git clone https://github.com/Icaro0310/devin-explore
cd devin-explore/packages/pmThe repository is archived; open issues and PRs belong to devin-explore. History remains readable here for reference.
Original README (pre-archive)
Part of the DEVIN ecosystem
Track: Related · Nature: product
For: Operations, Maintainers
Interface: CLI / Registry
Path: Maintainers · step 2/3 — afterdevin-powerups, beforedevin-internals-spec
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.
A project manager over your Devin sessions — it reads sessions.db
(and optionally the GUI's state.vscdb), groups work per
repository/project, and generates status reports, milestones and a
machine-readable project registry.
Every Devin CLI session is recorded in a local sessions.db, but the app
gives you no project-level view of it. After a few weeks the database holds
a hundred sessions and you cannot answer the basic questions: which repos
did I actually work on? what is the state of project X? which milestones
are still open? The history is all there — it is just locked in a flat
session list with no grouping, no rollups, no output you can hand to a
report or another tool.
The orchestrator workspace proved the idea with a one-off audit script
(audit_sessions.py → sessions_report.md / sessions_summary.csv): a
lifetime audit of 100+ sessions grouped by working_directory. This
project turns that script into a maintained tool on top of
devin-internals-spec's
schema-gated SessionsStore parser — it does not re-implement the DB
reading or re-invent the grouping.
It's a project manager over your Devin sessions — it reads sessions.db
and gives you per-repo status, milestones and a registry.
- Side-by-side: Devin lists sessions but cannot group them per
repository, tag one as a milestone marker, or emit a project registry —
devin-pmdoes what the base tool cannot do at all. - No-Devin: remove Devin and there is no
sessions.db— the extra disappears entirely. - Safe by construction: parsing goes through
devin-internals-spec's schema-version gate, so a new Devin migration fails loudly instead of silently corrupting your rollup.
Python ≥ 3.10 required; install with uv (recommended) or pipx.
uv tool install devin-pmor with pipx (alternative):
pipx install devin-pmFor development:
pip install -e ".[dev]"
pytestdevin-pm status # per-project rollup table
devin-pm status --json # same, machine-readable
devin-pm status --vscdb # also merge GUI sessions (auto-detect)
devin-pm status --vscdb path/state.vscdb # pin the GUI store
devin-pm report --project my-repo # markdown status report
devin-pm report # global report, all projects
devin-pm report --project x --out x.md # write to file
devin-pm milestones --project my-repo # milestone list + done %
devin-pm registry --out registry.json # machine-readable registry
devin-pm verify # diff tracked projects vs hub registry
devin-pm verify --json # same, machine-readable--sessions-db PATH overrides the database location on every subcommand;
otherwise devin-pm auto-detects %APPDATA%/devin/cli/sessions.db
(DEVIN_PM_SESSIONS_DB env var also works). All reads are read-only.
The Desktop app stores session→workspace bindings in the Electron store
<config>/Devin/User/globalStorage/state.vscdb — keys of the form
windsurfSpace.sessionWorkspace/<backend>/<slug> holding JSON
{workspaceId, label, folders[], lastUpdated}. Passing --vscdb on any
subcommand merges them into the same project grouping (PM-1):
devin-pm status --vscdb # bare flag: auto-detect
devin-pm report --vscdb PATH # pin a specific state.vscdbGUI sessions have no transcript — they group by workspaceId (falling
back to the first folders[] entry, then label) and are marked
gui-sourced everywhere: status gui in reports, a GUI column in the
status table, a source column in session tables, and gui_sessions
counts in --json/registry output. A bare --vscdb with no store
found warns and continues with sessions.db only; an explicit missing
PATH exits 2. DEVIN_PM_STATE_VSCDB overrides auto-detection. The
store is opened mode=ro — read-only, always.
The same repo may be recorded as C:\Users\X\repo, /c/Users/X/repo
(MSYS/Git-Bash) or \\wsl.localhost\Ubuntu\home\u\repo (WSL UNC). Before
PM-3 that split one project into three groups. Grouping keys now fold:
C:\x ⇄ C:/x ⇄ /c/x ⇄ /cygdrive/c/x (drive-rooted paths are
case-folded — the Windows FS is case-insensitive), WSL UNC prefixes map
to the in-distro POSIX path, and separators/trailing slashes collapse.
Output keeps the original path; only the grouping key is normalized.
POSIX paths keep their case (/home/u/Foo ≠ /home/u/foo).
devin-pm verify cross-checks the projects pm tracks against the
authoritative ecosystem catalog in devin-powerups/registry.json:
devin-pm verify --registry ../devin-powerups/registry.json--registry defaults to ../devin-powerups/registry.json relative to the
current directory (then the checkout sibling of this package). The report
has three sections:
- in registry but unknown to pm — cataloged repos with no sessions on this machine (informational, never counts as drift);
- tracked by pm but missing from registry — projects with sessions that
the registry does not list. Entries count as drift only when they look
ecosystem-shaped (
devin-*name or a checkout under the hub's parent directory); others are tagged[non-ecosystem]; - field drift — for matched repos,
name/descriptionread from the checkout'spyproject.tomlandurlfrom the gitoriginremote vs the registry values. Unobservable fields (no pyproject, no remote) are skipped, never guessed.
--pm-registry FILE verifies a saved devin-pm registry --out document
instead of opening sessions.db. Exit code: 1 on drift, 0 when clean —
usable as a maintenance gate. Everything is local and read-only
(sessions.db, registry.json, pyproject.toml, .git/config).
Tag a session by naming its title milestone: <name> — that marks a
milestone in the session's project; archiving (hiding) the session marks
it done. Or list them manually in milestones.json at the project root:
{"milestones": [{"name": "M1 — core", "done": true}, "M2 — polish"]}File entries win over session-detected ones on name collision.
0 ok · 1 read/parse error (verify: also drift found) · 2 missing
db / unknown project / missing inputs.
devin-pm computes its reports straight from the local sessions.db
(%APPDATA%\devin\cli\sessions.db on Windows,
~/.local/share/devin/cli/sessions.db on Linux). Output goes to your
terminal or a local file — nothing external is contacted, and no VM, message
queue or model server is involved.
Tested on Windows and Linux (windows-latest + ubuntu-latest in CI).
Devin's sessions.db is auto-detected per platform — %APPDATA%\devin\ on
Windows, ~/.local/share/devin/ (XDG_DATA_HOME) on Linux,
~/Library/Application Support/devin/ on macOS. Override with the
DEVIN_PM_SESSIONS_DB env var (see Usage). The GUI state.vscdb lives at
<config>/Devin/User/globalStorage/state.vscdb (%APPDATA% on Windows,
XDG_CONFIG_HOME/~/.config on Linux); override with
DEVIN_PM_STATE_VSCDB.
- Private, volatile internals.
sessions.dbis an implementation detail of Devin; parsing is gated on the known schema versions (15–17) and refuses anything newer rather than guessing. - Cost is best-effort. The DB does not record billing in a documented
field;
cogs_jsonis unstable. Where no recognizable cost field exists, reports show-and the registry emitsnull— unknown, not zero. - GUI coverage is bindings-only.
--vscdbreads session→workspace bindings fromstate.vscdb; GUI transcripts (acp-messages/*.db) are not covered, so gui sessions carry no cost/milestone detail beyond amilestone:label. - Read-only. This project never writes to Devin's databases; the only
files it writes are the ones you ask for (
--out,milestones.jsonis yours to author). - Grouping normalizes spellings, not machines.
C:\x⇄/c/xand WSL-UNC prefixes fold into one key, but/home/u/repovsc:/users/u/repostay distinct — nothing in the path proves they are the same directory. POSIX paths keep their case.
pip install -e ".[dev]"
pytestFixtures-first TDD — see docs/SPEC.md for the data contracts and CONTRIBUTING.md for ground rules.
- You have weeks of Devin sessions and want a per-repo rollup — which projects exist, their session counts, latest activity, status — without scrolling the app's flat session list.
- You want Markdown status reports or a JSON registry to feed docs,
dashboards or other tools (
devin-pm registry --out registry.json). - You track milestones and want them detected automatically from
milestone: <name>session titles, or curated in amilestones.jsonfile at the project root. - You want strictly read-only rollups that fail loudly on unknown
sessions.dbschema versions instead of silently misreading them.
- You need GUI session transcripts —
--vscdbcovers thestate.vscdbworkspace bindings (which GUI session worked on which workspace), not theacp-messages/*.dbmessage stores. - You need reliable cost or billing rollups — the DB has no documented cost
field; reports show
-/nullwhere it is unknown, never an estimate. - You need live session state — devin-pm reports on the
sessions.dbsnapshot at read time; for live activity seedevin-office.
What is devin-pm? A CLI that turns Devin's flat sessions.db into a
project-management view: per-repository status tables, Markdown reports,
milestone tracking and a machine-readable registry. It is read-only — the
only files it writes are the reports you ask for.
How are sessions grouped into projects? By working directory: each
session records where it ran, and sessions sharing that path become one
project. The grouping key normalizes path spellings — C:\x, /c/x and
/cygdrive/c/x fold together (case-insensitive on drive-rooted paths),
and \\wsl.localhost\<distro>\… maps to the in-distro POSIX path — while
POSIX paths keep their case. With --vscdb, GUI session→workspace
bindings join the same grouping and are marked gui.
How do I mark a milestone? Name a session's title milestone: <name> —
that marks it in the session's project, and archiving (hiding) the session
marks it done. Alternatively, list milestones in milestones.json at the
project root; file entries win on name collision.
Why does my report show - for cost? Because sessions.db does not
record billing in a documented field. Where no recognizable cost exists,
devin-pm reports null/- — unknown — rather than printing a misleading
zero.
MIT — see LICENSE.