Every Claude Code session ends and forgets: which approach you rejected and why, which bug was fixed and how, where the work stopped. DevLog captures it from three short lines at the end of each response, hands it back to Claude before it repeats a mistake, and stops it at the moments that matter — no release with open work behind it, no dependency installed unchecked. On a local dashboard, without you writing a line of it.
The session ends and the context evaporates with it. You open the project days later and neither you nor Claude remembers where you stopped.
"We'll get back to it later" gets said in one session and forgotten in the next. Nothing holds anyone accountable.
A discovered bug left unfixed, a plan step never finished — and the release went out because nothing stood in its way.
Claude wasn't in the conversation that settled the decision; it only reads the code — and the reason isn't in the code.
No commands to memorize, no files to write, and your history never enters your repo. You work with Claude exactly as you always do.
The protocol reaches Claude automatically at the start of every session, so it closes its work with lines like -(built), -(todo) and -(bug fix) #7.
At the end of every response, DevLog reads the tags and posts them to the local server. Zero noise in your conversation context; your history lives in DevLog's own data directory, not in your repo.
Open 127.0.0.1:7777 and watch all your projects: activity, plans, releases, vulnerabilities — moving in real time over WebSocket.
Ordinary trackers record and watch. DevLog enforces discipline on Claude itself — 19 guards that refuse instead of warn; here are three of them.
Claude finished work that matches an open task and didn't close it? The response is rejected until it does. Someone tries to ship a release with items still open or tests that haven't passed? The command is intercepted before it runs. Claude tries to install a dependency blind? The command is blocked with the safe version to pin — the newest stable at least 7 days old and clean in OSV. Nothing slips through — not because someone was paying attention, but because the system doesn't allow it.
Every project Claude touches appears automatically: what was built, opened, closed — updating in real time, no refresh.
Plans with phases and checkboxes that persist across sessions: Claude says "step done" and the ☑ flips on your dashboard.
Built-in scanning against the OSV.dev database — no API key, no external service — including transitive dependencies.
npm, crates.io, PyPI, Go and Packagist — compares your versions against the latest official release and flags anything newer than 7 days.
-(release) is enough: DevLog runs your project's own checks (typecheck, lint, tests) in the background and records the release once they pass. Then it writes the release report, bumps the version in your manifest, and runs the post-release steps you declared (mirror to the public checkout, then build). Any failure reaches you on the next response, and a release that went out wrong can be rolled back.
Each session starts with a compact injected context: what was done before and what's still open — so Claude never reinvents what it built yesterday.
Every edit Claude makes is recorded with its full diff — per file, per session, reviewable from the dashboard.
Reports, analyses and plans written as Markdown and served as styled HTML — without Claude hand-writing a web page.
Every user-visible capability is recorded as one plain-language line, and a polished client report is generated from the inventory whenever you need it.
Claude asks "have we solved this before?" and gets stored decisions and fixes back in the same turn — and a new bug resembling a closed one automatically surfaces its old fix.
"What keeps breaking?" — a retrospective of every bug and vulnerability ever, with ages and files, plus a full-history study saved as a document that measures progress since the last one. Every fix is closed with its cause and a failure class from a fixed list (condition, timing, silent failure…), so you see which kind keeps recurring — and a bug that comes back is linked to the old one with ⟲.
Rules captured from your corrections, pulled by language or app type only when you ask — Claude never pulls them on its own, so they never get in the way of a project they don't fit. A rule written inside a project stays there; the global: prefix promotes it to all your projects — so Claude never repeats the same mistake in another project.
-(ask:why) hands Claude a file's full history — its purpose, the decisions that shaped it, every bug that touched it and how it ended — before any big edit. -(ask:map) ranks files by how much depends on them.
The first time Claude touches a file five or more files depend on, it's stopped once: "this is a load-bearing wall — here's what sits on it." It doesn't prevent demolition; it prevents unaware demolition.
-(ask:recent) summarizes past sessions by time: their tags, files, commands and which failed. And your literal request is stored with every batch — so "why was this asked for?" is answered in your words.
After a batch that closes items, one nudge asks for the turning points: an approach that failed, a change of direction, a deliberate deferral — stamped by an evidence check: a claim with no trace in the session is marked unsupported.
A page for every dependency in your project: why it's there, its official description, its security status. Overriding a warning is recorded as an open security item — it doesn't vanish.
Which model opens more bugs, whose fixes hold, who ships without tests — numbers from your real work; every tag carries the name of the model that wrote it.
Before/after effect of every rule, a hit counter per guard (a silent guard vs a dead one), and a "backed / no trace" stamp on every "I did X" claim — with no built-in AI.
Old data is archived compressed, undo keeps a copy first — and if the copy can't be written the deletion is refused. Export any project as one file and import it on another machine.
Move or rename a project folder and its history follows. A copy of the folder, or two folders with the same name, become separate projects whose records never mix — via a random id in .devlog/project.json that stays out of git.
All your data stays on your machine. The server listens on 127.0.0.1 only — nothing leaves for the internet.
Bun and Node built-ins only. No supply chain to worry about, no unknown package to audit.
No sign-up, no tracking, no cloud. The only outbound calls are dependency lookups — package names and versions to the official registries and OSV.dev, plus an update check to GitHub Releases. Metadata only, never your code or history; each one has its own off switch.
Built-in defenses against DNS rebinding, XSS and path traversal; API keys, passwords and tokens are scrubbed from the command log before it's stored — covered by 2,500+ automated tests.
/plugin marketplace add fmaaakcode/devlog
/plugin install devlog@devlog
That's everything: the hooks, the protocol and the server all ship inside the plugin,
and the server starts on its own with your first session.
Open http://127.0.0.1:7777 and watch your dashboard.
The only requirement: Bun on your machine.
Almost none. Tags are captured straight from Claude's responses and the history is stored in DevLog's own directory (~/.devlog/data) outside your projects. What DevLog does write into a project is one .devlog/ folder: a tiny identity file (project.json, kept out of git automatically), plus generated docs, release pages and the DEVLOG_STATUS.md mirror when those features are used. Add it to .gitignore or commit it; nothing else in your tree is touched.
The session-start injection is compact and conditional (it only appears when needed), and tag capture adds a fraction of a second at the end of a response — a small price for real enforcement.
Not for its core work — capture, dashboard, guards and recall all run offline. Three things go online, all opt-out: the dependency freshness/vulnerability check (official registries + OSV.dev, package names and versions only), the library advisor behind -(ask:lib) and the install gate, and an hourly update check against GitHub Releases. Kill switches: DEVLOG_REGISTRY_CHECK_DISABLED=1, DEVLOG_VULN_CHECK_DISABLED=1, DEVLOG_VERSION_CHECK_DISABLED=1.
The release guard can be bypassed consciously with an environment variable (DEVLOG_RELEASE_GUARD=0) — the decision stays yours, but nothing ever slips through by accident.