@dinasor/mnemo-cli 0.0.1
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/CHANGELOG.md +46 -0
- package/LICENSE +21 -0
- package/README.md +263 -0
- package/VERSION +1 -0
- package/bin/mnemo.js +139 -0
- package/memory.ps1 +178 -0
- package/memory_mac.sh +2447 -0
- package/package.json +36 -0
- package/scripts/memory/installer/bootstrap.ps1 +21 -0
- package/scripts/memory/installer/core/bridge.ps1 +285 -0
- package/scripts/memory/installer/core/io.ps1 +110 -0
- package/scripts/memory/installer/core/paths.ps1 +83 -0
- package/scripts/memory/installer/features/gitignore_setup.ps1 +80 -0
- package/scripts/memory/installer/features/hooks_setup.ps1 +157 -0
- package/scripts/memory/installer/features/mcp_setup.ps1 +87 -0
- package/scripts/memory/installer/features/memory_scaffold.ps1 +541 -0
- package/scripts/memory/installer/features/vector_setup.ps1 +103 -0
- package/scripts/memory/installer/templates/add-journal-entry.ps1 +122 -0
- package/scripts/memory/installer/templates/add-lesson.ps1 +151 -0
- package/scripts/memory/installer/templates/autonomy/__init__.py +6 -0
- package/scripts/memory/installer/templates/autonomy/context_safety.py +181 -0
- package/scripts/memory/installer/templates/autonomy/entity_resolver.py +215 -0
- package/scripts/memory/installer/templates/autonomy/ingest_pipeline.py +252 -0
- package/scripts/memory/installer/templates/autonomy/lifecycle_engine.py +254 -0
- package/scripts/memory/installer/templates/autonomy/policies.yaml +59 -0
- package/scripts/memory/installer/templates/autonomy/reranker.py +220 -0
- package/scripts/memory/installer/templates/autonomy/retrieval_router.py +148 -0
- package/scripts/memory/installer/templates/autonomy/runner.py +272 -0
- package/scripts/memory/installer/templates/autonomy/schema.py +150 -0
- package/scripts/memory/installer/templates/autonomy/vault_policy.py +205 -0
- package/scripts/memory/installer/templates/build-memory-sqlite.py +111 -0
- package/scripts/memory/installer/templates/clear-active.ps1 +55 -0
- package/scripts/memory/installer/templates/customization.md +84 -0
- package/scripts/memory/installer/templates/lint-memory.ps1 +217 -0
- package/scripts/memory/installer/templates/mnemo_vector.py +556 -0
- package/scripts/memory/installer/templates/query-memory-sqlite.py +95 -0
- package/scripts/memory/installer/templates/query-memory.ps1 +122 -0
- package/scripts/memory/installer/templates/rebuild-memory-index.ps1 +293 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Mnemo are documented here.
|
|
4
|
+
|
|
5
|
+
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Mnemo uses [Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.0.1] - 2026-02-21
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- First public Mnemo release with dual installers: `memory.ps1` (Windows PowerShell 5.1+/7+) and `memory_mac.sh` (macOS/Linux POSIX shell).
|
|
13
|
+
- Installer CLI support for `--dry-run` / `-DryRun`, `--force` / `-Force`, project naming, and optional vector enablement.
|
|
14
|
+
- Modular installer architecture with dedicated core and feature modules under `scripts/memory/installer/` (bootstrap, path resolution, I/O, bridges, scaffold, hooks, vector, MCP, `.gitignore`).
|
|
15
|
+
- Canonical memory root at `.mnemo/` with compatibility bridges to `.cursor/` and `.agent/` so existing IDE integrations continue to work.
|
|
16
|
+
- Bridge manager with cross-platform fallback behavior (symlink/junction/hardlink/mirror) and repair/migration logic for legacy layouts.
|
|
17
|
+
- Canonical memory scaffold including always-read files (`hot-rules.md`, `active-context.md`, `memo.md`), lessons, journals, digests, ADR, and templates.
|
|
18
|
+
- Atomic lesson workflow (`L-XXX-*`) and monthly journal workflow with rebuildable indexes/digests.
|
|
19
|
+
- Helper script suite for daily operations (PowerShell + shell variants): rebuild index, lint memory, query memory, add lesson, add journal entry, clear active context.
|
|
20
|
+
- Tag vocabulary enforcement and memory lint guardrails for frontmatter, structure, and token-safety checks.
|
|
21
|
+
- Optional SQLite FTS support (`memory.sqlite`) when Python is available, including build/query helpers.
|
|
22
|
+
- Optional vector mode with `mnemo_vector.py` MCP server and tools: `vector_search`, `vector_sync`, `vector_forget`, `vector_health`, `memory_status`.
|
|
23
|
+
- Vector embedding provider support for both OpenAI and Gemini.
|
|
24
|
+
- Autonomy runtime templates installed with vector mode (`autonomy/*` + `policies.yaml`) for ingestion, lifecycle, reranking, context safety, and policy handling.
|
|
25
|
+
- Portable git hooks via `.githooks/` with automatic `core.hooksPath` setup.
|
|
26
|
+
- Hook automation: `pre-commit` rebuild/lint and optional `post-commit` non-blocking vector sync.
|
|
27
|
+
- Multi-agent bridge outputs: `CLAUDE.md`, `AGENTS.md`, and `.agent/rules/memory-system.md`.
|
|
28
|
+
- Cross-platform CI coverage (Windows/macOS/Ubuntu), regression tests, modularization guardrails, and Python syntax checks for autonomy/retrieval modules.
|
|
29
|
+
- Nightly benchmark workflow for retrieval quality/drift monitoring plus artifact upload.
|
|
30
|
+
- GitHub release workflow for tag-based publishing with preflight/version/changelog validation and packaged installer assets.
|
|
31
|
+
- Governance and contribution assets: `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `SECURITY.md`, `SUPPORT.md`, issue templates, PR template, `CODEOWNERS`, and Dependabot config.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
- Versioning is centralized in root `VERSION` and consumed by installers and generated output.
|
|
35
|
+
- Installer/runtime path resolution prefers canonical `.mnemo` while preserving `.cursor` compatibility bridges.
|
|
36
|
+
- Python resolution strategy is aligned across memory tooling (`py` / `python3` / `python` fallback behavior where applicable).
|
|
37
|
+
- Managed `.gitignore` and hook behavior now reflect canonical `.mnemo` artifacts while keeping bridge compatibility.
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
- Duplicate managed `.gitignore` entries on repeated force installs.
|
|
41
|
+
- Bridge idempotency/self-copy failures around `.cursor/mcp.json` compatibility targets.
|
|
42
|
+
- Version string drift between installer metadata and generated output by using `VERSION` as single source of truth.
|
|
43
|
+
- Python fallback handling in memory query flows that previously depended on a single interpreter name.
|
|
44
|
+
|
|
45
|
+
[Unreleased]: https://github.com/DiNaSoR/Mnemo/compare/v0.0.1...HEAD
|
|
46
|
+
[0.0.1]: https://github.com/DiNaSoR/Mnemo/releases/tag/v0.0.1
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DragonArab
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/header.png" alt="Mnemo - A Memory System for AI Coding Agents" width="100%">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# Mnemo 🧠
|
|
6
|
+
|
|
7
|
+
[](https://github.com/DiNaSoR/Mnemo/actions/workflows/ci.yml)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
|
|
10
|
+
> Token-safe repo memory for AI coding agents, with an autonomous runtime and optional semantic recall.
|
|
11
|
+
>
|
|
12
|
+
> ✅ Works with Cursor • Claude Code • Gemini Antigravity • OpenAI Codex • Windsurf • and more
|
|
13
|
+
|
|
14
|
+
Mnemo scaffolds a structured memory layer under `.mnemo/` (canonical) and keeps permanent compatibility bridges for `.cursor/` and `.agent/`.
|
|
15
|
+
|
|
16
|
+
## ✨ Why Mnemo
|
|
17
|
+
|
|
18
|
+
- 🧭 **Predictable retrieval order** so agents read high-signal memory first
|
|
19
|
+
- 🧱 **Atomic lessons + indexed journal** for durable project knowledge
|
|
20
|
+
- 🛡️ **Quality guardrails** (lint, token budget checks, CI benchmarks)
|
|
21
|
+
- ⚙️ **Autonomous mode** with vector sync and lifecycle tracking
|
|
22
|
+
- 🔌 **MCP tools** for semantic recall in Cursor when vector mode is enabled
|
|
23
|
+
|
|
24
|
+
## 🚀 Install Mnemo (once per project)
|
|
25
|
+
|
|
26
|
+
Run from the **target project root**.
|
|
27
|
+
|
|
28
|
+
### Any OS (npx, recommended)
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
# Installs into your current project folder
|
|
32
|
+
npx @dinasor/mnemo-cli@latest
|
|
33
|
+
|
|
34
|
+
# Optional flags (cross-platform)
|
|
35
|
+
npx @dinasor/mnemo-cli@latest --dry-run
|
|
36
|
+
npx @dinasor/mnemo-cli@latest --force
|
|
37
|
+
npx @dinasor/mnemo-cli@latest --enable-vector --vector-provider gemini
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Windows (PowerShell)
|
|
41
|
+
|
|
42
|
+
```powershell
|
|
43
|
+
# Standard install
|
|
44
|
+
powershell -ExecutionPolicy Bypass -File .\memory.ps1
|
|
45
|
+
|
|
46
|
+
# With vector mode (OpenAI default)
|
|
47
|
+
powershell -ExecutionPolicy Bypass -File .\memory.ps1 -EnableVector
|
|
48
|
+
|
|
49
|
+
# With vector mode (Gemini embeddings)
|
|
50
|
+
powershell -ExecutionPolicy Bypass -File .\memory.ps1 -EnableVector -VectorProvider gemini
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### macOS / Linux (POSIX shell)
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
# Standard install
|
|
57
|
+
sh ./memory_mac.sh
|
|
58
|
+
|
|
59
|
+
# With vector mode (OpenAI default)
|
|
60
|
+
sh ./memory_mac.sh --enable-vector
|
|
61
|
+
|
|
62
|
+
# With vector mode (Gemini embeddings)
|
|
63
|
+
sh ./memory_mac.sh --enable-vector --vector-provider gemini
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Post-install sanity check
|
|
67
|
+
|
|
68
|
+
```powershell
|
|
69
|
+
powershell -ExecutionPolicy Bypass -File .\scripts\memory\rebuild-memory-index.ps1
|
|
70
|
+
powershell -ExecutionPolicy Bypass -File .\scripts\memory\lint-memory.ps1
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
If vector mode is enabled, restart your IDE once and run:
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
vector_health
|
|
77
|
+
vector_sync
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 🧩 IDE setup guide (per project)
|
|
83
|
+
|
|
84
|
+
Use the section that matches your IDE. Each project should run Mnemo install once.
|
|
85
|
+
|
|
86
|
+
| IDE / Agent | What installer creates | What you do next |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| Cursor | `.mnemo/rules/cursor/00-memory-system.mdc` (+ `.mnemo/mcp/cursor.mcp.json`, bridged to `.cursor/mcp.json`) | Restart Cursor, run `vector_health`, then `vector_sync` |
|
|
89
|
+
| Claude Code | `CLAUDE.md` bridge file | Open repo in Claude Code and follow read order from `CLAUDE.md` |
|
|
90
|
+
| Gemini Antigravity | `.agent/rules/memory-system.md` | Ensure Antigravity loads project rules from `.agent/rules/` |
|
|
91
|
+
| OpenAI Codex | `AGENTS.md` | Start Codex from repo root so `AGENTS.md` is in scope |
|
|
92
|
+
| Windsurf / Other IDEs | `.mnemo/memory/` knowledge base (also visible at `.cursor/memory/`) | Point memory/context path to `.mnemo/memory/` |
|
|
93
|
+
|
|
94
|
+
### 1) Cursor IDE 🟦
|
|
95
|
+
|
|
96
|
+
1. Run installer in your project (`memory.ps1` or `memory_mac.sh`).
|
|
97
|
+
2. For semantic tools, enable vector mode during install.
|
|
98
|
+
3. Confirm `.mnemo/mcp/cursor.mcp.json` exists (and `.cursor/mcp.json` bridge is present).
|
|
99
|
+
4. Restart Cursor.
|
|
100
|
+
5. Run `vector_health` then `vector_sync`.
|
|
101
|
+
|
|
102
|
+
You should see MCP tools:
|
|
103
|
+
`vector_search`, `vector_sync`, `vector_forget`, `vector_health`, `memory_status`.
|
|
104
|
+
|
|
105
|
+
### 2) Claude Code 🤝
|
|
106
|
+
|
|
107
|
+
1. Run Mnemo install in your project root.
|
|
108
|
+
2. Confirm `CLAUDE.md` exists (auto-generated by installer).
|
|
109
|
+
3. Start Claude Code from the project root.
|
|
110
|
+
4. Keep `.mnemo/memory/` committed so memory travels with the repo (Cursor still reads through bridge).
|
|
111
|
+
|
|
112
|
+
### 3) Gemini Antigravity 🔷
|
|
113
|
+
|
|
114
|
+
1. Run Mnemo install in your project root.
|
|
115
|
+
2. Confirm `.agent/rules/memory-system.md` exists.
|
|
116
|
+
3. Ensure your Antigravity setup loads `.agent/rules/`.
|
|
117
|
+
4. (Optional) Enable vector mode for semantic memory workflows.
|
|
118
|
+
|
|
119
|
+
### 4) OpenAI Codex 🧪
|
|
120
|
+
|
|
121
|
+
1. Run Mnemo install in your project root.
|
|
122
|
+
2. Confirm `AGENTS.md` exists.
|
|
123
|
+
3. Launch Codex from the same root so `AGENTS.md` is used.
|
|
124
|
+
4. Follow the retrieval order defined in `AGENTS.md`.
|
|
125
|
+
|
|
126
|
+
### 5) Windsurf / Other IDEs 🌊
|
|
127
|
+
|
|
128
|
+
1. Run Mnemo install in your project root.
|
|
129
|
+
2. Point your IDE's memory/context config to `.mnemo/memory/` (or `.cursor/memory/` bridge).
|
|
130
|
+
3. Reuse the same retrieval order:
|
|
131
|
+
`hot-rules.md` → `active-context.md` → `memo.md` → indexed lessons/digests.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 🧠 What Mnemo gives you
|
|
136
|
+
|
|
137
|
+
- **Always-read layer**: `.mnemo/memory/hot-rules.md`, `active-context.md`, `memo.md`
|
|
138
|
+
- **Atomic lessons**: `.mnemo/memory/lessons/L-XXX-*.md` + generated lesson index
|
|
139
|
+
- **Monthly journal + digests**: `.mnemo/memory/journal/YYYY-MM.md` + `.mnemo/memory/digests/*.digest.md`
|
|
140
|
+
- **Rule enforcement**: `.mnemo/rules/cursor/00-memory-system.mdc` (bridged to `.cursor/rules/`)
|
|
141
|
+
- **Helper scripts**: `scripts/memory/*` (rebuild, lint, query, add-lesson, add-journal-entry, clear-active)
|
|
142
|
+
- **Optional SQLite FTS**: `.mnemo/memory/memory.sqlite` when Python is available
|
|
143
|
+
- **Optional vector layer**: `scripts/memory/mnemo_vector.py` + MCP tools
|
|
144
|
+
- **Optional autonomous runtime**: `scripts/memory/autonomy/*` (vector mode)
|
|
145
|
+
|
|
146
|
+
## 🤖 Autonomous mode (no human in the loop)
|
|
147
|
+
|
|
148
|
+
When installed with vector mode (`-EnableVector` / `--enable-vector`), Mnemo can run autonomously:
|
|
149
|
+
|
|
150
|
+
| Component | Purpose |
|
|
151
|
+
|---|---|
|
|
152
|
+
| `autonomy/runner.py` | Orchestrates detect → ingest → lifecycle → journal delta |
|
|
153
|
+
| `autonomy/ingest_pipeline.py` | Classifies/ingests changed memory content |
|
|
154
|
+
| `autonomy/lifecycle_engine.py` | Fact ADD / UPDATE / DEPRECATE / NOOP with audit trail |
|
|
155
|
+
| `autonomy/entity_resolver.py` | Stable entity IDs + alias mapping |
|
|
156
|
+
| `autonomy/retrieval_router.py` | Intent routing to memory categories |
|
|
157
|
+
| `autonomy/reranker.py` | Score fusion (semantic + authority + temporal + entity) |
|
|
158
|
+
| `autonomy/context_safety.py` | Dedup, contradiction checks, token budget guard |
|
|
159
|
+
| `autonomy/vault_policy.py` | Redaction/sensitivity policy enforcement |
|
|
160
|
+
| `autonomy/policies.yaml` | Benchmark + safety thresholds |
|
|
161
|
+
|
|
162
|
+
Runner triggers:
|
|
163
|
+
- `post-commit` hook
|
|
164
|
+
- `post-merge` / `post-checkout` hooks
|
|
165
|
+
- `python runner.py --mode schedule`
|
|
166
|
+
- `python runner.py --mode once`
|
|
167
|
+
|
|
168
|
+
## 🗂️ Generated layout
|
|
169
|
+
|
|
170
|
+
```text
|
|
171
|
+
.mnemo/
|
|
172
|
+
memory/
|
|
173
|
+
hot-rules.md
|
|
174
|
+
active-context.md
|
|
175
|
+
memo.md
|
|
176
|
+
lessons/
|
|
177
|
+
journal/
|
|
178
|
+
digests/
|
|
179
|
+
adr/
|
|
180
|
+
templates/
|
|
181
|
+
rules/
|
|
182
|
+
cursor/
|
|
183
|
+
00-memory-system.mdc
|
|
184
|
+
01-vector-search.mdc # vector mode only
|
|
185
|
+
agent/
|
|
186
|
+
memory-system.md
|
|
187
|
+
mcp/
|
|
188
|
+
cursor.mcp.json # vector mode only
|
|
189
|
+
|
|
190
|
+
.cursor/ # permanent compatibility bridge
|
|
191
|
+
memory/
|
|
192
|
+
rules/
|
|
193
|
+
mcp.json # bridge to .mnemo/mcp/cursor.mcp.json
|
|
194
|
+
|
|
195
|
+
.agent/ # permanent compatibility bridge
|
|
196
|
+
rules/
|
|
197
|
+
|
|
198
|
+
scripts/
|
|
199
|
+
memory/
|
|
200
|
+
rebuild-memory-index.ps1
|
|
201
|
+
lint-memory.ps1
|
|
202
|
+
query-memory.ps1
|
|
203
|
+
add-lesson.ps1
|
|
204
|
+
add-journal-entry.ps1
|
|
205
|
+
clear-active.ps1
|
|
206
|
+
mnemo_vector.py # vector mode only
|
|
207
|
+
autonomy/ # vector mode only
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## 🛠️ Helper scripts (quick reference)
|
|
211
|
+
|
|
212
|
+
| Script | What it does |
|
|
213
|
+
|---|---|
|
|
214
|
+
| `rebuild-memory-index.ps1` | Rebuilds lesson/journal indexes and digests |
|
|
215
|
+
| `lint-memory.ps1` | Validates frontmatter, tags, date headers, token budget |
|
|
216
|
+
| `query-memory.ps1` | Searches memory via file search or SQLite FTS (`-UseSqlite`) |
|
|
217
|
+
| `add-lesson.ps1` | Creates next `L-XXX` lesson with normalized tags |
|
|
218
|
+
| `add-journal-entry.ps1` | Adds entry under current date in monthly journal |
|
|
219
|
+
| `clear-active.ps1` | Resets `active-context.md` |
|
|
220
|
+
| `mnemo_vector.py` | Vector sync/search MCP server (vector mode only) |
|
|
221
|
+
|
|
222
|
+
## 🔐 Git hooks and API keys
|
|
223
|
+
|
|
224
|
+
Mnemo auto-configures `core.hooksPath` to `.githooks` and installs:
|
|
225
|
+
|
|
226
|
+
- `pre-commit`: rebuild + lint memory
|
|
227
|
+
- `post-commit` (vector mode): non-blocking `vector_sync` with lock protection
|
|
228
|
+
|
|
229
|
+
Important:
|
|
230
|
+
- Cursor MCP tools read API keys from `.mnemo/mcp/cursor.mcp.json` env placeholders (`.cursor/mcp.json` stays bridged).
|
|
231
|
+
- Git hooks read API keys from your shell environment.
|
|
232
|
+
|
|
233
|
+
```sh
|
|
234
|
+
# bash/zsh example
|
|
235
|
+
export OPENAI_API_KEY="sk-..."
|
|
236
|
+
# or
|
|
237
|
+
export GEMINI_API_KEY="..."
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## ✅ Recommended daily workflow
|
|
241
|
+
|
|
242
|
+
1. Update `.mnemo/memory/active-context.md` at task start.
|
|
243
|
+
2. Search first (`query-memory.ps1`) before opening many files.
|
|
244
|
+
3. Use `vector_search` when keyword lookup misses.
|
|
245
|
+
4. At finish: add journal entry, add lesson if needed, rebuild, clear active context.
|
|
246
|
+
|
|
247
|
+
## 📋 Requirements
|
|
248
|
+
|
|
249
|
+
- **PowerShell**: Windows PowerShell 5.1+ or PowerShell 7 (`pwsh`)
|
|
250
|
+
- **Git**
|
|
251
|
+
- **Optional**: Python 3 for SQLite FTS index
|
|
252
|
+
- **Optional (vector mode)**:
|
|
253
|
+
- Python 3.10+
|
|
254
|
+
- API key: `OPENAI_API_KEY` or `GEMINI_API_KEY`
|
|
255
|
+
- Auto-installed deps: `openai`, `sqlite-vec`, `mcp[cli]>=1.2.0,<2.0` (+ `google-genai` for Gemini)
|
|
256
|
+
|
|
257
|
+
## 🤝 Contributing
|
|
258
|
+
|
|
259
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md). Bug reports and feature requests use the issue templates in [.github/ISSUE_TEMPLATE/](.github/ISSUE_TEMPLATE/). Security issues go to [SECURITY.md](SECURITY.md).
|
|
260
|
+
|
|
261
|
+
## 📄 License
|
|
262
|
+
|
|
263
|
+
See [LICENSE](LICENSE).
|
package/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.0.1
|
package/bin/mnemo.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawnSync } = require("child_process");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
|
|
7
|
+
const packageRoot = path.resolve(__dirname, "..");
|
|
8
|
+
const cwd = process.cwd();
|
|
9
|
+
const rawArgs = process.argv.slice(2);
|
|
10
|
+
const wantsHelp = rawArgs.includes("--help") || rawArgs.includes("-h");
|
|
11
|
+
|
|
12
|
+
function printHelp() {
|
|
13
|
+
console.log(`Mnemo CLI
|
|
14
|
+
|
|
15
|
+
Usage:
|
|
16
|
+
npx @dinasor/mnemo-cli@latest [options]
|
|
17
|
+
|
|
18
|
+
Options:
|
|
19
|
+
--dry-run
|
|
20
|
+
--force
|
|
21
|
+
--enable-vector
|
|
22
|
+
--vector-provider <openai|gemini>
|
|
23
|
+
--project-name <name>
|
|
24
|
+
--repo-root <path> (defaults to current directory)
|
|
25
|
+
--help
|
|
26
|
+
`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function fail(message) {
|
|
30
|
+
console.error(`[mnemo] ${message}`);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function mapWindowsArgs(args) {
|
|
35
|
+
const mapped = [];
|
|
36
|
+
let hasRepoRoot = false;
|
|
37
|
+
|
|
38
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
39
|
+
const arg = args[i];
|
|
40
|
+
|
|
41
|
+
if (arg === "--dry-run") {
|
|
42
|
+
mapped.push("-DryRun");
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (arg === "--force") {
|
|
46
|
+
mapped.push("-Force");
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (arg === "--enable-vector") {
|
|
50
|
+
mapped.push("-EnableVector");
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (arg === "--vector-provider") {
|
|
54
|
+
const value = args[i + 1];
|
|
55
|
+
if (!value) fail("Missing value for --vector-provider");
|
|
56
|
+
mapped.push("-VectorProvider", value);
|
|
57
|
+
i += 1;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (arg === "--project-name") {
|
|
61
|
+
const value = args[i + 1];
|
|
62
|
+
if (!value) fail("Missing value for --project-name");
|
|
63
|
+
mapped.push("-ProjectName", value);
|
|
64
|
+
i += 1;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (arg === "--repo-root") {
|
|
68
|
+
const value = args[i + 1];
|
|
69
|
+
if (!value) fail("Missing value for --repo-root");
|
|
70
|
+
mapped.push("-RepoRoot", value);
|
|
71
|
+
hasRepoRoot = true;
|
|
72
|
+
i += 1;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (arg.toLowerCase() === "-reporoot") {
|
|
77
|
+
hasRepoRoot = true;
|
|
78
|
+
}
|
|
79
|
+
mapped.push(arg);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!hasRepoRoot && !wantsHelp) {
|
|
83
|
+
mapped.push("-RepoRoot", cwd);
|
|
84
|
+
}
|
|
85
|
+
return mapped;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function mapPosixArgs(args) {
|
|
89
|
+
const mapped = [];
|
|
90
|
+
let hasRepoRoot = false;
|
|
91
|
+
|
|
92
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
93
|
+
const arg = args[i];
|
|
94
|
+
mapped.push(arg);
|
|
95
|
+
|
|
96
|
+
if (arg === "--repo-root") {
|
|
97
|
+
if (!args[i + 1]) fail("Missing value for --repo-root");
|
|
98
|
+
mapped.push(args[i + 1]);
|
|
99
|
+
hasRepoRoot = true;
|
|
100
|
+
i += 1;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!hasRepoRoot && !wantsHelp) {
|
|
105
|
+
mapped.push("--repo-root", cwd);
|
|
106
|
+
}
|
|
107
|
+
return mapped;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (wantsHelp) {
|
|
111
|
+
printHelp();
|
|
112
|
+
process.exit(0);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (process.platform === "win32") {
|
|
116
|
+
const installer = path.join(packageRoot, "memory.ps1");
|
|
117
|
+
if (!fs.existsSync(installer)) {
|
|
118
|
+
fail(`Installer not found at ${installer}`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const args = [
|
|
122
|
+
"-ExecutionPolicy",
|
|
123
|
+
"Bypass",
|
|
124
|
+
"-File",
|
|
125
|
+
installer,
|
|
126
|
+
...mapWindowsArgs(rawArgs)
|
|
127
|
+
];
|
|
128
|
+
const result = spawnSync("powershell", args, { stdio: "inherit" });
|
|
129
|
+
process.exit(result.status ?? 1);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const installer = path.join(packageRoot, "memory_mac.sh");
|
|
133
|
+
if (!fs.existsSync(installer)) {
|
|
134
|
+
fail(`Installer not found at ${installer}`);
|
|
135
|
+
}
|
|
136
|
+
const result = spawnSync("sh", [installer, ...mapPosixArgs(rawArgs)], {
|
|
137
|
+
stdio: "inherit"
|
|
138
|
+
});
|
|
139
|
+
process.exit(result.status ?? 1);
|
package/memory.ps1
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
<#
|
|
2
|
+
memory.ps1 - Mnemo Windows Installer (modular orchestrator)
|
|
3
|
+
Windows-first, token-safe, scalable repo memory for AI coding agents.
|
|
4
|
+
|
|
5
|
+
Version is read from VERSION file at repo root.
|
|
6
|
+
|
|
7
|
+
Features:
|
|
8
|
+
- Curated "always read" memory: hot-rules.md + active-context.md + memo.md
|
|
9
|
+
- Atomic lessons (individual files) with strict YAML frontmatter
|
|
10
|
+
- Monthly journal + auto-generated digest + journal index
|
|
11
|
+
- Cursor rule (.mdc) to enforce behavior
|
|
12
|
+
- Helper scripts: rebuild, query (SQLite+grep), lint, add-lesson, add-journal-entry
|
|
13
|
+
- Tag validation against tag-vocabulary.md
|
|
14
|
+
- BOM-tolerant parsing
|
|
15
|
+
- Portable hooks via .githooks/ + .git/hooks/ (auto-configured)
|
|
16
|
+
- Lint runs on pre-commit
|
|
17
|
+
- Optional semantic vector layer (OpenAI / Gemini)
|
|
18
|
+
- Autonomous memory runtime (no-human-in-the-loop) when EnableVector
|
|
19
|
+
|
|
20
|
+
USAGE (from repo root):
|
|
21
|
+
powershell -ExecutionPolicy Bypass -File .\memory.ps1
|
|
22
|
+
powershell -ExecutionPolicy Bypass -File .\memory.ps1 -ProjectName "MyProject"
|
|
23
|
+
powershell -ExecutionPolicy Bypass -File .\memory.ps1 -Force
|
|
24
|
+
powershell -ExecutionPolicy Bypass -File .\memory.ps1 -DryRun
|
|
25
|
+
powershell -ExecutionPolicy Bypass -File .\memory.ps1 -EnableVector
|
|
26
|
+
powershell -ExecutionPolicy Bypass -File .\memory.ps1 -EnableVector -VectorProvider gemini
|
|
27
|
+
#>
|
|
28
|
+
|
|
29
|
+
[CmdletBinding()]
|
|
30
|
+
param(
|
|
31
|
+
[string]$RepoRoot = (Get-Location).Path,
|
|
32
|
+
[string]$ProjectName = "",
|
|
33
|
+
[switch]$Force,
|
|
34
|
+
[switch]$DryRun,
|
|
35
|
+
[switch]$EnableVector,
|
|
36
|
+
[ValidateSet("openai","gemini")][string]$VectorProvider = "openai"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
Set-StrictMode -Version Latest
|
|
40
|
+
$ErrorActionPreference = "Stop"
|
|
41
|
+
|
|
42
|
+
# Expose DryRun at script scope so modules can read it
|
|
43
|
+
$script:DryRun = $DryRun.IsPresent
|
|
44
|
+
|
|
45
|
+
# Read version from VERSION file (single source of truth)
|
|
46
|
+
$InstallerRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
47
|
+
$_versionFile = Join-Path $InstallerRoot "VERSION"
|
|
48
|
+
$MnemoVersion = if (Test-Path $_versionFile) { (Get-Content $_versionFile -Raw).Trim() } else { "0.0.0" }
|
|
49
|
+
|
|
50
|
+
if ($DryRun) {
|
|
51
|
+
Write-Host "[DRY RUN] No files will be written. Showing what would happen." -ForegroundColor Cyan
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
# Bootstrap installer modules (dot-sources core + feature modules)
|
|
55
|
+
. (Join-Path $InstallerRoot "scripts\memory\installer\bootstrap.ps1") -InstallerRoot $InstallerRoot
|
|
56
|
+
|
|
57
|
+
# Resolve paths
|
|
58
|
+
$RepoRoot = (Resolve-Path $RepoRoot).Path
|
|
59
|
+
if ([string]::IsNullOrWhiteSpace($ProjectName)) {
|
|
60
|
+
$ProjectName = Split-Path -Leaf $RepoRoot
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# Initialize path context
|
|
64
|
+
$ctx = Initialize-MnemoPaths -RepoRoot $RepoRoot
|
|
65
|
+
|
|
66
|
+
# Create directory structure
|
|
67
|
+
foreach ($dir in $ctx.AllDirs) { New-MnemoDirectory -Path $dir }
|
|
68
|
+
|
|
69
|
+
# Migrate legacy locations into canonical .mnemo store before scaffolding.
|
|
70
|
+
if (-not $DryRun) {
|
|
71
|
+
$legacyPairs = @(
|
|
72
|
+
@{ Source = $ctx.CursorMemoryDir; Target = $ctx.MemoryDir; Label = ".cursor/memory -> .mnemo/memory" },
|
|
73
|
+
@{ Source = $ctx.CursorRulesDir; Target = $ctx.RulesDir; Label = ".cursor/rules -> .mnemo/rules/cursor" },
|
|
74
|
+
@{ Source = $ctx.AgentRulesDir; Target = $ctx.MnemoRulesAgentDir; Label = ".agent/rules -> .mnemo/rules/agent" }
|
|
75
|
+
)
|
|
76
|
+
foreach ($pair in $legacyPairs) {
|
|
77
|
+
if (-not (Test-Path -LiteralPath $pair.Source)) { continue }
|
|
78
|
+
$sourceResolved = (Resolve-Path -LiteralPath $pair.Source -ErrorAction SilentlyContinue).Path
|
|
79
|
+
if ($sourceResolved -and (Test-MnemoPathEqual -A $sourceResolved -B $pair.Target)) { continue }
|
|
80
|
+
$copied = Copy-MnemoDirectoryContent -SourceDir $pair.Source -TargetDir $pair.Target
|
|
81
|
+
if ($copied -gt 0) {
|
|
82
|
+
Write-Host "Migrated $copied files ($($pair.Label))" -ForegroundColor Cyan
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# Install memory content scaffold (hot-rules, memo, journal, rules, multi-agent bridges)
|
|
88
|
+
Install-MemoryScaffold -Ctx $ctx -ProjectName $ProjectName -MnemoVersion $MnemoVersion -Force:$Force
|
|
89
|
+
|
|
90
|
+
# Install helper scripts from templates (and autonomy modules if vector enabled)
|
|
91
|
+
Install-MemoryScripts -Ctx $ctx -InstallerRoot $InstallerRoot -Force:$Force -EnableVector:$EnableVector -VectorProvider $VectorProvider
|
|
92
|
+
|
|
93
|
+
# Vector engine setup (Python deps, installs mnemo_vector.py + autonomy modules)
|
|
94
|
+
$vectorPython = $null
|
|
95
|
+
if ($EnableVector) {
|
|
96
|
+
$vectorPython = Install-VectorEngine -Ctx $ctx -InstallerRoot $InstallerRoot -Force:$Force -VectorProvider $VectorProvider
|
|
97
|
+
|
|
98
|
+
if (-not $DryRun -and $null -ne $vectorPython) {
|
|
99
|
+
Install-McpConfig -Ctx $ctx -VectorPython $vectorPython -VectorProvider $VectorProvider -Force:$Force
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
# Git hooks (pre-commit lint/rebuild + optional post-commit vector sync)
|
|
104
|
+
Install-GitHooks -Ctx $ctx -VectorPython $vectorPython -EnableVector:$EnableVector -Force:$Force
|
|
105
|
+
|
|
106
|
+
# Bridge canonical .mnemo content into IDE integration locations.
|
|
107
|
+
Ensure-MnemoCanonicalBridges -Ctx $ctx
|
|
108
|
+
|
|
109
|
+
# Auto-configure portable hooks path (removes the manual 'git config' step)
|
|
110
|
+
if (-not $DryRun -and (Test-Path $ctx.GitDir)) {
|
|
111
|
+
$currentHooksPath = & git -C $RepoRoot config core.hooksPath 2>$null
|
|
112
|
+
if ($currentHooksPath -ne ".githooks") {
|
|
113
|
+
& git -C $RepoRoot config core.hooksPath .githooks 2>$null
|
|
114
|
+
Write-Host "Configured: git config core.hooksPath .githooks" -ForegroundColor Green
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
# Token budget check
|
|
119
|
+
Test-MnemoTokenBudget -Ctx $ctx
|
|
120
|
+
|
|
121
|
+
# Auto-managed .gitignore block
|
|
122
|
+
Update-MnemoGitignore -Ctx $ctx -EnableVector:$EnableVector
|
|
123
|
+
|
|
124
|
+
# Setup complete
|
|
125
|
+
Write-Host ""
|
|
126
|
+
Write-Host "Setup complete. (Mnemo v$MnemoVersion)" -ForegroundColor Green
|
|
127
|
+
Write-Host ""
|
|
128
|
+
Write-Host "Memory system installed to: $($ctx.MemoryDir)" -ForegroundColor Cyan
|
|
129
|
+
Write-Host "Cursor bridge path: $($ctx.CursorMemoryDir)" -ForegroundColor DarkGray
|
|
130
|
+
Write-Host ""
|
|
131
|
+
Write-Host "Helper scripts:" -ForegroundColor Cyan
|
|
132
|
+
Write-Host " Add lesson: scripts\memory\add-lesson.ps1 -Title ""..."" -Tags ""..."" -Rule ""...""" -ForegroundColor DarkGray
|
|
133
|
+
Write-Host " Add journal: scripts\memory\add-journal-entry.ps1 -Tags ""..."" -Title ""...""" -ForegroundColor DarkGray
|
|
134
|
+
Write-Host " Query: scripts\memory\query-memory.ps1 -Query ""..."" [-UseSqlite]" -ForegroundColor DarkGray
|
|
135
|
+
Write-Host " Lint: scripts\memory\lint-memory.ps1" -ForegroundColor DarkGray
|
|
136
|
+
Write-Host " Clear: scripts\memory\clear-active.ps1" -ForegroundColor DarkGray
|
|
137
|
+
Write-Host " Rebuild: scripts\memory\rebuild-memory-index.ps1" -ForegroundColor DarkGray
|
|
138
|
+
Write-Host ""
|
|
139
|
+
|
|
140
|
+
if ($EnableVector -and (-not $DryRun)) {
|
|
141
|
+
Write-Host "Vector tools enabled ($VectorProvider):" -ForegroundColor Cyan
|
|
142
|
+
Write-Host " MCP tools: vector_search, vector_sync, vector_forget, vector_health, memory_status" -ForegroundColor DarkGray
|
|
143
|
+
Write-Host " Rule: .cursor/rules/01-vector-search.mdc" -ForegroundColor DarkGray
|
|
144
|
+
Write-Host " MCP: .cursor/mcp.json -> MnemoVector server" -ForegroundColor DarkGray
|
|
145
|
+
Write-Host ""
|
|
146
|
+
Write-Host "Autonomous memory runtime:" -ForegroundColor Cyan
|
|
147
|
+
Write-Host " Engine: scripts\memory\autonomy\runner.py" -ForegroundColor DarkGray
|
|
148
|
+
Write-Host " Auto-triggers: post-commit, post-merge, post-checkout hooks" -ForegroundColor DarkGray
|
|
149
|
+
Write-Host ""
|
|
150
|
+
Write-Host "Important: export API key in your shell profile." -ForegroundColor Yellow
|
|
151
|
+
if ($VectorProvider -eq "gemini") {
|
|
152
|
+
Write-Host " `$env:GEMINI_API_KEY = '<your-key>'" -ForegroundColor White
|
|
153
|
+
} else {
|
|
154
|
+
Write-Host " `$env:OPENAI_API_KEY = '<your-key>'" -ForegroundColor White
|
|
155
|
+
}
|
|
156
|
+
Write-Host " (MCP env in mcp.json is used by Cursor tools, not git hooks.)" -ForegroundColor DarkGray
|
|
157
|
+
Write-Host ""
|
|
158
|
+
Write-Host "Next steps:" -ForegroundColor Cyan
|
|
159
|
+
Write-Host " 1) Set API key environment variable" -ForegroundColor White
|
|
160
|
+
Write-Host " 2) Restart Cursor, then run: vector_health" -ForegroundColor White
|
|
161
|
+
Write-Host " 3) Run: vector_sync (first-time index build)" -ForegroundColor White
|
|
162
|
+
Write-Host " 4) Memory system is now autonomous (auto-syncs on every commit)" -ForegroundColor White
|
|
163
|
+
} elseif ($EnableVector -and $DryRun) {
|
|
164
|
+
Write-Host "Vector tools previewed (dry run):" -ForegroundColor Cyan
|
|
165
|
+
Write-Host " No dependencies installed and no MCP/hooks were modified." -ForegroundColor DarkGray
|
|
166
|
+
Write-Host ""
|
|
167
|
+
} else {
|
|
168
|
+
Write-Host "Next steps:" -ForegroundColor Cyan
|
|
169
|
+
Write-Host " 1) Run: powershell -ExecutionPolicy Bypass -File scripts/memory/rebuild-memory-index.ps1" -ForegroundColor White
|
|
170
|
+
Write-Host " 2) Run: powershell -ExecutionPolicy Bypass -File scripts/memory/lint-memory.ps1" -ForegroundColor White
|
|
171
|
+
Write-Host " 3) Git hooks are pre-configured (auto-rebuilds on commit)" -ForegroundColor White
|
|
172
|
+
Write-Host " 4) For semantic search: re-run with -EnableVector [-VectorProvider gemini]" -ForegroundColor White
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if ($DryRun) {
|
|
176
|
+
Write-Host ""
|
|
177
|
+
Write-Host "[DRY RUN] No changes were made." -ForegroundColor Cyan
|
|
178
|
+
}
|