mnemosyne-cc 1.6.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 (35) hide show
  1. mnemosyne_cc-1.6.0/.gitignore +17 -0
  2. mnemosyne_cc-1.6.0/LICENSE +21 -0
  3. mnemosyne_cc-1.6.0/PKG-INFO +443 -0
  4. mnemosyne_cc-1.6.0/README.md +415 -0
  5. mnemosyne_cc-1.6.0/pyproject.toml +92 -0
  6. mnemosyne_cc-1.6.0/src/mnemosyne/__init__.py +5 -0
  7. mnemosyne_cc-1.6.0/src/mnemosyne/__main__.py +4 -0
  8. mnemosyne_cc-1.6.0/src/mnemosyne/align.py +196 -0
  9. mnemosyne_cc-1.6.0/src/mnemosyne/artifact_export.py +295 -0
  10. mnemosyne_cc-1.6.0/src/mnemosyne/artifacts.py +315 -0
  11. mnemosyne_cc-1.6.0/src/mnemosyne/clean.py +144 -0
  12. mnemosyne_cc-1.6.0/src/mnemosyne/cli.py +1818 -0
  13. mnemosyne_cc-1.6.0/src/mnemosyne/codex.py +544 -0
  14. mnemosyne_cc-1.6.0/src/mnemosyne/config.py +220 -0
  15. mnemosyne_cc-1.6.0/src/mnemosyne/drift.py +345 -0
  16. mnemosyne_cc-1.6.0/src/mnemosyne/formats.py +115 -0
  17. mnemosyne_cc-1.6.0/src/mnemosyne/installer.py +248 -0
  18. mnemosyne_cc-1.6.0/src/mnemosyne/mcp_server.py +573 -0
  19. mnemosyne_cc-1.6.0/src/mnemosyne/memory.py +263 -0
  20. mnemosyne_cc-1.6.0/src/mnemosyne/parser.py +380 -0
  21. mnemosyne_cc-1.6.0/src/mnemosyne/plugin_assets/.claude-plugin/marketplace.json +19 -0
  22. mnemosyne_cc-1.6.0/src/mnemosyne/plugin_assets/.claude-plugin/plugin.json +16 -0
  23. mnemosyne_cc-1.6.0/src/mnemosyne/plugin_assets/.gitkeep +0 -0
  24. mnemosyne_cc-1.6.0/src/mnemosyne/plugin_assets/.mcp.json +8 -0
  25. mnemosyne_cc-1.6.0/src/mnemosyne/plugin_assets/commands/export.md +28 -0
  26. mnemosyne_cc-1.6.0/src/mnemosyne/plugin_assets/commands/history.md +18 -0
  27. mnemosyne_cc-1.6.0/src/mnemosyne/plugin_assets/commands/memories.md +25 -0
  28. mnemosyne_cc-1.6.0/src/mnemosyne/plugin_assets/commands/recall.md +19 -0
  29. mnemosyne_cc-1.6.0/src/mnemosyne/plugin_assets/commands/summon.md +23 -0
  30. mnemosyne_cc-1.6.0/src/mnemosyne/plugin_assets/hooks/hooks.json +17 -0
  31. mnemosyne_cc-1.6.0/src/mnemosyne/plugin_assets/skills/session-history/SKILL.md +138 -0
  32. mnemosyne_cc-1.6.0/src/mnemosyne/py.typed +0 -0
  33. mnemosyne_cc-1.6.0/src/mnemosyne/query.py +458 -0
  34. mnemosyne_cc-1.6.0/src/mnemosyne/recall.py +254 -0
  35. mnemosyne_cc-1.6.0/src/mnemosyne/render.py +469 -0
