@korrlabs/mnemos-pi 2.15.0

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.
package/README.ru.md ADDED
@@ -0,0 +1,378 @@
1
+ <!-- markdownlint-disable MD041 MD033 -->
2
+ <p align="center">
3
+ <img src="docs/assets/mnemos-banner.svg" alt="Mnemos — сервер памяти и знаний для AI-агентов" width="100%">
4
+ </p>
5
+
6
+ <h1 align="center">Mnemos</h1>
7
+
8
+ <p align="center">
9
+ <strong>Сервер памяти и знаний для AI-агентов</strong><br>
10
+ <em>назван в честь титаниды памяти, создан для AI-агентов, которым нужна память</em>
11
+ </p>
12
+
13
+ <p align="center">
14
+ <a href="pyproject.toml"><img src="https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-3776ab" alt="Python"></a>
15
+ <a href="pyproject.toml"><img src="https://img.shields.io/badge/license-MIT-blue" alt="License: MIT"></a>
16
+ <a href="https://github.com/Korrnals/mnemos/releases"><img src="https://img.shields.io/github/v/release/Korrnals/mnemos?label=version&color=blueviolet" alt="Version"></a>
17
+ </p>
18
+
19
+ <p align="center">
20
+ <a href="README.md">🇬🇧 English</a> · <strong>🇷🇺 Русский</strong>
21
+ </p>
22
+
23
+ <p align="center">
24
+ <a href="#-возможности">Возможности</a> ·
25
+ <a href="#-быстрый-старт">Быстрый старт</a> ·
26
+ <a href="#-что-такое-mnemos">Что это</a> ·
27
+ <a href="#%EF%B8%8F-архитектура">Архитектура</a> ·
28
+ <a href="#%EF%B8%8F-три-поверхности-одно-ядро">Поверхности</a> ·
29
+ <a href="#-документация">Документация</a>
30
+ </p>
31
+
32
+ ---
33
+
34
+ ## ✨ Возможности
35
+
36
+ Один локальный сервер — и подключённый агентский харнес получает полный стек памяти.
37
+
38
+ | Область | Что даёт |
39
+ |---------|----------|
40
+ | **Универсальное подключение** | MCP-сервер (26 инструментов, stdio) + REST API — любой харнесс с поддержкой MCP подключается одной строкой ([инструменты](docs/ru/user/mcp-tools.md) · [HTTP](docs/ru/user/http-api.md)) |
41
+ | **Готовые интеграции** | zcode, стандарт `~/.agents` (Claude / Codex / Continue / Qwen и др.), pi — через [`mnemos integration`](docs/ru/user/integration-guide.md): таргеты развёртывания, однострочные MCP-пресеты, доктор мульти-харнесов |
42
+ | **Пакет скиллов** | 14+ скиллов памяти деплоятся в харнесы |
43
+ | **Гибкая память** | Гибридный поиск (полнотекстовый + векторный, слияние ранжирования), [теги-контракт](docs/ru/user/tag-contract.md), память по агентам и проектам, профили [контекстного фильтра](docs/ru/user/context-filter.md), сжатие CCR — экономия 70–90% токенов, оригиналы сохраняются |
44
+ | **Сборка контекста** | `assemble_context`: поиск → сжатие → фильтр → скан секретов → выравнивание кэша → бюджет токенов, провенанс каждого блока |
45
+ | **Мост контекста** | `on_context_rewrite` — при сжатии истории харнессом оригинал без потерь доступен по требованию |
46
+ | **Хуки жизненного цикла** | `pre_llm_call` (впрыск контекста перед запросом модели), `on_session_start`, `post_tool_call` (авто-сжатие выводов инструментов) |
47
+ | **Публикация v3.0.0** | Запись видна сразу после сохранения, фоновая дообработка с бесшовной подменой, карантин с нейтральной ретракцией |
48
+ | **Автозащита** | Детекторы инъекций / секретов на входе и публикации, скан каждой выдачи, полный аудит с привязкой к записи |
49
+ | **Автоконвейер** | Фоновый обработчик: кластеризация, дедупликация, гейт качества, публикация |
50
+
51
+ Автономность для произвольного харнесса, LLM-дообогащение и публикация пакетов
52
+ (PyPI / npm) — частично; полная честная карта: [docs/ru/features.md](docs/ru/features.md).
53
+
54
+ ---
55
+
56
+ ## 🚀 Быстрый старт
57
+
58
+ Четыре шага до рабочего хранилища памяти, подключённого к VS Code Copilot.
59
+
60
+ ### 1 · Установка
61
+
62
+ ```bash
63
+ curl -fsSL https://raw.githubusercontent.com/Korrnals/mnemos/main/scripts/install.sh | bash
64
+ ```
65
+
66
+ Установщик делает всё за вас — знание Python или venv не требуется:
67
+
68
+ - создаёт изолированное окружение в `~/.mnemos/venv`;
69
+ - кладёт лаунчер `mnemos` в `~/.local/bin`, чтобы CLI работал в любом шелле (**активировать venv не нужно**);
70
+ - тут же предлагает настроить интеграцию VS Code MCP (или сделайте это позже — см. шаг 3).
71
+
72
+ > Нужен неинтерактивный запуск? Добавьте `--mcp` / `--no-mcp`, чтобы выбрать заранее, например
73
+ > `… | bash -s -- --mcp`.
74
+
75
+ ### 2 · Запись и поиск
76
+
77
+ ```bash
78
+ mnemos add "Первая запись — Mnemos помнит между сессиями" \
79
+ --tags project:mnemos,agent:tech-writer,mnemos:learning
80
+
81
+ mnemos search "помнит между сессиями"
82
+ ```
83
+
84
+ Это весь цикл: **записал, нашёл, не потерял.** Каждая запись несёт
85
+ [контракт тегов](docs/ru/user/tag-contract.md) (`project:` / `agent:` / `mnemos:`), чтобы память оставалась упорядоченной.
86
+
87
+ ### 3 · Подключение к VS Code (MCP)
88
+
89
+ Если во время установки вы ответили **да** — всё готово, просто перезагрузите окно VS Code.
90
+ Чтобы настроить вручную или на другой машине:
91
+
92
+ ```bash
93
+ curl -fsSL https://raw.githubusercontent.com/Korrnals/mnemos/main/scripts/mcp-setup.sh | bash
94
+ ```
95
+
96
+ Затем **перезагрузите окно VS Code** (`Ctrl+Shift+P → Reload Window`). Инструменты `mnemos_*` появятся
97
+ в палитре инструментов Copilot, и агенты смогут вызывать `mnemos_add` / `mnemos_search` напрямую.
98
+
99
+ ### 4 · Установка поведенческих инструкций
100
+
101
+ ```bash
102
+ mnemos integration setup
103
+ ```
104
+
105
+ Развёртывает инструкции использования памяти, скилы и режим промпта в ваш
106
+ агентский харнес (Copilot `~/.copilot/`, обычный Copilot, Cursor). Агенты теперь
107
+ *знают когда и как* использовать память Mnemos — а не просто имеют инструменты.
108
+
109
+ Добавьте `--wire-agents --all`, чтобы в том же проходе выдать инструменты
110
+ `mnemos/*` во фронтматтер Copilot-агентов. См. [руководство по интеграции](docs/ru/user/integration-guide.md#подключение-mcp-инструментов-к-агентам)
111
+ по флагам wiring и [руководство по контекстному фильтру](docs/ru/user/context-filter.md)
112
+ — пятиступенчатый очиститель шума, который запускается автоматически при каждом `mnemos_add`.
113
+
114
+ <details>
115
+ <summary><strong>🛠️ Другие способы установки</strong> — из исходников, готовый wheel или контейнер</summary>
116
+
117
+ <br>
118
+
119
+ **Из исходников** (для разработки):
120
+
121
+ ```bash
122
+ git clone https://github.com/Korrnals/mnemos.git
123
+ cd mnemos
124
+ uv venv && source .venv/bin/activate
125
+ uv pip install -e ".[dev]"
126
+ ```
127
+
128
+ **Готовый wheel** (зафиксировать конкретную версию):
129
+
130
+ <!-- version:pip -->
131
+ ```bash
132
+ pip install https://github.com/Korrnals/mnemos/releases/download/v3.0.0/mnemos-3.0.0-py3-none-any.whl
133
+ ```
134
+ <!-- /version:pip -->
135
+
136
+ **Контейнер одной командой** — скачивает образ, создаёт тома, запускает на порту 8787:
137
+
138
+ ```bash
139
+ export MNEMOS_API__TOTP_MASTER_KEY=$(python3 -c "import secrets; print(secrets.token_urlsafe(32))")
140
+ curl -fsSL https://raw.githubusercontent.com/Korrnals/mnemos/main/scripts/install.sh | bash -s -- --container
141
+ ```
142
+
143
+ Полное руководство — [container-deployment.md](docs/ru/admin/runbooks/container-deployment.md).
144
+
145
+ </details>
146
+
147
+ <details>
148
+ <summary><strong>🐳 Запуск готового образа напрямую (GHCR)</strong></summary>
149
+
150
+ <br>
151
+
152
+ Образ публикуется в `ghcr.io/korrnals/mnemos` при каждом release-теге.
153
+
154
+ ```bash
155
+ # Сгенерируйте TOTP-ключ (обязательно — контейнер слушает 0.0.0.0)
156
+ export MNEMOS_API__TOTP_MASTER_KEY=$(python3 -c "import secrets; print(secrets.token_urlsafe(32))")
157
+
158
+ podman run -d --name mnemos \
159
+ -p 8787:8787 \
160
+ -v mnemos-data:/data \
161
+ -v mnemos-vault:/vault \
162
+ -e MNEMOS_API__TOTP_MASTER_KEY="${MNEMOS_API__TOTP_MASTER_KEY}" \
163
+ <!-- version:image -->
164
+ ghcr.io/korrnals/mnemos:3.0.0
165
+ <!-- /version:image -->
166
+
167
+ curl -s http://localhost:8787/health | jq
168
+ ```
169
+
170
+ <!-- version:tags -->
171
+ Теги: `:3.0.0` (фиксированная) · `:latest` (rolling). Работает и с `docker` — замените `podman` на `docker`.
172
+ <!-- /version:tags -->
173
+
174
+ </details>
175
+
176
+ > 📘 Пошаговое руководство первого запуска с MCP- и HTTP-серверами —
177
+ > [getting-started.md](docs/ru/user/getting-started.md).
178
+
179
+ ---
180
+
181
+ ## 🧩 Что такое Mnemos
182
+
183
+ **Однотенантный, локально-ориентированный сервер памяти** для AI-агентов. Одно ядро in-process, три
184
+ эквивалентных поверхности управления и слой хранения, который можно прочитать своими глазами.
185
+
186
+ | | Возможность | Что это даёт |
187
+ |---|------------|-------------------|
188
+ | 🔎 | **Гибридный поиск** | Векторная близость + полнотекстовый FTS5 по каждой записи |
189
+ | 🧪 | **Конвейер знаний** | Жизненный цикл `raw → processing → processed → published` с конечным автоматом |
190
+ | 🧠 | **Recall на агента** | Сфокусированная поверхность recall в контексте проекта каждого агента |
191
+ | ⚙️ | **Движок политик** | Планирование и триггеры автоматизации над хранилищем памяти |
192
+ | 🧹 | **Контекстный фильтр** | Пятиступенчатая очистка логов / stdout перед отправкой модели |
193
+ | 🗜️ | **Обратимое сжатие (CCR)** | Сжатие большого контента без потери данных — оригиналы кэшируются в SQLite, извлекаются по хеш-маркеру |
194
+ | 🧷 | **CacheAligner (P1-5)** | Перенос динамического контента (таймстампы, UUID, session id, токены) в хвост, чтобы KV-кэши провайдеров (Anthropic `cache_control`, OpenAI prefix caching) попадали между запросами |
195
+ | 🪶 | **Сокращение токенов вывода (P1-7)** | Опциональные параметры `verbosity` / `effort` на `mnemos_add` / `mnemos_search` / `mnemos_recall_context` управляют стилем вывода вызывающей стороны — обратная совместимость, значения по умолчанию — no-op |
196
+ | 📂 | **Path-scoped rules** | Ингест правил проекта и применение их по пути файла |
197
+ | 🗂️ | **Obsidian vault** | Markdown-зеркало, которое люди могут смотреть, править и grep'ать |
198
+
199
+ SQLite для метаданных, локальный векторный индекс на numpy + SQLite для recall и Obsidian-совместимый
200
+ vault для людей в процессе.
201
+
202
+ ---
203
+
204
+ ## 🏗️ Архитектура
205
+
206
+ <details open>
207
+ <summary><strong>Схема системы</strong> — клиенты → интерфейсы → ядро → хранилище</summary>
208
+
209
+ <br>
210
+
211
+ ```mermaid
212
+ flowchart TB
213
+ subgraph CLIENTS["Клиенты"]
214
+ C1(["VS Code · Copilot\nstdio MCP"])
215
+ C2(["CLI — mnemos …"])
216
+ C3(["HTTP API клиент"])
217
+ end
218
+
219
+ subgraph IFACE["Слой интерфейсов"]
220
+ MCP["mcp_server.py"]
221
+ FAPI["api/main.py · FastAPI"]
222
+ TYPER["cli/main.py · Typer"]
223
+ end
224
+
225
+ MGR(["MemoryManager\nmanager.py"])
226
+
227
+ subgraph PROC["Подсистемы обработки"]
228
+ CF["Context Filter\nfilter/"]
229
+ PP["Knowledge Pipeline\npipeline/"]
230
+ RE["Recall Engine\nrecall/"]
231
+ PE["Policy Engine\npolicy/"]
232
+ end
233
+
234
+ subgraph BG["Фоновые сервисы"]
235
+ WA["Watchers\nwatchers/"]
236
+ AC["Auto-collect\nauto_collect.py"]
237
+ end
238
+
239
+ subgraph STORE["Слой хранения"]
240
+ SQ[("SQLite\nFTS5 · traces · projects")]
241
+ VS[("Vector Store\nnumpy + SQLite")]
242
+ VLT[("Obsidian Vault\nmarkdown mirror")]
243
+ end
244
+
245
+ C1 -->|"stdio"| MCP
246
+ C2 --> TYPER
247
+ C3 --> FAPI
248
+ MCP --> MGR
249
+ TYPER --> MGR
250
+ FAPI --> MGR
251
+ MGR --> CF
252
+ MGR --> PP
253
+ MGR --> RE
254
+ MGR --> SQ
255
+ MGR --> VS
256
+ MGR --> VLT
257
+ CF -.->|"raw + clean"| SQ
258
+ PP -->|"status transitions"| SQ
259
+ PP -->|"published upsert"| VS
260
+ RE -->|"FTS5 MATCH"| SQ
261
+ RE -->|"cosine search"| VS
262
+ PE -->|"schedule / trigger"| MGR
263
+ WA -->|"file events"| MGR
264
+ AC -.->|"checkpoint reminder"| MCP
265
+ ```
266
+
267
+ </details>
268
+
269
+ Более глубокий разбор — модель данных, конечные автоматы, границы безопасности, эксплуатационные аспекты —
270
+ в [architecture/overview.md](docs/ru/architecture/overview.md).
271
+
272
+ ---
273
+
274
+ ## 🎛️ Три поверхности, одно ядро
275
+
276
+ Один и тот же `MemoryManager` управляет всеми тремя интерфейсами. Выберите подходящий клиенту.
277
+
278
+ | Поверхность | Когда использовать… | Документация |
279
+ |---------|--------------|-----------|
280
+ | **CLI** — `mnemos …` | Вы работаете в шелле, нужен быстрый ad-hoc add / search или скрипты cron | [cli-reference.md](docs/ru/user/cli-reference.md) |
281
+ | **HTTP** — `mnemos serve` | У вас не-MCP клиент — веб-дашборд, мобильное приложение, CI runner | [http-api.md](docs/ru/user/http-api.md) |
282
+ | **MCP** — `mnemos mcp-server` | Вы VS Code Copilot или любой MCP-aware агент — путь Copilot-агентов | [mcp-tools.md](docs/ru/user/mcp-tools.md) |
283
+
284
+ MCP-поверхность также предоставляет **A2A Sessions API** (M16) — постоянный бэкенд для многошаговых
285
+ разговоров агентов. Пять endpoints (`POST /v1/sessions`, append-turn, range-load, …) позволяют агентам
286
+ переживать рестарты без потери контекста. См. [a2a-sessions.md](docs/ru/architecture/a2a-sessions.md).
287
+
288
+ ---
289
+
290
+ ## 📖 Лор
291
+
292
+ > В «Теогонии» Гесиода **Мнемосина** (Μνημοσύνη) — титанида памяти. Она, от Зевса, родила девять муз и
293
+ > через них сделала возможным воспоминание мира. Её имя — корень слова *мнемонический*, и к ней обращается
294
+ > каждый певец, поэт и философ, прежде чем начать.
295
+
296
+ Это программное обеспечение носит её имя, потому что создано для той же задачи: **сделать воспоминание
297
+ возможным для тех, кто мыслит.** AI-агенты, оторванные от единственного разговора, теряют всё, что было
298
+ до. Mnemos даёт им место, где можно это сохранить — структурированно, с поиском, по контракту — чтобы то,
299
+ что они узнали, не исчезало с закрытием сессии. Музы, в конце концов, были не для богов. Они были для
300
+ песен.
301
+
302
+ ---
303
+
304
+ ## 📚 Документация
305
+
306
+ | Страница | Содержание |
307
+ |------|----------------|
308
+ | [docs/README.md](docs/README.md) | Главная страница документации — выбор языка (EN / RU) |
309
+ | [getting-started.md](docs/ru/user/getting-started.md) | Первый запуск: установка → первая запись → первый поиск → MCP / HTTP |
310
+ | [architecture/overview.md](docs/ru/architecture/overview.md) | Архитектура, модель данных, конечные автоматы, границы безопасности |
311
+ | [cli-reference.md](docs/ru/user/cli-reference.md) | Все подкоманды `mnemos` с флагами, значениями по умолчанию, примерами |
312
+ | [mcp-tools.md](docs/ru/user/mcp-tools.md) | Все инструменты `mnemos_*` для VS Code Copilot |
313
+ | [http-api.md](docs/ru/user/http-api.md) | Все HTTP endpoints (CRUD памяти + A2A Sessions, M16) |
314
+ | [a2a-sessions.md](docs/ru/architecture/a2a-sessions.md) | Контракт agent-to-agent разговоров (M16) |
315
+ | [tag-contract.md](docs/ru/user/tag-contract.md) | Схема `project:` / `agent:` / `mnemos:`, обязательная для каждой записи |
316
+ | [security.md](docs/ru/admin/security.md) | Модель угроз, SSRF-защита, FTS5 escape, пиннинг HF Hub |
317
+ | [runbooks/](docs/ru/admin/runbooks/) | Установка, миграция, резервное копирование, обновление зависимостей |
318
+ | [container-deployment.md](docs/ru/admin/runbooks/container-deployment.md) | Сборка, push, compose, podman, Kubernetes, quadlet |
319
+ | [adr/](docs/project/adr/) | Архитектурные решения (ADR) — *почему* за каждым дизайном |
320
+ | [milestones.md](docs/project/milestones.md) | Журнал milestones со статусами |
321
+ | [reports/](docs/project/reports/) | Отчёты о завершённых этапах — итоговый отчёт по каждой фазе дорожной карты |
322
+ | [CHANGELOG.md](CHANGELOG.md) | Release notes — формат Keep a Changelog |
323
+
324
+ ---
325
+
326
+ ## 🤝 Интеграции
327
+
328
+ Mnemos работает с любым харнессом, говорящим по MCP. Три уровня интеграции —
329
+ выберите самый сильный из доступных для вашего харнесса:
330
+
331
+ | Харнесс | Нативная цель | Однострочный MCP-пресет | Шаблон адаптера |
332
+ |---------|---------------|-------------------------|-----------------|
333
+ | VS Code Copilot | `copilot` (+ промпты через `generic-copilot`) | [mcp-setup.sh](scripts/mcp-setup.sh) | ✓ |
334
+ | Claude Code | через `agents` | [пресет](integrations/mcp-presets.md#claude-code) | ✓ |
335
+ | Cursor | `cursor` | [пресет](integrations/mcp-presets.md#cursor) | ✓ |
336
+ | Codex | через `agents` | [пресет](integrations/mcp-presets.md#codex) | ✓ |
337
+ | Windsurf | — | [пресет](integrations/mcp-presets.md#windsurf) | ✓ |
338
+ | ZCode | `zcode` | — | ✓ |
339
+ | Любой харнесс стандарта AGENTS.md | `agents` | — | ✓ |
340
+ | [Hermes Agent](https://hermes-agent.nousresearch.com/) | `hermes` (нативный `MemoryProvider` плагин) | — | — |
341
+
342
+ - **[Hermes Agent](https://hermes-agent.nousresearch.com/)** — нативный `MemoryProvider` плагин
343
+ (`integrations/hermes/`): автоматический prefetch, sync-turn, зеркалирование встроенной памяти.
344
+ С версии плагина **3.0.0** (ADR-0017 D1) плагин работает **in-process** — требуется `pip install mnemos`
345
+ в Python-окружении Hermes, а легаси-ключи конфигурации `base_url` / `api_key` / `totp_secret` удалены.
346
+ См. [руководство по интеграции](docs/ru/user/integration-guide.md#hermes-agent).
347
+ - **Нативные цели** — `mnemos integration setup --target <имя>` развёртывает
348
+ поведенческий пакет и регистрирует MCP-сервер за один проход. См.
349
+ [руководство по интеграции](docs/ru/user/integration-guide.md).
350
+ - **Однострочные MCP-пресеты** — [`integrations/mcp-presets.md`](integrations/mcp-presets.md):
351
+ Cursor, Claude Code, Codex и Windsurf подключаются вставкой одной строки.
352
+ - **Шаблон адаптера** — [`integrations/adapter-template.md`](integrations/adapter-template.md):
353
+ Connect / Expose / Configure + чеклист приёмки для любого харнесса,
354
+ говорящего по MCP stdio.
355
+
356
+ Общий контракт — [схема тегов](docs/ru/user/tag-contract.md) — `project:<slug>`, `agent:<slug>`
357
+ и хотя бы один `mnemos:<subtype>` — которую должна нести каждая запись.
358
+
359
+ ---
360
+
361
+ ## ⚖️ Исходный код и лицензия
362
+
363
+ - **Исходник** — этот репозиторий, [github.com/Korrnals/mnemos](https://github.com/Korrnals/mnemos).
364
+ - **Лицензия** — MIT (см. [pyproject.toml](pyproject.toml)).
365
+
366
+ ## 🌱 Участие
367
+
368
+ PR приветствуются. Прочитайте [PLAN.md](PLAN.md) для roadmap и следуйте конвенциям в [docs/](docs/).
369
+
370
+ Git-workflow: `feat/*` → `dev-<этап>` → `release/X.Y.Z` → `main`; `main` принимает только `release/*` и
371
+ `hotfix/*` PR. Обязательны Conventional Commits. Запустите `make verify` перед открытием PR.
372
+
373
+ ---
374
+
375
+ <p align="center">
376
+ <sub><strong>Воспроизведите зелёное состояние:</strong> <code>make verify</code> запускает полный
377
+ quality gate — ruff + mypy --strict + bandit + pip-audit + 802 тестов. Если зелёно — готово к публикации.</sub>
378
+ </p>
@@ -0,0 +1,178 @@
1
+ /**
2
+ * mnemos-mcp — MCP bridge for the Pi coding agent.
3
+ *
4
+ * Pi (npm @earendil-works/pi-coding-agent)
5
+ * has no built-in MCP client by design: tools arrive via TypeScript
6
+ * extensions. This extension spawns `mnemos mcp-server` over stdio, performs
7
+ * the MCP handshake and registers every `mnemos_*` tool as a native Pi tool.
8
+ *
9
+ * Deployed by: mnemos integration setup --target pi
10
+ * Location: ~/.pi/agent/extensions/mnemos-mcp.ts
11
+ * Requires: `mnemos` on PATH (override with MNEMOS_BIN env var).
12
+ * Reload: /reload (Pi hot-reloads extensions) or /mnemos to reconnect.
13
+ */
14
+
15
+ import { spawn, type ChildProcess } from "node:child_process";
16
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
17
+ import { Type } from "typebox";
18
+
19
+ const MNEMOS_BIN = process.env.MNEMOS_BIN ?? "mnemos";
20
+ const REQ_TIMEOUT_MS = 60_000;
21
+
22
+ interface McpTool {
23
+ name: string;
24
+ description?: string;
25
+ inputSchema?: Record<string, unknown>;
26
+ }
27
+
28
+ export default function mnemosMcpBridge(pi: ExtensionAPI) {
29
+ let child: ChildProcess | null = null;
30
+ let nextId = 1;
31
+ let buffer = "";
32
+ let started = false;
33
+ let registeredNames = new Set<string>();
34
+ const pending = new Map<
35
+ number,
36
+ { resolve: (v: unknown) => void; reject: (e: Error) => void; timer: NodeJS.Timeout }
37
+ >();
38
+
39
+ // ── JSON-RPC plumbing ──────────────────────────────────────────────────
40
+ function send(obj: unknown): void {
41
+ if (!child?.stdin?.writable) throw new Error("mnemos MCP: stdin not writable");
42
+ child.stdin.write(JSON.stringify(obj) + "\n");
43
+ }
44
+
45
+ function request(method: string, params?: unknown): Promise<any> {
46
+ const id = nextId++;
47
+ return new Promise((resolve, reject) => {
48
+ const timer = setTimeout(() => {
49
+ pending.delete(id);
50
+ reject(new Error(`mnemos MCP: timeout on ${method}`));
51
+ }, REQ_TIMEOUT_MS);
52
+ pending.set(id, { resolve, reject, timer });
53
+ send({ jsonrpc: "2.0", id, method, params });
54
+ });
55
+ }
56
+
57
+ function handleLine(line: string): void {
58
+ line = line.trim();
59
+ if (!line) return;
60
+ let msg: any;
61
+ try {
62
+ msg = JSON.parse(line);
63
+ } catch {
64
+ return; // non-RPC noise on stdout
65
+ }
66
+ if (msg.id !== undefined && pending.has(msg.id)) {
67
+ const p = pending.get(msg.id)!;
68
+ pending.delete(msg.id);
69
+ clearTimeout(p.timer);
70
+ if (msg.error) p.reject(new Error(msg.error.message ?? JSON.stringify(msg.error)));
71
+ else p.resolve(msg.result);
72
+ }
73
+ // Server notifications (progress, …) are intentionally ignored.
74
+ }
75
+
76
+ function killChild(): void {
77
+ child?.stdin?.end();
78
+ child?.kill("SIGTERM");
79
+ child = null;
80
+ started = false;
81
+ }
82
+
83
+ async function startBridge(): Promise<McpTool[]> {
84
+ if (child) killChild();
85
+ buffer = "";
86
+ child = spawn(MNEMOS_BIN, ["mcp-server"], { stdio: ["pipe", "pipe", "ignore"] });
87
+ child.on("error", (e: Error) => {
88
+ started = false;
89
+ });
90
+ child.stdout!.setEncoding("utf8");
91
+ child.stdout!.on("data", (chunk: string) => {
92
+ buffer += chunk;
93
+ let nl: number;
94
+ while ((nl = buffer.indexOf("\n")) >= 0) {
95
+ handleLine(buffer.slice(0, nl));
96
+ buffer = buffer.slice(nl + 1);
97
+ }
98
+ });
99
+ child.on("exit", () => {
100
+ started = false;
101
+ for (const [, p] of pending) {
102
+ clearTimeout(p.timer);
103
+ p.reject(new Error("mnemos MCP: server exited"));
104
+ }
105
+ pending.clear();
106
+ });
107
+
108
+ await request("initialize", {
109
+ protocolVersion: "2024-11-05",
110
+ capabilities: {},
111
+ clientInfo: { name: "pi-mnemos-bridge", version: "1.0.0" },
112
+ });
113
+ send({ jsonrpc: "2.0", method: "notifications/initialized" });
114
+ const res = await request("tools/list", {});
115
+ started = true;
116
+ return (res.tools ?? []) as McpTool[];
117
+ }
118
+
119
+ // ── Register MCP tools as native Pi tools ───────────────────────────────
120
+ function registerTool(tool: McpTool): boolean {
121
+ if (registeredNames.has(tool.name)) return false;
122
+ const schema =
123
+ tool.inputSchema && tool.inputSchema.type === "object"
124
+ ? Type.Unsafe(tool.inputSchema)
125
+ : Type.Object({});
126
+
127
+ pi.registerTool({
128
+ name: tool.name,
129
+ label: tool.name.replace(/^mnemos_/, "🧠 "),
130
+ description: tool.description ?? `mnemos MCP tool ${tool.name}`,
131
+ promptSnippet: `Persistent shared memory: ${tool.description?.slice(0, 120) ?? tool.name}`,
132
+ parameters: schema as never,
133
+ async execute(_toolCallId: string, params: unknown) {
134
+ if (!started) await startBridge();
135
+ const result = await request("tools/call", {
136
+ name: tool.name,
137
+ arguments: params,
138
+ });
139
+ const parts: Array<{ type: string; text?: string }> = result.content ?? [];
140
+ const text = parts
141
+ .map((p) => (p.type === "text" ? p.text ?? "" : `[${p.type}]`))
142
+ .join("\n")
143
+ .trim();
144
+ return {
145
+ content: [{ type: "text", text: text || "(empty result)" }],
146
+ details: { isError: result.isError ?? false },
147
+ };
148
+ },
149
+ });
150
+ registeredNames.add(tool.name);
151
+ return true;
152
+ }
153
+
154
+ async function connect(ctx: { ui?: { notify: (m: string, l?: string) => void } }): Promise<void> {
155
+ try {
156
+ const tools = await startBridge();
157
+ registeredNames = new Set();
158
+ let fresh = 0;
159
+ for (const t of tools) if (registerTool(t)) fresh++;
160
+ ctx.ui?.notify(`🧠 mnemos: ${fresh} memory tools online (${tools.length} served)`, "info");
161
+ } catch (e) {
162
+ ctx.ui?.notify(`🧠 mnemos: bridge failed — ${(e as Error).message}`, "warning");
163
+ }
164
+ }
165
+
166
+ // ── Lifecycle ────────────────────────────────────────────────────────────
167
+ pi.on("session_start", (_event: unknown, ctx: Parameters<Parameters<typeof pi.on>[1]>[1]) =>
168
+ connect(ctx as { ui?: { notify: (m: string, l?: string) => void } }),
169
+ );
170
+ pi.on("session_end", () => killChild());
171
+ process.on("exit", () => killChild());
172
+
173
+ // Manual control: /mnemos reconnects the bridge and re-registers tools.
174
+ pi.registerCommand("mnemos", {
175
+ description: "Reconnect the mnemos MCP memory bridge",
176
+ handler: async (_args: string, ctx: any) => connect(ctx),
177
+ });
178
+ }
@@ -0,0 +1,2 @@
1
+ # Skill files (SKILL.md) are added by Stream B (Tech Writer).
2
+ # This directory is the source pack shipped with the package.
@@ -0,0 +1,53 @@
1
+ ---
2
+ name: mnemos-agent-recall
3
+ description: Agent-scoped memory recall — what did THIS agent (or a teammate) previously learn, decide, or leave open
4
+ ---
5
+
6
+ # Mnemos Agent Recall
7
+
8
+ Pull the latest memories written by a specific agent slug (yours or a
9
+ teammate's). Use it to resume another agent's thread of work or to check
10
+ what a specialist agent already established before duplicating it.
11
+
12
+ ## WHEN
13
+
14
+ - **Resuming work after a context reset** — your own latest entries first.
15
+ - **Taking over from another agent** — review their trail before changing
16
+ their decisions.
17
+ - **Team coordination** — check what `gcw-tech-lead` / `reviewer` / etc.
18
+ already decided in this project.
19
+
20
+ ## STEPS
21
+
22
+ 1. **Recall your own trail**:
23
+
24
+ ```text
25
+ mnemos_agent_recall(agent=<your-slug>, limit=10)
26
+ ```
27
+
28
+ 2. **Scope to the project** to cut noise from other work:
29
+
30
+ ```text
31
+ mnemos_agent_recall(agent=<slug>, project=<project-slug>, limit=10)
32
+ ```
33
+
34
+ 3. **Narrow with a query** when the trail is long:
35
+
36
+ ```text
37
+ mnemos_agent_recall(agent=<slug>, query="auth refactor", limit=5)
38
+ ```
39
+
40
+ 4. **For open work**, follow up with `mnemos_workflow(action="get", …)` on
41
+ entries tagged `mnemos:open-question`.
42
+
43
+ ## DISCIPLINE
44
+
45
+ - Agent recall is a **trail, not a search** — for topical questions use
46
+ `mnemos-recall` (hybrid search) instead.
47
+ - Entries appear newest-first; if the trail is stale, check
48
+ `mnemos_list_recent` before assuming the agent stopped writing.
49
+
50
+ ## See also
51
+
52
+ - Skill `mnemos-recall` — topical semantic search
53
+ - Skill `mnemos-workflow` — lifecycle of open questions
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: mnemos-cache-align
3
+ description: Stabilize prompt prefixes for provider KV caches — move dynamic tokens to the end before caching matters
4
+ ---
5
+
6
+ # Mnemos Cache Align
7
+
8
+ Relocate dynamic content (timestamps, UUIDs, session ids, tokens) to the
9
+ END of a text so its prefix stays byte-identical across requests. That
10
+ makes provider KV caches (Anthropic cache_control, OpenAI prefix caching)
11
+ actually hit.
12
+
13
+ ## WHEN
14
+
15
+ - **Repeated calls with a large shared prefix** — system prompts, tool
16
+ definitions, style guides — with only a volatile tail.
17
+ - **Cache hit-rate is poor** despite stable-looking prompts — hidden
18
+ timestamps/ids at the top are usually the cause.
19
+ - **Building a prompt template** that will fire many times.
20
+
21
+ ## STEPS
22
+
23
+ 1. **Align the text**:
24
+
25
+ ```text
26
+ mnemos_align_prefix(text=<prompt>, profile="code")
27
+ ```
28
+
29
+ Profiles: `code` (keeps bare identifiers in place — avoids mangling
30
+ long symbol names), `docs`, `default`.
31
+
32
+ 2. **Use the aligned text** as the stable prefix; append the truly
33
+ per-request values AFTER it.
34
+
35
+ 3. **Verify by diffing** two aligned outputs for the same logical content —
36
+ the prefix must be byte-identical.
37
+
38
+ ## DISCIPLINE
39
+
40
+ - Align ONCE at template build time, not per request.
41
+ - Don't align user-facing prose where order carries meaning — this is for
42
+ machine-consumed prompts.
43
+ - `code` profile skips bare tokens deliberately; the default profile is
44
+ more aggressive.
45
+
46
+ ## See also
47
+
48
+ - Skill `mnemos-compress` — shrinking big outputs that changed anyway