The Code Was in Git. The AI Conversations TO Implement it,Was Gone A developer built ContextVault, an open-source, local-first memory layer for AI-assisted development, after losing context from AI conversations when switching between tools like ChatGPT, Codex, and Cursor. ContextVault preserves and makes searchable the reasoning behind code changes, addressing the structural problem of fragmented context across multiple AI agents. The tool includes a CLI and an Electron desktop app, both sharing the same Markdown-based data model. I reopened an old project and found a working authentication implementation. What I could not find was the reason it looked that way. The commits showed the final code, but not: The answers were scattered across a ChatGPT thread, a Codex session, and a terminal that no longer existed. There was another layer to it. I don't stick to one agent. I move between Codex, Claude Code, Cursor, and plain ChatGPT threads — sometimes because one tool genuinely fits the task better, more often because I simply run out of credits on one and switch to another mid-task. Every time that happened, the new agent started from zero. It had no idea what the previous one had already tried, decided, or ruled out. I either re-explained everything from memory, or let the new agent guess and re-discover things the old one already knew. This is not only a documentation problem. It is a structural problem in AI-assisted development. We use several tools to produce one project, but every tool keeps a separate, temporary memory. That experience became ContextVault. ContextVault is an open-source, local-first memory layer for AI work. It preserves useful context from browser LLM conversations, terminals, and coding-agent sessions, then makes that context searchable and reusable in later sessions. Think of the distinction this way: Git: what changed in the code? ContextVault: why did we change it, what failed, and what should happen next? The trigger for building it was specifically the agent-switching problem: whenever one agent ran out of credits or hit a limit, I needed the next one to pick up exactly where the last one left off, instead of restarting the investigation. ContextVault has three user-facing surfaces: There is no required account or ContextVault backend. Browser data stays in the browser. Project sessions stay in local Markdown. Initialize ContextVault inside a repository: npx @aliabdm/contextvault init contextvault record During the session, preserve only the context that may matter later: /title Fix authentication callback /source codex /user The login redirects back to the sign-in page. /agent The session cookie is missing during the callback. /decision Keep authentication checks in middleware. /problem The previous SameSite change did not fix the callback. /task Add a regression test for the redirect loop. /end The result is readable Markdown under: .contextvault/sessions/ Later, a developer or agent can ask for evidence: contextvault history --since 2w contextvault decisions auth --source codex contextvault problems auth --since 30d contextvault retrieve "authentication callback" contextvault prepare "fix authentication callback" retrieve ranks relevant local events. prepare creates a focused Markdown package for the next agent. The current engine is deterministic and lexical. It does not send the project to an LLM or generate an ungrounded answer. The CLI proved the model, but it limited the audience. Someone who simply wants "authentication decisions from the last month" should not need to know this syntax: contextvault decisions auth --source codex --since 30d So I built an Electron app over the package. The first version exposed command buttons and a raw arguments field. Technically, this preserved package compatibility. From a UX perspective, it was still asking users to think like a shell parser. The app was a GUI, but not yet a Desktop product. The redesign goal became similar to Docker CLI and Docker Desktop: Share the engine and data model, but give each surface a complete experience. The easiest way to build the GUI would have been to give Desktop its own recorder and database: php CLI - Markdown Desktop - SQLite or custom JSON That would immediately create two versions of ContextVault. Sessions, migrations, bug fixes, and indexing behavior would eventually drift. Existing CLI users would need imports or conversions before using Desktop. Instead, the architecture keeps one source of truth: Browser exports CLI / agents Desktop recorder \ | / \ | / .contextvault Markdown | local Context Engine | History · Search · Retrieve · Prepare · Memory Desktop is a GUI over the same engine and files—not a second implementation. When the user clicks Start recording , the Electron main process launches the bundled package recorder with the selected project as its working directory. The renderer only receives a narrow preload API: startRecorder { title, source } sendRecorderCommand recorderId, command finishRecorder recorderId cancelRecorder recorderId An entry created in the GUI is sent to the real recorder: await window.contextVault.sendRecorderCommand recorderId, /decision ${content} , The package writes the final session Markdown. This means a session created in Desktop is visible to: contextvault list contextvault show