@@ -0,0 +1,17 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .venv/
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ dist/
7
+ build/
8
+ *.egg-info/
9
+ exports/
10
+
11
+ # OS noise
12
+ .DS_Store
13
+ Thumbs.db
14
+
15
+ # Editor noise
16
+ .vscode/
17
+ .idea/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dominikos Pritis
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,443 @@
1
+ Metadata-Version: 2.4
2
+ Name: mnemosyne-cc
3
+ Version: 1.6.0
4
+ Summary: Memory + context suite for Claude Code and Codex CLI: clean transcript exports (markdown/JSONL/plain), cross-session merge, cross-tool recall, memory drift checks, plus an MCP server and a Claude Code plugin.
5
+ Project-URL: Homepage, https://github.com/entro314-labs/mnemosyne
6
+ Project-URL: Repository, https://github.com/entro314-labs/mnemosyne
7
+ Project-URL: Issues, https://github.com/entro314-labs/mnemosyne/issues
8
+ Author-email: Dominikos Pritis <idominikos@outlook.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: anthropic,claude,claude-code,cli,export,jsonl,markdown,transcript
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: MacOS
16
+ Classifier: Operating System :: POSIX :: Linux
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Software Development
20
+ Classifier: Topic :: Text Processing :: Markup :: Markdown
21
+ Classifier: Topic :: Utilities
22
+ Requires-Python: >=3.13
23
+ Requires-Dist: cyclopts==5.0.0a7
24
+ Requires-Dist: mcp>=2.0.0a2
25
+ Requires-Dist: rich>=15.0
26
+ Requires-Dist: tomli-w>=1.2.0
27
+ Description-Content-Type: text/markdown
28
+
29
+ # mnemosyne
30
+
31
+ Mnemosyne is a Titaness in Greek mythology. She is the personification of memory and remembrance, and a fitting namesake for a project that serves as a clean, structured layer on top of the raw conversation logs produced by Claude Code. Mnemosyne takes the noisy, append-only JSONL files that Claude Code generates and transforms them into human- and agent-readable formats, while also providing tools for browsing, exporting, merging, and searching through past sessions.
32
+
33
+ > Memory + context suite for Claude Code and Codex CLI — clean transcript exports, curated memories, hidden subagent transcripts, cross-session merge, cross-tool recall, memory drift checks, project archive, MCP server, and a Claude Code plugin. For humans and agents.
34
+
35
+ Claude Code stores every conversation under
36
+ `~/.claude/projects/<slug>/<session-uuid>.jsonl` — a noisy, append-only log
37
+ of every event the IDE saw. This project is **the clean read/transform/query
38
+ layer on top of that archive**: take raw JSONL → produce the canonical
39
+ human- and agent-readable version → serve it through the access patterns
40
+ that actually matter.
41
+
42
+ ## What you can do with it
43
+
44
+ | Workflow | Command |
45
+ | --- | --- |
46
+ | "Export all my sessions for this project as readable markdown" | `syne export-all` |
47
+ | "Just the last month, please" | `syne export-all --since 2026-04-01` |
48
+ | "Only the sessions about auth" | `syne export-all --matching '(?i)auth'` |
49
+ | "Combine 3 sessions into one synthesis doc" | `syne merge abc123 def456 ghi789 -o synthesis.md` |
50
+ | "All Godot work from this project in one document" | `syne merge --all-from scifigame --matching '(?i)godot' -o godot-archive.md` |
51
+ | "Onboarding context — last 5 sessions concatenated" | `syne merge --all-from <project> --last 5 -o context.md` |
52
+ | "What did I do this week, across every project" | `syne merge --all-projects --since 2026-05-13 -o week.md` |
53
+ | "Back up every Claude Code conversation I've ever had" | `syne export-all --all-projects -o ~/claude-archive` |
54
+ | "…and everything else Claude saved alongside them" | `syne export-all --full` |
55
+ | "Just this project's curated memories" | `syne export-all --memories` |
56
+ | "The full transcripts of every subagent an audit spawned" | `syne export <id> --subagents` |
57
+ | "Give me JSONL to feed into an embedding pipeline" | `syne export-all --format jsonl` |
58
+ | "Plain text I can paste into another LLM" | `syne export-all --format plain` |
59
+ | "Let Claude itself search and load my past sessions and memories" | `syne install` (the MCP server + plugin) |
60
+ | "Tell every agent (Claude, opencode, Codex…) to self-align from its own memory" | `syne align` |
61
+ | "A small recall brief I can pipe into a session-start hook" | `syne recall --recent` |
62
+ | "What did I do in **Codex CLI** on this project?" | `syne codex-list` |
63
+ | "Export a Codex rollout as readable markdown" | `syne codex-export <id>` |
64
+ | "Which of my curated memories have gone stale?" | `syne drift` |
65
+
66
+ ## Install (two commands)
67
+
68
+ Requires Python 3.13+ and [uv](https://github.com/astral-sh/uv).
69
+
70
+ ```bash
71
+ # 1. install the package — puts `syne` and `syne mcp` on PATH globally
72
+ uv tool install mnemosyne-cc
73
+ # …or straight from source for the bleeding edge:
74
+ # uv tool install git+https://github.com/entro314-labs/mnemosyne
75
+
76
+ # 2. (optional) wire the Claude Code plugin sidecar — adds slash commands + skill
77
+ syne install
78
+ ```
79
+
80
+ The PyPI distribution is **`mnemosyne-cc`** (the bare `mnemosyne` name is taken by
81
+ an unrelated project); the import package and the `syne` command are still `mnemosyne`.
82
+
83
+ Step 2 copies the plugin into `~/.claude/plugins/mnemosyne/` and
84
+ registers it. Then in Claude Code: `/plugin install
85
+ mnemosyne@mnemosyne`. The CLI works fine without
86
+ step 2; step 2 is only needed if you want `/recall`, `/history`, `/summon`,
87
+ `/export` slash commands inside Claude Code.
88
+
89
+ Update later: `uv tool upgrade mnemosyne-cc && syne install`.
90
+ Uninstall: `syne uninstall && uv tool uninstall mnemosyne-cc`.
91
+
92
+ ## The three layers
93
+
94
+ | Layer | Consumer | What it does |
95
+ | --- | --- | --- |
96
+ | **CLI (`syne`)** | You, in a terminal | Browse, export, merge, search, drift-check. |
97
+ | **MCP server (`syne mcp`)** | Any agent (incl. Claude Code) | 19 read-only tools: self-align, transcripts, memories, handoffs, subagents, Codex rollouts, drift. |
98
+ | **Claude Code plugin** | Claude Code specifically | `session-history` skill + `/recall`, `/memories`, `/history`, `/summon`, `/export` slash commands — wires Claude to its own past via the MCP. |
99
+
100
+ All three share the same parser, renderer, project discovery, and noise
101
+ filtering.
102
+
103
+ ## CLI
104
+
105
+ Run `syne` with no arguments. When the current directory is a known Claude Code
106
+ workspace, it loads that workspace's sessions directly — no project chooser.
107
+ Run it from anywhere else (or pass `--pick`) to choose from all projects. Otherwise:
108
+
109
+ ```bash
110
+ syne list # sessions for the cwd's project
111
+ syne export <id-or-prefix> # single session → <project>/.mnemosyne-exports/
112
+ syne export-all # every session in the project
113
+ syne merge <id1> <id2> -o out.md # combine specific sessions
114
+ syne merge --all-from <project> # combine every session from a project
115
+ syne recall [query] [--memories] # small capped recall brief → stdout (hooks / non-MCP agents)
116
+ syne align # write the self-alignment directive into CLAUDE.md + AGENTS.md
117
+ syne drift # verify curated memories against the live repo (staleness check)
118
+ syne codex-list [--all] # Codex CLI rollouts for this project (~/.codex)
119
+ syne codex-export <id> # render one Codex rollout through the same pipeline
120
+ syne projects # registry of all known projects
121
+ syne config-show # current settings file
122
+ syne install / syne uninstall # plugin sidecar
123
+ syne mcp # MCP server on stdio (used by plugin)
124
+ ```
125
+
126
+ ### Filters and scope (on `export-all` and `merge`)
127
+
128
+ - `--since 2026-05-01` / `--until 2026-05-31` — date-range on `last_timestamp`.
129
+ - `--matching '(?i)regex'` — keep sessions whose title or first prompt matches.
130
+ - `--last N` (merge only) — keep the N most-recent sessions after filters.
131
+ - `--all-from <project>` (merge only) — combine every session in one project.
132
+ - `--all-projects` (merge + export-all) — operate across every known project.
133
+ - `--mode {transcript,compact,full}` — render-time mode override.
134
+ - `--format {markdown,jsonl,plain}` — output format.
135
+ - `--no-sidecar` / `--no-index` — skip sidecars or per-project index.
136
+
137
+ ### Artifacts beyond the transcript (on `export` and `export-all`)
138
+
139
+ Claude Code stores far more than the transcript next to each session — a curated
140
+ memory layer, session-handoff summaries, and the full transcripts of every
141
+ subagent and workflow agent (the main transcript only keeps each agent's final
142
+ result). These are **off by default**; opt in per category:
143
+
144
+ - `--memories` — the project's curated memory layer (`memory/*.md`): durable
145
+ facts (roadmaps, decisions, gotchas, preferences) with a `[[link]]` graph.
146
+ - `--subagents` — the full transcript of every spawned subagent, rendered in the
147
+ same mode as the main transcript.
148
+ - `--summaries` — session-memory handoff digests (`session-memory/summary.md`).
149
+ - `--workflows` — workflow orchestration scripts, run-journal summaries, and the
150
+ agents each workflow orchestrated.
151
+ - `--tool-results` — externalised large tool outputs, deterministically scrubbed.
152
+ - `--full` — all five at once. (Distinct from `--mode full`, which only controls
153
+ transcript verbosity.)
154
+
155
+ The same noise-reduction is applied: subagent/workflow transcripts go through the
156
+ full clean+render pipeline; memories and summaries are whitespace-normalised;
157
+ tool output is scrubbed; only workflow scripts are copied verbatim (they're code).
158
+
159
+ ### Output layout
160
+
161
+ A `syne export-all --full` lands like this (artifact bundles only appear for the
162
+ categories you enable):
163
+
164
+ ```
165
+ <project>/.mnemosyne-exports/
166
+ ├── fix-godot-spawn-location.md # rendered transcript
167
+ ├── fix-godot-spawn-location.meta.json # per-session metadata sidecar
168
+ ├── fix-godot-spawn-location.summary.md # session-memory handoff digest (--summaries)
169
+ ├── fix-godot-spawn-location.subagents/ # full subagent transcripts (--subagents)
170
+ │ ├── explore-find-spawn-logic-ac8a92f0.md
171
+ │ └── index.json # agent_type / description / tool_use_id map
172
+ ├── fix-godot-spawn-location.workflows/ # scripts + orchestrated agents (--workflows)
173
+ │ ├── scripts/audit-sweep-wf_364fe78c.js
174
+ │ └── wf_364fe78c-f35/
175
+ │ ├── general-purpose-audit-domain-a02e9451.md
176
+ │ └── journal-summary.json # agents started/completed/distinct
177
+ ├── fix-godot-spawn-location.tool-results/ # externalised tool output (--tool-results)
178
+ ├── memory/ # project-level curated memory (--memories)
179
+ │ ├── MEMORY.md # the human index (copied through)
180
+ │ ├── product-roadmap-mid-2026.md # per-memory copies
181
+ │ ├── memories.md # one consolidated document
182
+ │ └── memories.json # machine index w/ resolved/dangling link graph
183
+ ├── …
184
+ └── index.json # project-level index of all exports
185
+ ```
186
+
187
+ Each `.meta.json` carries everything a downstream tool needs without
188
+ re-parsing the raw JSONL: `{session_id, project_slug, ai_title, first_prompt,
189
+ first_timestamp, last_timestamp, user_count, assistant_count, source_jsonl,
190
+ source_size_bytes, rendered_file, rendered_size_bytes, mode, format,
191
+ generated_at}`. `index.json` is the same data aggregated across all sessions
192
+ in the export. `memory/` is written once per project; everything else is
193
+ per-session, keyed to the transcript's filename.
194
+
195
+ ## Render modes
196
+
197
+ Most of a raw JSONL session is tool I/O. Three levels:
198
+
199
+ | `--mode` | What's in the output | Size vs raw |
200
+ | --- | --- | --- |
201
+ | `transcript` | **(default)** Only user prompts + assistant prose. No tools. | ~13% |
202
+ | `compact` | Transcript + one-line summaries per tool call (`📄 Read /path (4521 chars)`, `🐚 Bash <cmd>` + result). | ~49% |
203
+ | `full` | Everything verbatim — tool inputs and results fenced. | ~93% |
204
+
205
+ Unconditional cleanups, all modes:
206
+
207
+ - Consecutive same-role turns coalesce under one header (3,593 → 47 headers on a real 6,000-message session).
208
+ - Boilerplate acks scrubbed (`The file X has been updated successfully`, `Todos have been modified successfully`).
209
+ - System-injected user messages dropped (`isMeta=True`).
210
+ - API/auth/credit error responses dropped (`stop_reason='stop_sequence'`).
211
+ - `<task-notification>` XML unwrapped to summary+result.
212
+ - System wrappers stripped: `<system-reminder>`, `<ide_opened_file>`, `<ide_selection>`, `<command-name>`, `<local-command-*>`.
213
+ - JSON-escape-encoded paste-ins unescaped (`\n\n` → real newlines) when the text looks serialized.
214
+
215
+ Deterministic machine-noise scrub on captured tool output (compact/full), pure
216
+ and idempotent — same input always yields the same output (see `clean.py`):
217
+
218
+ - ANSI/VT escape sequences removed (colour codes, cursor moves, OSC titles).
219
+ - Carriage-return progress bars collapsed to their final frame (`npm install`, download spinners).
220
+ - Base64 / data-URI blobs truncated to a `…[+N base64 chars]` stub (pasted screenshots, embedded binaries).
221
+ - Whitespace normalised on every document: trailing spaces trimmed, runs of 3+ blank lines collapsed.
222
+
223
+ ## Output formats
224
+
225
+ | `--format` | Shape | Best for |
226
+ | --- | --- | --- |
227
+ | `markdown` | Default. Headed turns, fenced tool blocks, code in fenced blocks. | Human reading. |
228
+ | `jsonl` | One JSON object per coalesced turn: `{turn_id, turn_index, role, timestamp, text, char_count, session_id, project_slug, project_path}`. `turn_id` is `{session_id}#{turn_index}` — stable across re-renders, safe to use as a vector store primary key. | Embedding pipelines, vector store ingestion, structured downstream consumers. |
229
+ | `plain` | No markdown decoration. `=== USER (ts) === / === ASSISTANT (ts) ===` headers. | Pasting into prompts for models that prefer no markup. |
230
+
231
+ ## MCP server
232
+
233
+ `syne mcp` speaks MCP over stdio. Nineteen read-only tools — one aggregated
234
+ self-align entry point, plus tools over transcripts, the curated memory layer,
235
+ handoff digests, hidden subagent transcripts, the Codex CLI archive, and memory
236
+ drift. Every tool carries MCP `readOnlyHint` annotations (nothing writes, nothing
237
+ leaves the machine), so hosts that honor annotations can auto-approve the calls:
238
+
239
+ | Tool | Purpose |
240
+ | --- | --- |
241
+ | `self_align(query?, project?, all_projects=false, max_chars=6000)` | **Start here.** One bounded packet: memory matches/index + recent summaries + transcript snippets + Codex rollouts/handoffs for the same project + `suggested_next` calls + guidance. Current project by default; cross-project only when explicit. No full bodies/transcripts. |
242
+ | `list_projects()` | Every project with sessions, sorted most-recent-used. |
243
+ | `list_sessions(project?, limit=20)` | Newest sessions in a project. |
244
+ | `get_session_summary(session_id, project?)` | Cheap header — no transcript loading. |
245
+ | `get_session_handoff(session_id, project?)` | The compaction handoff digest (Title / Current State / Next steps) — "where we left off", cheaper than a transcript. |
246
+ | `get_session(session_id, project?, mode="transcript", max_tool_chars=2000)` | Rendered markdown for one session. |
247
+ | `recall_recent(project?, limit=5)` | Last N session summaries for the current project. |
248
+ | `search_sessions(query, project?, all_projects=false, max_results=10, context_chars=200)` | Case-insensitive substring search across rendered transcripts. Current project by default; cross-project only when explicit. |
249
+ | `list_memories(project?)` | Curated memories for a project (name, type, description, links). |
250
+ | `get_memory(name, project?)` | One memory's full body + metadata, by name or prefix. |
251
+ | `search_memories(query, project?, all_projects=false, max_results=10)` | Substring search across memory names/descriptions/bodies. Current project by default; cross-project only when explicit. |
252
+ | `list_subagents(session_id, project?)` | The subagent transcripts behind a session's Task/workflow calls. |
253
+ | `get_subagent(session_id, agent_id, project?, mode="transcript")` | One subagent's full rendered transcript. |
254
+ | `list_codex_sessions(project?, limit=10)` | Codex CLI rollouts recorded for the same working tree (`~/.codex/sessions`) — cross-tool continuity. |
255
+ | `get_codex_session(session_id, mode="transcript")` | One Codex rollout rendered through the same pipeline (modes and scrubbing identical). |
256
+ | `list_codex_handoffs(project?)` | Codex's own per-session digests (rollout summaries) for this project. |
257
+ | `get_codex_handoff(name)` | One Codex handoff digest's full body, by file name or thread-id prefix. |
258
+ | `get_codex_memory(max_chars=4000)` | Codex's consolidated model-written memory (`memory_summary.md`), capped. Trust below curated memories. |
259
+ | `check_drift(project?)` | Deterministically verify every curated memory's cited paths, `path:line` anchors, and `[[links]]` against the live repo. |
260
+
261
+ Manual MCP registration (without the plugin):
262
+
263
+ ```json
264
+ {
265
+ "mcpServers": {
266
+ "mnemosyne": {
267
+ "command": "syne",
268
+ "args": ["mcp"]
269
+ }
270
+ }
271
+ }
272
+ ```
273
+
274
+ ## Claude Code plugin
275
+
276
+ After `syne install`, restart Claude Code, then run
277
+ `/plugin install mnemosyne@mnemosyne`. You get:
278
+
279
+ | Command | What it does |
280
+ | --- | --- |
281
+ | `/recall <query>` | Search past sessions, show matches with snippets. |
282
+ | `/memories [query]` | List or search the project's curated memories. |
283
+ | `/history [limit]` | List recent sessions for the current project. |
284
+ | `/summon <id-or-prefix> [mode]` | Load a session's transcript into context. |
285
+ | `/export <id-or-prefix \| --all> [--full \| --memories \| …]` | Export from inside Claude Code. |
286
+
287
+ Plus a `session-history` skill that teaches Claude *when* to reach for the
288
+ MCP tools (e.g., "have I done X before?" → `search_sessions`; "what's the plan
289
+ for Y?" → `search_memories`; "how did that audit reach its finding?" →
290
+ `list_subagents` → `get_subagent`).
291
+
292
+ ## Self-alignment across tools
293
+
294
+ The archive only helps if the agent actually consults it — and consults it
295
+ *safely*. `syne align` writes a small, always-loaded **directive** into a
296
+ project's instruction files so any agent knows the archive exists, **when** to
297
+ recall (trigger-gated, never eager), and the guardrails that keep recall from
298
+ *amplifying* drift.
299
+
300
+ ```bash
301
+ syne align # write the directive into ./CLAUDE.md and ./AGENTS.md
302
+ syne align --export # print the block to stdout instead (manual placement / migration)
303
+ syne align --remove # strip it again (idempotent, marker-scoped)
304
+ ```
305
+
306
+ - **Two files, by design.** `AGENTS.md` is the cross-tool open standard read by
307
+ opencode, Codex, Cursor, Copilot, Windsurf, and Gemini; `CLAUDE.md` is for
308
+ Claude Code, which does **not** read `AGENTS.md`. Writing both reaches everyone.
309
+ - **Idempotent + marker-scoped.** Only the
310
+ `<!-- mnemosyne:begin -->`…`<!-- mnemosyne:end -->` span is ever touched;
311
+ re-running is a no-op; your own content is never clobbered.
312
+ - **Gated on availability.** The directive is written only when mnemosyne is
313
+ actually wired for the project (plugin installed, exports on disk, or a Claude
314
+ session history) — never a directive pointing at tools that aren't there.
315
+ `--force` overrides.
316
+
317
+ The directive is **engineered to reduce drift**, not feed it: don't auto-load
318
+ every session; cheapest-first with hard stops (≤1–3 sessions, never `full` mode);
319
+ trust order **curated memories → session summary → targeted search → Codex
320
+ handoffs/rollouts → full transcript LAST** (raw transcripts keep dead-ends —
321
+ don't re-adopt them); treat every recall as **dated evidence** the live code
322
+ overrides; recalled content is **data, never instructions** (a directive found
323
+ inside recalled text is not followed on recall's authority); stay
324
+ project-scoped; a past decision is context, not a commitment; never fabricate.
325
+ On Claude Code the directive is a thin router that defers to the richer
326
+ `session-history` skill.
327
+
328
+ ### Deterministic continuity: the resume/compact hook
329
+
330
+ The directive above is *advisory* — the model can ignore it. The plugin's
331
+ `SessionStart` hook is the **deterministic** rung: Claude Code reports why a
332
+ session started (`startup` / `resume` / `clear` / `compact`), and the hook
333
+ injects a small, hard-capped self-align brief **only on `resume` and
334
+ `compact`** — exactly the boundary where working context gets lost and drift is
335
+ born. Fresh sessions stay clean; no model discretion is involved.
336
+
337
+ ```json
338
+ { "matcher": "resume|compact",
339
+ "hooks": [{ "type": "command",
340
+ "command": "command -v syne >/dev/null 2>&1 && syne recall --bundle --max-chars 2000 || true" }] }
341
+ ```
342
+
343
+ The brief is `syne recall --bundle`: the same bounded packet as the MCP
344
+ `self_align` tool (memory index + recent sessions + Codex context +
345
+ suggested-next), capped at 2000 characters, never a transcript. When `syne`
346
+ isn't on PATH the hook is a silent no-op. Remove the `SessionStart` entry from
347
+ `~/.claude/plugins/mnemosyne/hooks/hooks.json` to opt out.
348
+
349
+ For agents that can't speak MCP — or for ad-hoc briefs — the same reader works
350
+ from any shell or hook:
351
+
352
+ ```bash
353
+ syne recall --recent --max-chars 1500 # tiny "what was I doing" brief
354
+ syne recall --bundle "auth" # the full self-align packet, topic-scoped
355
+ syne recall "auth" --memories # curated decisions about auth
356
+ syne recall "JWT" --format json # machine-readable for piping
357
+ ```
358
+
359
+ ### Drift checks: recall you can trust
360
+
361
+ `syne drift` (and the `check_drift` MCP tool) mechanically verifies every
362
+ curated memory against the live repository: cited file paths must exist
363
+ (worktree, archive, or anywhere in the tree for bare names — vendor dirs
364
+ pruned), `path:line` anchors must still fall inside the file, and `[[links]]`
365
+ must resolve. Purely deterministic — a finding means the memory's claims about
366
+ the repo no longer hold, so treat it as stale until re-verified. This is the
367
+ computed counterpart of the directive's "dated evidence" rule.
368
+
369
+ ## Settings file
370
+
371
+ Persistent state at `~/.config/mnemosyne/config.toml`:
372
+
373
+ ```toml
374
+ [defaults]
375
+ output_dir = "{local_path}/.mnemosyne-exports" # {local_path} | {slug} | {cwd}
376
+ mode = "transcript" # transcript | compact | full
377
+ include_thinking = false
378
+ include_attachments = false
379
+ include_reminders = false
380
+ max_tool_chars = 2000
381
+
382
+ [[projects]]
383
+ slug = "-Users-foo-DevFolder-My-Projects-scifigame"
384
+ local_path = "/Users/foo/DevFolder/My-Projects/scifigame"
385
+ friendly_name = "scifigame"
386
+ git_remote = "https://github.com/foo/scifigame.git"
387
+ git_branch = "main"
388
+ last_used = "2026-05-19T15:13:04+00:00"
389
+ ```
390
+
391
+ The registry is rebuilt from the filesystem each run; user-edited fields
392
+ (`friendly_name`, `git_*`) are preserved. `last_used` updates whenever you
393
+ export from a project. Claude Code's slug encoding (`/` → `-`) is lossy
394
+ (`My-Projects` and `My/Projects` collide), so `syne` resolves the real local
395
+ path by reading the `cwd` field stored inside each session record —
396
+ authoritative, not heuristic.
397
+
398
+ ## Storage architecture
399
+
400
+ **Files all the way down.** The only persistent state this project creates:
401
+
402
+ - Cleaned exports under `<project>/.mnemosyne-exports/` (.md + .meta.json + index.json),
403
+ plus the opt-in artifact bundles (`<title>.subagents/`, `<title>.workflows/`,
404
+ `<title>.summary.md`, `<title>.tool-results/`, and a project-level `memory/`).
405
+ - TOML registry at `~/.config/mnemosyne/config.toml`
406
+
407
+ No database. The raw JSONL — and the `memory/`, `subagents/`, `workflows/`,
408
+ `session-memory/`, `tool-results/` dirs Claude Code writes beside it — are the
409
+ source of truth, owned by Claude Code; our output is durable,
410
+ version-controllable, grep-able, and embed-able. A SQLite FTS5 cache would only
411
+ be worth adding past ~5,000 sessions when full-text search starts feeling slow.
412
+ At that point it would be a derived cache, never canonical — `rm sessions.db`
413
+ would lose nothing.
414
+
415
+ ## Layout
416
+
417
+ ```
418
+ src/mnemosyne/
419
+ parser.py # JSONL → typed events (Message / Attachment / *Block)
420
+ clean.py # deterministic noise passes (ANSI / CR / base64 / whitespace)
421
+ render.py # events → markdown (3 modes + same-role coalescing) + collect_turns
422
+ formats.py # render_jsonl + render_plain (share collect_turns)
423
+ memory.py # curated memory layer: frontmatter parse + [[link]] graph + index
424
+ artifacts.py # discover per-session bundle (subagents / workflows / summaries / tool-results)
425
+ artifact_export.py # write the bundle to disk (reuses parser/render) + project memories + slugify
426
+ config.py # TOML settings + project registry + git enrichment
427
+ query.py # shared recall/search core (used by the MCP server AND `syne recall`)
428
+ recall.py # `syne recall` — capped, headers-first stdout brief for hooks / non-MCP agents
429
+ align.py # `syne align` — idempotent CLAUDE.md/AGENTS.md self-alignment directive writer
430
+ cli.py # cyclopts app: list / export / export-all / merge / recall / align / install / mcp
431
+ mcp_server.py # MCPServer with 13 read-only tools (self_align + sessions + memories + subagents)
432
+ installer.py # syne install / uninstall — deploys plugin to ~/.claude/plugins/
433
+ plugin_assets/ # bundled plugin templates (.claude-plugin/, skills/, commands/, .mcp.json)
434
+ tests/
435
+ test_parser.py / test_render.py / test_formats.py / test_cli_helpers.py
436
+ test_clean.py / test_workspace.py / test_installer.py / test_mcp_server.py
437
+ test_memory.py / test_artifacts.py / test_artifact_export.py
438
+ test_query.py / test_recall.py / test_align.py
439
+ ```
440
+
441
+ ## License
442
+
443
+ MIT © 2026 Dominikos Pritis. See [LICENSE](LICENSE).