EchoesVault is a persistent memory plugin for Codex and a portable project-memory protocol for Codex, OpenCode, Claude, and other coding agents. Codex bootstraps a shared runtime and agent instructions into the repository; after that, every supported agent uses the same validation, locking, logs, and deterministic index. Knowledge stays in plain Markdown, remains readable without any agent, works naturally with Git, and opens as an Obsidian-compatible vault.
Managed adapters: 1.1.1 · Engine: 1.1.1 · Protocol: 1.0.0 · Marker schema: 3
Install the plugin once:
codex plugin marketplace add psinetron/echoes-vault-codex
codex plugin add echoes-vault-codex@echoes-vaultStart a new Codex task in the repository that should own the memory and ask in any language:
Initialize EchoesVault for this project.
Инициализируй EchoesVault для этого проекта.
Then use natural language rather than memorizing commands:
Restore project memory.
Show EchoesVault status.
Remember this architectural decision.
Save and finish this EchoesVault session.
Initialization is project-local. The globally installed Codex plugin stays silent in every other repository until EchoesVault is initialized there. Commit the generated protocol, portable runtime, and adapters so Codex, OpenCode, Claude, and teammates all follow the same rules.
- Installation
- What it provides
- Protocol 1.0.0 specification
- Agent-neutral protocol
- Open Knowledge Format alignment
- Status card and quick actions
- Team development without CI/CD
- Upgrade to 1.1.1
- Local development
- Security and privacy
- Support
- Codex in the ChatGPT desktop app or Codex CLI. Plugins are not currently supported by the Codex IDE extension.
- Python 3.9 or newer available as
python3. - Git, when installing from GitHub.
- No Python packages, API keys, accounts, background services, or network access at runtime.
Review the bundled SessionStart hook before enabling the plugin if your
environment requires auditing third-party commands.
This repository contains a Codex marketplace manifest. Add it as a marketplace source:
codex plugin marketplace add psinetron/echoes-vault-codexThen choose either installation method.
Interactive plugin browser:
codex
/plugins
Open the EchoesVault marketplace, select EchoesVault for Codex, install it, and make sure it is enabled. Start a new Codex session after installation.
Direct CLI installation:
codex plugin add echoes-vault-codex@echoes-vaultVerify the result:
codex plugin listThe expected entry is echoes-vault-codex@echoes-vault with status installed, enabled.
- Run
codex plugin marketplace add psinetron/echoes-vault-codexonce in a terminal. - Restart the ChatGPT desktop app.
- Open Plugins.
- Select the EchoesVault marketplace.
- Open EchoesVault for Codex and select the plus button to install it.
- Confirm that it appears in the Installed row and is enabled.
- Start a new Codex task; already-open tasks do not acquire newly installed skills and hooks.
Clone the repository:
git clone https://github.com/psinetron/echoes-vault-codex.git
cd echoes-vault-codexRun the tests before installing:
python3 -m unittest discover -s tests -vAsk Codex to connect the existing folder to your personal marketplace:
Use $plugin-creator to add the existing plugin in the current directory to my personal
marketplace, install it, and use the cachebuster update flow for future local changes.
The standard personal marketplace lives at ~/.agents/plugins/marketplace.json. Do not replace
that file if it already contains other plugins; let $plugin-creator merge the entry safely.
After each local code change:
- Run the tests.
- Ask
$plugin-creatorto update the cachebuster and reinstallechoes-vault-codex. - Start a new Codex task to load the updated bundle.
The plugin is installed once for Codex but remains silent in projects that do not have an EchoesVault. Open the target project in a new task and ask in any language, for example:
Initialize EchoesVault for this project.
Инициализируй EchoesVault для этого проекта.
Подключи локальную память проекта.
Exact skill names are optional. You can also invoke $echoes-init explicitly. Initialization
creates only repository-local files:
EchoesVault/
├── .echoes-vault.json
├── .gitignore
├── AGENT_PROTOCOL.md # shared contract for every agent
├── index.md # generated locally; ignored by Git
├── pages/
├── daily/YYYY-MM-DD/ # UTC date; one unique file per write
├── assets/
└── raw/
.echoes-vault/
├── .gitignore
├── echoes_vault.py # portable runtime; committed to Git
├── state.json # local runtime state; ignored by Git
└── lock # short-lived local lock; ignored by Git
AGENTS.md # managed block for Codex/OpenCode
CLAUDE.md # managed block for Claude
.claude/skills/echoes-vault/SKILL.md
.opencode/skills/echoes-vault/SKILL.md
.opencode/commands/echoes-init.md
.opencode/commands/echoes-start.md
.opencode/commands/echoes-status.md
.opencode/commands/echoes-end.md
On later tasks, the first response includes a status card for initialized projects. Other projects remain unaffected and show no card.
Codex is convenient for installing and initializing EchoesVault, but it is not required after the portable files have been created. To bootstrap a project without Codex, clone or download this repository once and run its bundled engine against the target project:
git clone https://github.com/psinetron/echoes-vault-codex.git
python3 echoes-vault-codex/scripts/echoes_vault.py \
--workspace /path/to/your/project --agent codex --adapter-version 1.1.1 initCommit the generated protocol, portable runtime, and adapters in the target project. Teammates and
other agents then use .echoes-vault/echoes_vault.py from that project and do not need a global
EchoesVault installation.
Refresh all configured marketplaces:
codex plugin marketplace upgradeOr refresh only EchoesVault:
codex plugin marketplace upgrade echoes-vaultOpen /plugins in Codex CLI or the Plugins page in the desktop app, reinstall/update the plugin,
and start a new task. If Codex still loads an older local development build, use
$plugin-creator to apply a new cachebuster before reinstalling.
In Codex CLI, open codex, enter /plugins, select the installed plugin, and either disable it or
uninstall it. In the desktop app, open the plugin under Installed and select Uninstall
plugin.
Remove the marketplace source only when you no longer need it:
codex plugin marketplace remove echoes-vaultUninstalling the Codex plugin does not delete project knowledge or its portable runtime.
Initialized repositories continue to contain EchoesVault/, .echoes-vault/echoes_vault.py, and
the agent adapters. They can be used by another supported agent or read as plain Markdown.
| Symptom | Check |
|---|---|
| Marketplace does not appear | Run codex plugin marketplace list, then restart the desktop app. |
| Plugin is installed but skills are missing | Start a new Codex task or CLI session. |
| Status card does not appear | Confirm that the project contains EchoesVault/.echoes-vault.json; legacy vaults may still be detected by index.md. |
| Hook reports a Python error | Run python3 --version; version 3.9+ must be on PATH. |
| Local edits are ignored | Update the manifest cachebuster, reinstall, and start a new task. |
| You do not want memory in a project | Do not initialize it; the globally installed plugin remains silent there. |
| Protocol mismatch is reported | Stop writes, update the adapter or plugin, then run initialization again. Never force an older writer against a newer vault. |
| Portable runtime or agent adapters are missing | For adapters, run project configure-agents. If the runtime is missing or damaged, run upgrade from the installed plugin's bundled launcher. |
| An OpenCode command was not replaced | EchoesVault preserves unrecognized user-owned files. Compare it with the generated command and reconcile it manually. |
For Codex's general plugin installation and marketplace model, see the official plugin documentation and plugin packaging guide.
$echoes-init— idempotently create or activate the vault.$echoes-start— rebuild and restore the full index plus the three latest session entries.$echoes-vault— search pages, append scratchpad notes, and safely maintain knowledge pages.$echoes-end— explicitly distill and save final session memory.$echoes-status— show a compact dashboard with size, metrics, filesystem checks, metadata validity, index integrity, and scale warnings.- Agent Protocol 1.0.0 — a tracked contract that every coding agent reads before using memory.
- Portable engine 1.1.1 — the same dependency-free Python storage engine is committed into each initialized repository and is always the execution source after bootstrap.
- Claude and OpenCode adapters — project skills and root instruction blocks are installed without replacing unrelated user instructions.
- OKF-aligned knowledge storage — pages follow the core Open Knowledge Format (OKF) model of plain Markdown, YAML frontmatter, typed concepts, portable directories, and progressive-disclosure indexes.
- A lightweight
SessionStarthook that asks Codex to show the current status card once in its first response after startup, resume, or clear, but only in initialized projects. Uninitialized projects remain silent. Compaction refreshes hidden context without repeating the card. - Natural-language starter actions for initialization, restore, status, and explicit final save, so normal use does not require memorizing skill names.
- A dependency-free Python CLI with atomic replacement writes, a project-local lock, strict page metadata, conflict-marker detection, path sanitization, and optimistic concurrency checks.
The managed project structure is intentionally Git-friendly:
EchoesVault/
├── .echoes-vault.json # tracked initialization marker
├── .gitignore # ignores only generated index.md
├── AGENT_PROTOCOL.md # generated cross-agent contract
├── index.md # generated from page metadata
├── pages/
├── daily/YYYY-MM-DD/ # UTC date; unique scratchpad/session files
├── assets/
└── raw/
The tracked portable engine lives at .echoes-vault/echoes_vault.py. Runtime state and the shared
local lock live at .echoes-vault/state.json and .echoes-vault/lock; they contain no durable
knowledge and are ignored locally.
The complete public implementer specification is available in EchoesProtocol.md. It defines the repository layout, marker and page schemas, deterministic index algorithm, unique daily-log format, portable CLI contract, locking, optimistic concurrency, Git behavior, migration rules, security boundaries, and a compatibility checklist for third-party agents and tools. The specification is MIT-licensed and can be reused by Codex, OpenCode, Claude, editor extensions, custom agents, and independent integrations.
Initialization writes EchoesVault/AGENT_PROTOCOL.md and adds a delimited EchoesVault block to
the repository's AGENTS.md and CLAUDE.md. Existing content outside that block is preserved.
Project skills are also written for Claude and OpenCode:
.claude/skills/echoes-vault/SKILL.md
.opencode/skills/echoes-vault/SKILL.md
.opencode/commands/echoes-init.md
.opencode/commands/echoes-start.md
.opencode/commands/echoes-status.md
.opencode/commands/echoes-end.md
All agents are instructed to use the repository runtime:
python3 .echoes-vault/echoes_vault.py --workspace . \
--agent <agent-name> --adapter-version <adapter-version> <command>The Codex plugin package, portable engine, protocol, marker schema, and each agent adapter have
separate versions. Only protocolVersion defines storage compatibility. An OpenCode plugin version
is never compared with the Python engine version. The bundled Codex engine is used only for first
initialization, explicit upgrade, or recovery of a missing project runtime; it delegates to a
compatible project runtime and never downgrades a newer one.
The runtime marker declares protocolVersion: "1.0.0". An adapter that encounters a different
protocol version must stop before writing instead of guessing compatibility. Optional agent
values in append and end payloads add provenance to unique log filenames and bodies:
{
"entry": "- Confirmed the shared authentication contract.",
"agent": "claude"
}Legacy OpenCode tools that directly edit index.md or append to daily/YYYY-MM-DD.md must not be
used with a protocol 1.0 vault. OpenCode should use the generated project skill and portable
runtime instead. The standalone EchoesVault for OpenCode
requires a corresponding protocol-aware release before its legacy tools can be mixed safely.
Recognized legacy EchoesVault command files and known direct-tool skills are replaced by project-
runtime redirects; unrelated user-owned files with the same names are preserved and reported by
the health check for manual reconciliation.
- Codex: use the plugin actions,
$echoes-*skills, or natural-language requests. - OpenCode: use the generated
/echoes-init,/echoes-start,/echoes-status, and/echoes-endproject commands. They call the portable runtime rather than legacy mutation tools. - Claude Code:
CLAUDE.mdadvertises the protocol and the generated project skill handles natural-language initialization, restoration, status, recall, logging, and explicit final save. - Other agents: read
AGENTS.mdandEchoesVault/AGENT_PROTOCOL.md, then invoke the portable CLI directly.
The portable command surface is:
| Command | Purpose |
|---|---|
init |
Initialize or migrate the vault and install every adapter |
migrate |
Explicitly migrate a recognized legacy vault |
upgrade |
Explicitly upgrade the project runtime and tracked adapters |
protocol |
Report supported and repository protocol versions |
configure-agents |
Repair protocol documentation, guides, skills, and OpenCode commands |
inspect / status --format card |
Inspect quantitative health without changing any file |
hydrate |
Refresh only ignored index.md and local state.json |
start --recent 3 |
Restore the index and latest session entries |
search <query> |
Search page bodies literally |
append --payload - |
Write one unique scratchpad file |
hash <filename> |
Obtain the optimistic concurrency hash for an existing page |
upsert --payload - |
Create or safely replace a complete page |
end --confirm-explicit-user-end --payload - |
Perform an explicitly authorized final save |
rebuild-index |
Validate metadata and reconstruct the generated local index |
EchoesVault follows the core ideas of Google's Open Knowledge Format v0.2: knowledge is stored as UTF-8 Markdown, concept pages begin with YAML frontmatter, every page has a type, and index.md enables progressive discovery without loading the complete vault.
EchoesVault deliberately extends the strict OKF shape with Obsidian [[wikilinks]], required stack
and status fields, daily/ session logs, and lifecycle values used by the original OpenCode plugin.
For that reason this project describes itself as OKF-aligned, rather than claiming strict OKF
v0.2 conformance. The files remain human-readable, Git-friendly, and straightforward for agents
and generic Markdown tooling to consume.
Every knowledge page uses frontmatter like:
---
type: architecture
stack: [python, codex]
status: active
summary: Authentication boundaries and token flow.
---summary is required, must fit on one line, and is limited to 160 characters. The Python runtime
builds index.md from filenames and these summaries in a fixed Unicode-aware order. Page bodies are
not used, so rebuilding the index consumes no model context and the same pages always produce the
same bytes. Existing pre-1.0 vaults are migrated automatically when their old index contains a
description for every page missing summary.
After the plugin is installed, start a new Codex task. On the first response, EchoesVault adds a compact card similar to:
### EchoesVault · ✓ Healthy
| Storage | Knowledge | Session |
|---|---|---|
| 186.4 KB · 48 files | 42 pages · 6 logs | active |
Protocol: 1.0.0 · engine: 1.1.1 · adapters ready.
Integrity: index, structure, metadata, and local paths are consistent.
The card is generated from live filesystem data. inspect and status are strictly read-only: they
do not initialize, migrate, repair adapters, regenerate the index, write state, or create a lock.
Projects without the initialization marker (or a legacy EchoesVault/index.md) show no card and
receive no hook context. A legacy vault gets an actionable migration card. Use the
plugin starter actions, invoke $echoes-status, or ask naturally in any language: “show vault
status”, “покажи состояние памяти”, “restore project memory”, or “сохрани эту сессию”. Exact skill
names are optional. Codex plugins cannot pin a permanent custom sidebar, so the card appears in the
conversation instead.
For scripts and diagnostics, request the same card directly:
python3 .echoes-vault/echoes_vault.py --workspace . inspect --format cardFrom a clone of this repository, you can also inspect another workspace with the bundled engine:
python3 scripts/echoes_vault.py --workspace /path/to/project inspect --format cardThe original OpenCode plugin exposes runtime tools, command templates, and a custom TUI sidebar through OpenCode-specific APIs. A Codex plugin natively packages skills, scripts, hooks, and optional MCP servers. EchoesVault uses Codex as the installer and bootstrapper, then places an agent-neutral runtime and instructions inside the repository:
| Choice | Benefit | Trade-off |
|---|---|---|
| Skills instead of custom slash-command registration | Native discovery and explicit $echoes-* workflows |
Invocation uses $echoes-start, not /echoes-start |
| Local CLI instead of an MCP server | No daemon, network, package install, or protocol dependency | Codex executes a local command rather than calling named MCP tools |
| Repository-portable runtime and protocol | Codex, OpenCode, and Claude share one writer and one set of invariants | The generated runtime and adapters are committed to each project |
| One-time SessionStart card instead of a sidebar | Live health is visible at the start of a task and after resume | There is no always-visible custom status panel |
| Explicit start/end | Predictable token cost and no accidental final save | The user must request restoration and finalization |
| Frontmatter-generated local index | Stable output, no model-token rebuild cost, and no index merge conflicts | Every page needs a concise summary |
| Unique daily files plus a project-local lock | Concurrent local writes and cross-branch logs do not overwrite one shared file | Same-page semantic conflicts still need human resolution |
| Optimistic hashes for existing pages | Prevents silent lost updates | Existing-page updates need one extra hash step |
Compared with the original, the port deliberately strengthens frontmatter validation, rejects path traversal, detects missing structure, symbolic links, unreadable files, invalid page metadata, Git conflict markers, and duplicate/orphan/missing index entries, uses UTC for sortable log paths, and avoids copying OpenCode/TUI dependencies. It keeps local-offset timestamps inside logs, deprecation-over-deletion, read-before-write, daily scratchpads, index synchronization, and the 200-page scale warning.
Commit durable knowledge and the small initialization files:
EchoesVault/.echoes-vault.json
EchoesVault/.gitignore
EchoesVault/AGENT_PROTOCOL.md
EchoesVault/pages/**
EchoesVault/daily/**
EchoesVault/assets/**
EchoesVault/raw/**
.echoes-vault/.gitignore
.echoes-vault/echoes_vault.py
AGENTS.md
CLAUDE.md
.claude/skills/echoes-vault/SKILL.md
.opencode/skills/echoes-vault/SKILL.md
.opencode/commands/echoes-init.md
.opencode/commands/echoes-start.md
.opencode/commands/echoes-status.md
.opencode/commands/echoes-end.md
Do not commit generated or machine-local files:
EchoesVault/index.md
.echoes-vault/state.json
.echoes-vault/lock
.opencode/echoes-state.json
.codex/echoes-vault-state.json
echoes-init adds those ignore rules automatically. If EchoesVault/index.md was already tracked
before upgrading, remove only that file from Git's index once while keeping the local copy:
git rm --cached EchoesVault/index.md
git add EchoesVault .echoes-vault/.gitignore .echoes-vault/echoes_vault.py AGENTS.md CLAUDE.md
git add .claude/skills/echoes-vault/SKILL.md .opencode/skills/echoes-vault/SKILL.md
git add .opencode/commands/echoes-init.md .opencode/commands/echoes-start.md
git add .opencode/commands/echoes-status.md .opencode/commands/echoes-end.md
git commit -m "Make EchoesVault index generated locally"After pulling, switching branches, or merging, explicitly refresh the ignored generated index and local state without touching tracked adapters:
python3 .echoes-vault/echoes_vault.py --workspace . hydratestart also hydrates before returning context. A focused index recovery command is available:
python3 .echoes-vault/echoes_vault.py --workspace . rebuild-indexDifferent pages and unique daily-log files normally merge cleanly. If two branches edit the same
knowledge page, Git still reports the ordinary Markdown conflict; resolve its meaning manually,
remove every conflict marker, keep valid frontmatter including summary, run hydrate, and request
EchoesVault status. The read-only health card reports unresolved <<<<<<<, =======, or
>>>>>>> markers. Its Git-readiness section also reports durable files that are untracked or
ignored and local state.json/lock files that were accidentally tracked, with exact suggested
commands; it never runs git add or git rm itself. No CI job,
Git hook, daemon, or background watcher is required.
After installing the Codex plugin 1.1.1, run initialization once in every existing vault. It keeps
Protocol 1.0.0, installs engine 1.1.1, preserves local state schema 4, and refreshes the managed
agent adapters. This patch also exposes the neutral managedAdapterVersion diagnostics field;
codexAdapterVersion remains as a deprecated compatibility alias for existing integrations:
Update this project's EchoesVault to protocol 1.0.0.
Обнови EchoesVault этого проекта до протокола 1.0.0.
Or run the bundled engine directly:
python3 /path/to/echoes-vault-codex/scripts/echoes_vault.py --workspace . \
--agent codex --adapter-version 1.1.1 upgradeState is read in this priority: .echoes-vault/state.json, .opencode/echoes-state.json, then
.codex/echoes-vault-state.json. Session flags and timestamps are preserved and schema 4 state is
written to .echoes-vault/state.json. Known legacy OpenCode skills are converted to shared-runtime
redirects; unknown files remain untouched and appear as adapter conflicts. Do not enable an older
OpenCode writer that still edits the index or shared daily files directly.
Validate all skills and the plugin:
for skill in skills/*; do
python3 /path/to/skill-creator/scripts/quick_validate.py "$skill"
done
python3 /path/to/plugin-creator/scripts/validate_plugin.py .Run the test suite:
python3 -m unittest discover -s tests -vThe runtime requires Python 3.9 or newer and only the standard library.
EchoesVault makes no network requests and has no authentication. Vault data operations are confined
to EchoesVault/, .echoes-vault/, the managed blocks in AGENTS.md and CLAUDE.md, and the
generated Claude/OpenCode project skills inside the resolved workspace; symbolic-link escapes are
rejected. Existing unrelated root instructions are preserved. Treat the vault like source code: do
not store secrets unless the repository's access policy permits them.
If EchoesVault saves you time or helps your agents work more consistently, you can support its continued development on Buy Me a Coffee. Support is entirely optional—the plugin remains open source under the MIT License.
MIT