memory-boost 0.1.1__tar.gz → 0.2.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.
- {memory_boost-0.1.1 → memory_boost-0.2.0}/.claude-plugin/plugin.json +4 -4
- {memory_boost-0.1.1 → memory_boost-0.2.0}/CHANGELOG.md +24 -0
- memory_boost-0.2.0/CONTRIBUTING.md +16 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/PKG-INFO +65 -13
- {memory_boost-0.1.1 → memory_boost-0.2.0}/README.md +61 -11
- memory_boost-0.2.0/docs/logo-400.png +0 -0
- memory_boost-0.2.0/llms-install.md +144 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/pyproject.toml +5 -2
- memory_boost-0.2.0/scripts/eval_recall.py +61 -0
- memory_boost-0.2.0/scripts/render-logo.py +25 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/scripts/smoke.sh +1 -1
- {memory_boost-0.1.1 → memory_boost-0.2.0}/server.json +2 -2
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/__init__.py +1 -1
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/cli.py +44 -5
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/core.py +126 -12
- memory_boost-0.2.0/src/memory_boost/semantic.py +150 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/server.py +22 -5
- {memory_boost-0.1.1 → memory_boost-0.2.0}/tests/test_cli.py +9 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/tests/test_core.py +54 -4
- {memory_boost-0.1.1 → memory_boost-0.2.0}/tests/test_mcp.py +50 -3
- memory_boost-0.2.0/tests/test_packaging.py +104 -0
- memory_boost-0.2.0/tests/test_semantic.py +152 -0
- memory_boost-0.1.1/CONTRIBUTING.md +0 -11
- memory_boost-0.1.1/tests/test_packaging.py +0 -58
- {memory_boost-0.1.1 → memory_boost-0.2.0}/.claude-plugin/marketplace.json +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/.github/ISSUE_TEMPLATE/bug.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/.github/ISSUE_TEMPLATE/harness.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/.github/pull_request_template.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/.github/workflows/ci.yml +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/.github/workflows/release.yml +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/.gitignore +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/CODE_OF_CONDUCT.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/LICENSE +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/SECURITY.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/docs/architecture.mmd +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/docs/architecture.png +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/docs/demo.gif +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/docs/demo.tape +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/docs/social.html +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/docs/social.png +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/scripts/render-demo.sh +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/skills/memory-boost/SKILL.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/skills/restore-session/SKILL.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/skills/retro/SKILL.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/skills/save-session/SKILL.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/drift.py +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/example_transcripts/-work-acme-api/0a1b2c3d-1111-4aaa-8bbb-000000000001.jsonl +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/example_transcripts/-work-acme-api/0a1b2c3d-3333-4aaa-8bbb-000000000003.jsonl +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/example_transcripts/-work-acme-api/0a1b2c3d-4444-4aaa-8bbb-000000000004.jsonl +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/example_transcripts/-work-pixel-notes/0a1b2c3d-2222-4aaa-8bbb-000000000002.jsonl +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/example_wiki/concepts/money-as-integer-cents.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/example_wiki/concepts/retry-jobs-idempotently.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/example_wiki/context/preferences.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/example_wiki/decisions/cors-allow-all.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/example_wiki/decisions/float-money.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/example_wiki/decisions/pin-postgres-15.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/example_wiki/decisions/queue-in-postgres.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/example_wiki/decisions/sessions-in-redis.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/example_wiki/log.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/example_wiki/projects/acme-api.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/example_wiki/projects/legacy-dashboard.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/example_wiki/projects/pixel-notes.md +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/lessons.py +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/src/memory_boost/mine.py +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/tests/conftest.py +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/tests/test_drift.py +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/tests/test_lessons.py +0 -0
- {memory_boost-0.1.1 → memory_boost-0.2.0}/tests/test_mine.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memory-boost",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Markdown memory your coding agent reads and writes over MCP, with drift reports that flag stale decisions and local digests of your own sessions. Everything stays in a local folder.",
|
|
5
5
|
"author": { "name": "Arnau González", "url": "https://github.com/arnaugonzalez" },
|
|
6
6
|
"homepage": "https://github.com/arnaugonzalez/memory-boost",
|
|
7
7
|
"repository": "https://github.com/arnaugonzalez/memory-boost",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"mcpServers": {
|
|
11
11
|
"memory": {
|
|
12
12
|
"command": "uvx",
|
|
13
|
-
"args": ["--quiet", "
|
|
13
|
+
"args": ["--quiet", "memory-boost==0.2.0", "serve"]
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
"hooks": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"hooks": [
|
|
20
20
|
{
|
|
21
21
|
"type": "command",
|
|
22
|
-
"command": "uvx --quiet
|
|
22
|
+
"command": "uvx --quiet memory-boost==0.2.0 hook session-start",
|
|
23
23
|
"timeout": 120
|
|
24
24
|
}
|
|
25
25
|
]
|
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.0 — 2026-10-18
|
|
4
|
+
|
|
5
|
+
- recall: freshness is now a down-weight on the bm25 score instead of a hard sort, so a strong match is no longer buried under fresher weak ones.
|
|
6
|
+
- Optional semantic recall: `pip install "memory-boost[semantic]"` plus `MEMORY_BOOST_SEMANTIC=1` and a local
|
|
7
|
+
`embeddinggemma` (Ollama) adds vector search via sqlite-vec. Default mode when on is `hybrid`; `recall --mode`
|
|
8
|
+
and `MEMORY_BOOST_RECALL_MODE` select `fts`, `semantic` or `hybrid`. Falls back to full-text if Ollama is down.
|
|
9
|
+
The base install is unchanged.
|
|
10
|
+
While embedding, `memory-boost index` and `recall` report `embedding N/M chunks…` on stderr (one
|
|
11
|
+
rewritten line on a terminal, a line every 128 chunks otherwise); stdout and the MCP server stay quiet.
|
|
12
|
+
- `shelf`: park a one-line idea in a wiki page (default `concepts/idea-shelf.md`) from the CLI
|
|
13
|
+
(`memory-boost shelf "..."`) or the new `memory_shelf` MCP tool, without reading the page.
|
|
14
|
+
- `serve --http [--host 127.0.0.1] [--port 8765]`: the MCP server over streamable HTTP (stateless,
|
|
15
|
+
JSON responses) at `http://HOST:PORT/mcp`, for one long-lived local server shared by several
|
|
16
|
+
sessions. stdio stays the default. Requires `mcp>=1.10`.
|
|
17
|
+
- MCP `initialize` reports `serverInfo` as `memory-boost` and its own version (it reported the mcp
|
|
18
|
+
library's version).
|
|
19
|
+
- Plugin: the MCP server and the session-start hook run the exact release (`uvx memory-boost==0.2.0`)
|
|
20
|
+
instead of the plugin checkout, as the Claude plugin directory requires pinned launchers. A test
|
|
21
|
+
fails if any pinned install (plugin, README, `llms-install.md`) drifts from `__version__`.
|
|
22
|
+
- `llms-install.md`: steps an agent (Claude Code, Codex, Cline, Cursor) can follow to install the CLI
|
|
23
|
+
and register the MCP server over stdio or `serve --http`, with a harness-independent check. The
|
|
24
|
+
README gains an "Install from your agent" prompt and pins its install commands.
|
|
25
|
+
- `docs/logo-400.png` (400×400, for MCP directories), rendered by `scripts/render-logo.py`.
|
|
26
|
+
|
|
3
27
|
## 0.1.1 — 2026-09-26
|
|
4
28
|
|
|
5
29
|
- README renders on PyPI and in the MCP registry: the demo GIF, the architecture diagram (now an
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
```bash
|
|
4
|
+
uv sync
|
|
5
|
+
uv run pytest
|
|
6
|
+
uvx ruff check .
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Keep the core stdlib-only (the `mcp` package is the single runtime dependency) and keep
|
|
10
|
+
the hook path fast: `memory-boost hook` must not import `mcp`. Open an issue before
|
|
11
|
+
large changes.
|
|
12
|
+
|
|
13
|
+
Releasing: the version lives in `pyproject.toml`, `src/memory_boost/__init__.py`,
|
|
14
|
+
`.claude-plugin/plugin.json` (`version` and both `memory-boost==X` launchers), `server.json`,
|
|
15
|
+
the `memory-boost==X` pins in `README.md` and `llms-install.md`, and a dated `CHANGELOG.md`
|
|
16
|
+
heading. `tests/test_packaging.py` fails until all of them agree.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: memory-boost
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Memory that reviews itself: a markdown wiki for coding agents over MCP, plus drift reports on the wiki and digests of your own sessions.
|
|
5
5
|
Project-URL: Repository, https://github.com/arnaugonzalez/memory-boost
|
|
6
6
|
Project-URL: Issues, https://github.com/arnaugonzalez/memory-boost/issues
|
|
@@ -17,7 +17,9 @@ Classifier: Operating System :: POSIX :: Linux
|
|
|
17
17
|
Classifier: Programming Language :: Python :: 3
|
|
18
18
|
Classifier: Topic :: Software Development
|
|
19
19
|
Requires-Python: >=3.11
|
|
20
|
-
Requires-Dist: mcp<2,>=1.
|
|
20
|
+
Requires-Dist: mcp<2,>=1.10
|
|
21
|
+
Provides-Extra: semantic
|
|
22
|
+
Requires-Dist: sqlite-vec>=0.1.6; extra == 'semantic'
|
|
21
23
|
Description-Content-Type: text/markdown
|
|
22
24
|
|
|
23
25
|
<!-- mcp-name: io.github.arnaugonzalez/memory-boost -->
|
|
@@ -71,9 +73,9 @@ times.
|
|
|
71
73
|
No install needed; the wiki lands in `~/.local/share/memory-boost`:
|
|
72
74
|
|
|
73
75
|
```bash
|
|
74
|
-
uvx memory-boost init --example # sample wiki with five kinds of rot + four synthetic transcripts
|
|
75
|
-
uvx memory-boost drift # what in that memory is stale, orphaned or never written down
|
|
76
|
-
uvx memory-boost mine # now on your real ~/.claude/projects: aggregates only
|
|
76
|
+
uvx memory-boost==0.2.0 init --example # sample wiki with five kinds of rot + four synthetic transcripts
|
|
77
|
+
uvx memory-boost==0.2.0 drift # what in that memory is stale, orphaned or never written down
|
|
78
|
+
uvx memory-boost==0.2.0 mine # now on your real ~/.claude/projects: aggregates only
|
|
77
79
|
```
|
|
78
80
|
|
|
79
81
|
To keep it in Claude Code, install the plugin. It brings the MCP server, the session-start
|
|
@@ -84,7 +86,22 @@ brief and the skills in one step; it only needs [uv](https://docs.astral.sh/uv/)
|
|
|
84
86
|
/plugin install memory-boost@memory-boost
|
|
85
87
|
```
|
|
86
88
|
|
|
87
|
-
Other agents, or the CLI on its own: `uv tool install memory-boost` (or
|
|
89
|
+
Other agents, or the CLI on its own: `uv tool install memory-boost==0.2.0` (or
|
|
90
|
+
`pipx install memory-boost==0.2.0`). Or let your agent do it: see [Install from your agent](#install-from-your-agent).
|
|
91
|
+
|
|
92
|
+
## Install from your agent
|
|
93
|
+
|
|
94
|
+
Paste this into Claude Code, Codex, Cline or Cursor:
|
|
95
|
+
|
|
96
|
+
> Install memory-boost 0.2.0 by following
|
|
97
|
+
> https://github.com/arnaugonzalez/memory-boost/blob/main/llms-install.md : install the CLI with
|
|
98
|
+
> `uv tool install memory-boost==0.2.0`, run `memory-boost init`, register `memory-boost serve`
|
|
99
|
+
> as a stdio MCP server named `memory`, check that it answers with nine `memory_*` tools, then run
|
|
100
|
+
> `memory-boost drift` and show me the output. Ask me before writing outside the memory home
|
|
101
|
+
> (`~/.local/share/memory-boost`) or editing any global agent config.
|
|
102
|
+
|
|
103
|
+
The agent-oriented steps (stdio and `serve --http`, per harness, with checks) are in
|
|
104
|
+
[llms-install.md](https://github.com/arnaugonzalez/memory-boost/blob/main/llms-install.md).
|
|
88
105
|
|
|
89
106
|
## On a real machine
|
|
90
107
|
|
|
@@ -123,9 +140,11 @@ it needed a new tool: the data was already on disk. It needed a reader.
|
|
|
123
140
|
## What it is
|
|
124
141
|
|
|
125
142
|
1. **A wiki you own.** `projects/*.md`, `decisions/*.md`, `concepts/*.md`, `log.md`. Plain
|
|
126
|
-
markdown; edit by hand, keep it in git. SQLite FTS5 index as a disposable cache.
|
|
143
|
+
markdown; edit by hand, keep it in git. SQLite FTS5 index as a disposable cache. Nine MCP
|
|
127
144
|
tools for any harness: `memory_brief`, `memory_recall`, `memory_page`, `memory_save`,
|
|
128
|
-
`memory_checkpoint`, `memory_resume`, `memory_drift`, `memory_lesson`.
|
|
145
|
+
`memory_checkpoint`, `memory_resume`, `memory_drift`, `memory_lesson`, `memory_shelf`.
|
|
146
|
+
`memory_shelf` (CLI: `memory-boost shelf "idea"`) appends a dated one-line idea to
|
|
147
|
+
`concepts/idea-shelf.md` without the agent reading the page back.
|
|
129
148
|
2. **Freshness as data.** Decisions carry `status:` and `review_by:`. Search results are tagged
|
|
130
149
|
`current / unclassified / review / historic / superseded`, current first.
|
|
131
150
|
3. **Session checkpoints** that survive `/compact`, with one line per *other* active session on
|
|
@@ -143,6 +162,16 @@ it needed a new tool: the data was already on disk. It needed a reader.
|
|
|
143
162
|
|
|
144
163
|
MCP server (all harnesses): command `memory-boost`, args `["serve"]`.
|
|
145
164
|
|
|
165
|
+
To share one server between several sessions, run it over streamable HTTP (stateless, JSON
|
|
166
|
+
responses) and point each harness at `http://127.0.0.1:8765/mcp`:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
memory-boost serve --http # --host 127.0.0.1 --port 8765 are the defaults
|
|
170
|
+
claude mcp add --transport http memory -s user http://127.0.0.1:8765/mcp
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
It binds to loopback by default and has no authentication: keep it there.
|
|
174
|
+
|
|
146
175
|
| Harness | MCP registration | Context at session start |
|
|
147
176
|
|---|---|---|
|
|
148
177
|
| Claude Code (plugin) | `/plugin install memory-boost@memory-boost` | Included: hook, MCP server, skills |
|
|
@@ -163,7 +192,8 @@ checkpoint. It never blocks session start: on any error it prints nothing.
|
|
|
163
192
|
Skills: `/memory-boost` (router: when to run what), `/save-session`, `/restore-session`,
|
|
164
193
|
`/retro`. The plugin installs them as `/memory-boost:retro` and so on; without it, copy
|
|
165
194
|
`skills/*` into `~/.claude/skills/`. The first session after installing the plugin takes a few
|
|
166
|
-
extra seconds while uv fetches
|
|
195
|
+
extra seconds while uv fetches `memory-boost==0.2.0` and its dependencies from PyPI (the only
|
|
196
|
+
network access the plugin makes); later sessions start in about 0.2 s.
|
|
167
197
|
|
|
168
198
|
CLI contract for agents: data on stdout, errors on stderr with a `fix:` line, `--json` on every
|
|
169
199
|
reading command (with a `version` field), exit 0 = trust stdout, 1 = not found, 2 = bad input.
|
|
@@ -176,8 +206,30 @@ Reports end with a `next:` line naming the exact command to run.
|
|
|
176
206
|
<sub>Source: [docs/architecture.mmd](https://github.com/arnaugonzalez/memory-boost/blob/main/docs/architecture.mmd)</sub>
|
|
177
207
|
|
|
178
208
|
The project is resolved from the working directory name (`~/work/acme-api` → `projects/acme-api.md`);
|
|
179
|
-
map other names in `aliases.json`. Under 1,
|
|
180
|
-
embeddings, no daemon
|
|
209
|
+
map other names in `aliases.json`. Under 1,900 lines of Python, one dependency (`mcp`), no
|
|
210
|
+
embeddings unless you opt into semantic recall, no daemon unless you run `serve --http`.
|
|
211
|
+
|
|
212
|
+
## Semantic recall (optional)
|
|
213
|
+
|
|
214
|
+
Off by default: `memory_recall` is full-text only and the base install stays one dependency.
|
|
215
|
+
To also match paraphrases and other languages, run a local embedding model:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
pip install "memory-boost[semantic]==0.2.0" # adds sqlite-vec
|
|
219
|
+
ollama pull embeddinggemma
|
|
220
|
+
export MEMORY_BOOST_SEMANTIC=1
|
|
221
|
+
memory-boost index # embeds the wiki once; later runs embed only changes
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
The first index of a large wiki on CPU can take minutes: as a rough guide, about 15 minutes for some
|
|
225
|
+
850 documents on a laptop without a GPU (one measurement, not a benchmark). `memory-boost index` and
|
|
226
|
+
`recall` show `embedding N/M chunks…` on stderr while it runs; later runs re-embed only what changed.
|
|
227
|
+
|
|
228
|
+
Default mode when on is `hybrid` (full-text and vectors fused by weighted reciprocal rank); override
|
|
229
|
+
with `MEMORY_BOOST_RECALL_MODE=fts|semantic|hybrid` or `memory-boost recall --mode`. If Ollama is down,
|
|
230
|
+
recall falls back to full-text and logs a warning. On a private 64-query set (39 literal, 25 paraphrase)
|
|
231
|
+
with a warm index on CPU: paraphrase nDCG@10 0.46 to 0.76, literal 0.80 to 0.85, p50 about 110 ms per query.
|
|
232
|
+
The query set is not published.
|
|
181
233
|
|
|
182
234
|
## Configuration
|
|
183
235
|
|
|
@@ -195,7 +247,7 @@ embeddings, no daemon.
|
|
|
195
247
|
| | memory-boost | [basic-memory](https://github.com/basicmachines-co/basic-memory) | [claude-mem](https://github.com/thedotmack/claude-mem) | [agent-retro](https://github.com/giannimassi/agent-retro) |
|
|
196
248
|
|---|---|---|---|---|
|
|
197
249
|
| Store | Markdown wiki you edit | Markdown | Captured observations | None (prompt skill) |
|
|
198
|
-
| Search | FTS5 | FTS + vectors | FTS + vectors | — |
|
|
250
|
+
| Search | FTS5 (+ optional local vectors) | FTS + vectors | FTS + vectors | — |
|
|
199
251
|
| Freshness / review dates | Yes | No | No | — |
|
|
200
252
|
| Drift report over memory | Yes | No | No | No |
|
|
201
253
|
| Session analytics | Yes (aggregates, local) | No | No | LLM reads the conversation |
|
|
@@ -208,7 +260,7 @@ agents already wrote down.
|
|
|
208
260
|
|
|
209
261
|
## Limits / non-goals
|
|
210
262
|
|
|
211
|
-
-
|
|
263
|
+
- Full-text search by default; embeddings only with the optional `[semantic]` extra and a local Ollama.
|
|
212
264
|
- `mine` understands Claude Code transcripts today. Codex is on the roadmap.
|
|
213
265
|
- Reports are as good as the wiki: an empty wiki yields an empty `drift`.
|
|
214
266
|
- Single user, local files. Linux and macOS; Windows untested.
|
|
@@ -49,9 +49,9 @@ times.
|
|
|
49
49
|
No install needed; the wiki lands in `~/.local/share/memory-boost`:
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
|
-
uvx memory-boost init --example # sample wiki with five kinds of rot + four synthetic transcripts
|
|
53
|
-
uvx memory-boost drift # what in that memory is stale, orphaned or never written down
|
|
54
|
-
uvx memory-boost mine # now on your real ~/.claude/projects: aggregates only
|
|
52
|
+
uvx memory-boost==0.2.0 init --example # sample wiki with five kinds of rot + four synthetic transcripts
|
|
53
|
+
uvx memory-boost==0.2.0 drift # what in that memory is stale, orphaned or never written down
|
|
54
|
+
uvx memory-boost==0.2.0 mine # now on your real ~/.claude/projects: aggregates only
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
To keep it in Claude Code, install the plugin. It brings the MCP server, the session-start
|
|
@@ -62,7 +62,22 @@ brief and the skills in one step; it only needs [uv](https://docs.astral.sh/uv/)
|
|
|
62
62
|
/plugin install memory-boost@memory-boost
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
Other agents, or the CLI on its own: `uv tool install memory-boost` (or
|
|
65
|
+
Other agents, or the CLI on its own: `uv tool install memory-boost==0.2.0` (or
|
|
66
|
+
`pipx install memory-boost==0.2.0`). Or let your agent do it: see [Install from your agent](#install-from-your-agent).
|
|
67
|
+
|
|
68
|
+
## Install from your agent
|
|
69
|
+
|
|
70
|
+
Paste this into Claude Code, Codex, Cline or Cursor:
|
|
71
|
+
|
|
72
|
+
> Install memory-boost 0.2.0 by following
|
|
73
|
+
> https://github.com/arnaugonzalez/memory-boost/blob/main/llms-install.md : install the CLI with
|
|
74
|
+
> `uv tool install memory-boost==0.2.0`, run `memory-boost init`, register `memory-boost serve`
|
|
75
|
+
> as a stdio MCP server named `memory`, check that it answers with nine `memory_*` tools, then run
|
|
76
|
+
> `memory-boost drift` and show me the output. Ask me before writing outside the memory home
|
|
77
|
+
> (`~/.local/share/memory-boost`) or editing any global agent config.
|
|
78
|
+
|
|
79
|
+
The agent-oriented steps (stdio and `serve --http`, per harness, with checks) are in
|
|
80
|
+
[llms-install.md](https://github.com/arnaugonzalez/memory-boost/blob/main/llms-install.md).
|
|
66
81
|
|
|
67
82
|
## On a real machine
|
|
68
83
|
|
|
@@ -101,9 +116,11 @@ it needed a new tool: the data was already on disk. It needed a reader.
|
|
|
101
116
|
## What it is
|
|
102
117
|
|
|
103
118
|
1. **A wiki you own.** `projects/*.md`, `decisions/*.md`, `concepts/*.md`, `log.md`. Plain
|
|
104
|
-
markdown; edit by hand, keep it in git. SQLite FTS5 index as a disposable cache.
|
|
119
|
+
markdown; edit by hand, keep it in git. SQLite FTS5 index as a disposable cache. Nine MCP
|
|
105
120
|
tools for any harness: `memory_brief`, `memory_recall`, `memory_page`, `memory_save`,
|
|
106
|
-
`memory_checkpoint`, `memory_resume`, `memory_drift`, `memory_lesson`.
|
|
121
|
+
`memory_checkpoint`, `memory_resume`, `memory_drift`, `memory_lesson`, `memory_shelf`.
|
|
122
|
+
`memory_shelf` (CLI: `memory-boost shelf "idea"`) appends a dated one-line idea to
|
|
123
|
+
`concepts/idea-shelf.md` without the agent reading the page back.
|
|
107
124
|
2. **Freshness as data.** Decisions carry `status:` and `review_by:`. Search results are tagged
|
|
108
125
|
`current / unclassified / review / historic / superseded`, current first.
|
|
109
126
|
3. **Session checkpoints** that survive `/compact`, with one line per *other* active session on
|
|
@@ -121,6 +138,16 @@ it needed a new tool: the data was already on disk. It needed a reader.
|
|
|
121
138
|
|
|
122
139
|
MCP server (all harnesses): command `memory-boost`, args `["serve"]`.
|
|
123
140
|
|
|
141
|
+
To share one server between several sessions, run it over streamable HTTP (stateless, JSON
|
|
142
|
+
responses) and point each harness at `http://127.0.0.1:8765/mcp`:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
memory-boost serve --http # --host 127.0.0.1 --port 8765 are the defaults
|
|
146
|
+
claude mcp add --transport http memory -s user http://127.0.0.1:8765/mcp
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
It binds to loopback by default and has no authentication: keep it there.
|
|
150
|
+
|
|
124
151
|
| Harness | MCP registration | Context at session start |
|
|
125
152
|
|---|---|---|
|
|
126
153
|
| Claude Code (plugin) | `/plugin install memory-boost@memory-boost` | Included: hook, MCP server, skills |
|
|
@@ -141,7 +168,8 @@ checkpoint. It never blocks session start: on any error it prints nothing.
|
|
|
141
168
|
Skills: `/memory-boost` (router: when to run what), `/save-session`, `/restore-session`,
|
|
142
169
|
`/retro`. The plugin installs them as `/memory-boost:retro` and so on; without it, copy
|
|
143
170
|
`skills/*` into `~/.claude/skills/`. The first session after installing the plugin takes a few
|
|
144
|
-
extra seconds while uv fetches
|
|
171
|
+
extra seconds while uv fetches `memory-boost==0.2.0` and its dependencies from PyPI (the only
|
|
172
|
+
network access the plugin makes); later sessions start in about 0.2 s.
|
|
145
173
|
|
|
146
174
|
CLI contract for agents: data on stdout, errors on stderr with a `fix:` line, `--json` on every
|
|
147
175
|
reading command (with a `version` field), exit 0 = trust stdout, 1 = not found, 2 = bad input.
|
|
@@ -154,8 +182,30 @@ Reports end with a `next:` line naming the exact command to run.
|
|
|
154
182
|
<sub>Source: [docs/architecture.mmd](https://github.com/arnaugonzalez/memory-boost/blob/main/docs/architecture.mmd)</sub>
|
|
155
183
|
|
|
156
184
|
The project is resolved from the working directory name (`~/work/acme-api` → `projects/acme-api.md`);
|
|
157
|
-
map other names in `aliases.json`. Under 1,
|
|
158
|
-
embeddings, no daemon
|
|
185
|
+
map other names in `aliases.json`. Under 1,900 lines of Python, one dependency (`mcp`), no
|
|
186
|
+
embeddings unless you opt into semantic recall, no daemon unless you run `serve --http`.
|
|
187
|
+
|
|
188
|
+
## Semantic recall (optional)
|
|
189
|
+
|
|
190
|
+
Off by default: `memory_recall` is full-text only and the base install stays one dependency.
|
|
191
|
+
To also match paraphrases and other languages, run a local embedding model:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
pip install "memory-boost[semantic]==0.2.0" # adds sqlite-vec
|
|
195
|
+
ollama pull embeddinggemma
|
|
196
|
+
export MEMORY_BOOST_SEMANTIC=1
|
|
197
|
+
memory-boost index # embeds the wiki once; later runs embed only changes
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
The first index of a large wiki on CPU can take minutes: as a rough guide, about 15 minutes for some
|
|
201
|
+
850 documents on a laptop without a GPU (one measurement, not a benchmark). `memory-boost index` and
|
|
202
|
+
`recall` show `embedding N/M chunks…` on stderr while it runs; later runs re-embed only what changed.
|
|
203
|
+
|
|
204
|
+
Default mode when on is `hybrid` (full-text and vectors fused by weighted reciprocal rank); override
|
|
205
|
+
with `MEMORY_BOOST_RECALL_MODE=fts|semantic|hybrid` or `memory-boost recall --mode`. If Ollama is down,
|
|
206
|
+
recall falls back to full-text and logs a warning. On a private 64-query set (39 literal, 25 paraphrase)
|
|
207
|
+
with a warm index on CPU: paraphrase nDCG@10 0.46 to 0.76, literal 0.80 to 0.85, p50 about 110 ms per query.
|
|
208
|
+
The query set is not published.
|
|
159
209
|
|
|
160
210
|
## Configuration
|
|
161
211
|
|
|
@@ -173,7 +223,7 @@ embeddings, no daemon.
|
|
|
173
223
|
| | memory-boost | [basic-memory](https://github.com/basicmachines-co/basic-memory) | [claude-mem](https://github.com/thedotmack/claude-mem) | [agent-retro](https://github.com/giannimassi/agent-retro) |
|
|
174
224
|
|---|---|---|---|---|
|
|
175
225
|
| Store | Markdown wiki you edit | Markdown | Captured observations | None (prompt skill) |
|
|
176
|
-
| Search | FTS5 | FTS + vectors | FTS + vectors | — |
|
|
226
|
+
| Search | FTS5 (+ optional local vectors) | FTS + vectors | FTS + vectors | — |
|
|
177
227
|
| Freshness / review dates | Yes | No | No | — |
|
|
178
228
|
| Drift report over memory | Yes | No | No | No |
|
|
179
229
|
| Session analytics | Yes (aggregates, local) | No | No | LLM reads the conversation |
|
|
@@ -186,7 +236,7 @@ agents already wrote down.
|
|
|
186
236
|
|
|
187
237
|
## Limits / non-goals
|
|
188
238
|
|
|
189
|
-
-
|
|
239
|
+
- Full-text search by default; embeddings only with the optional `[semantic]` extra and a local Ollama.
|
|
190
240
|
- `mine` understands Claude Code transcripts today. Codex is on the roadmap.
|
|
191
241
|
- Reports are as good as the wiki: an empty wiki yields an empty `drift`.
|
|
192
242
|
- Single user, local files. Linux and macOS; Windows untested.
|
|
Binary file
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Installing memory-boost (instructions for AI agents)
|
|
2
|
+
|
|
3
|
+
You are an AI coding agent (Claude Code, Codex, Cline, Cursor or similar) asked to install
|
|
4
|
+
memory-boost and register it as an MCP server. Follow these steps in order. Run each check; if one
|
|
5
|
+
fails, stop and report the command and its stderr. Ask the user before you edit a global config
|
|
6
|
+
file (anything under `~`) or write outside the memory home.
|
|
7
|
+
|
|
8
|
+
What it is: a markdown wiki that agents read and write over MCP (nine `memory_*` tools), plus
|
|
9
|
+
`drift` reports on that memory and `mine` digests of local Claude Code transcripts. Everything is
|
|
10
|
+
local files; nothing is sent anywhere. The optional semantic recall talks only to a local Ollama.
|
|
11
|
+
|
|
12
|
+
## 1. Requirements
|
|
13
|
+
|
|
14
|
+
- Python 3.11+ and [uv](https://docs.astral.sh/uv/) (`uv --version`). If uv is missing, ask the
|
|
15
|
+
user before installing it. `pipx` works too: replace `uv tool install` with `pipx install`.
|
|
16
|
+
- Linux or macOS. Windows is untested.
|
|
17
|
+
|
|
18
|
+
## 2. Install the CLI (pinned)
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
uv tool install memory-boost==0.2.0
|
|
22
|
+
memory-boost --version # expect: memory-boost 0.2.0
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Check which binary the harness will run: `command -v memory-boost` must be inside `uv tool dir --bin`
|
|
26
|
+
and `memory-boost --version` must print 0.2.0. If it is not found, or another `memory-boost` comes
|
|
27
|
+
first on PATH, put the absolute path `$(uv tool dir --bin)/memory-boost` in the MCP config below
|
|
28
|
+
instead of `memory-boost` (or ask the user before running `uv tool update-shell`).
|
|
29
|
+
|
|
30
|
+
Without installing anything permanently, use `uvx memory-boost==0.2.0 <command>` instead of
|
|
31
|
+
`memory-boost <command>` everywhere below (MCP config: command `uvx`, args
|
|
32
|
+
`["--quiet", "memory-boost==0.2.0", "serve"]`).
|
|
33
|
+
|
|
34
|
+
## 3. Create the memory home
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
memory-boost init # creates the wiki in $MEMORY_BOOST_HOME (default ~/.local/share/memory-boost)
|
|
38
|
+
memory-boost drift # exit 0; an empty wiki gives an empty report
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
To see what it does on sample data first: `memory-boost init --example` (only into an empty home).
|
|
42
|
+
To use an existing markdown wiki, set `MEMORY_BOOST_WIKI=/path/to/wiki` in the MCP server's `env`.
|
|
43
|
+
|
|
44
|
+
## 4. Register the MCP server
|
|
45
|
+
|
|
46
|
+
Server name: `memory`. Transport: stdio (default). Command: `memory-boost`, args: `["serve"]`.
|
|
47
|
+
If a server named `memory` is already configured (`claude mcp list`, `codex mcp list` or the JSON
|
|
48
|
+
file), ask the user whether to replace it or use another name such as `memory-boost`.
|
|
49
|
+
Pick the block for your harness.
|
|
50
|
+
|
|
51
|
+
**Claude Code.** If the user wants the full setup (MCP server, session-start hook, skills), tell
|
|
52
|
+
them to run `/plugin marketplace add arnaugonzalez/memory-boost` and then
|
|
53
|
+
`/plugin install memory-boost@memory-boost` themselves, and skip the rest of this step.
|
|
54
|
+
MCP server only:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
claude mcp add memory -s user -- memory-boost serve # all projects (global: ask first)
|
|
58
|
+
claude mcp add memory -s project -- memory-boost serve # this repo only: writes ./.mcp.json
|
|
59
|
+
claude mcp list # expect: memory: memory-boost serve - ✓ Connected
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Codex CLI**:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
codex mcp add memory -- memory-boost serve
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
or in `~/.codex/config.toml`:
|
|
69
|
+
|
|
70
|
+
```toml
|
|
71
|
+
[mcp_servers.memory]
|
|
72
|
+
command = "memory-boost"
|
|
73
|
+
args = ["serve"]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Cline** (`cline_mcp_settings.json`), **Cursor** (`.cursor/mcp.json`), **VS Code, Gemini CLI and
|
|
77
|
+
other JSON configs**:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"mcpServers": {
|
|
82
|
+
"memory": { "command": "memory-boost", "args": ["serve"] }
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Optional: one shared server over HTTP
|
|
88
|
+
|
|
89
|
+
For several sessions sharing one long-lived server, run streamable HTTP (stateless, JSON responses).
|
|
90
|
+
It binds to 127.0.0.1 and has no authentication: never expose it on another interface.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
memory-boost serve --http # defaults: --host 127.0.0.1 --port 8765, endpoint /mcp
|
|
94
|
+
claude mcp add --transport http memory -s user http://127.0.0.1:8765/mcp
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
JSON configs: `{"mcpServers": {"memory": {"type": "streamableHttp", "url": "http://127.0.0.1:8765/mcp"}}}`
|
|
98
|
+
(Cline uses `streamableHttp`; Claude Code's `.mcp.json` uses `"type": "http"`). Codex:
|
|
99
|
+
`url = "http://127.0.0.1:8765/mcp"` under `[mcp_servers.memory]`. The server must already be
|
|
100
|
+
running (a user service or a terminal); this step does not start it for the user.
|
|
101
|
+
|
|
102
|
+
## 5. Check that the server answers
|
|
103
|
+
|
|
104
|
+
This talks to the server directly, independent of any harness. Expect `9`:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
printf '%s\n' \
|
|
108
|
+
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"check","version":"0"}}}' \
|
|
109
|
+
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
|
|
110
|
+
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
|
|
111
|
+
| memory-boost serve 2>/dev/null | grep -o '"name":"memory_[a-z]*"' | sort -u | wc -l
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
For the HTTP server: `curl -s -X POST http://127.0.0.1:8765/mcp -H 'Content-Type: application/json'
|
|
115
|
+
-H 'Accept: application/json, text/event-stream' -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"check","version":"0"}}}'`
|
|
116
|
+
returns `"serverInfo":{"name":"memory-boost","version":"0.2.0"}`.
|
|
117
|
+
|
|
118
|
+
The MCP tools: `memory_brief`, `memory_recall`, `memory_page`, `memory_save`, `memory_checkpoint`,
|
|
119
|
+
`memory_resume`, `memory_drift`, `memory_lesson`, `memory_shelf`.
|
|
120
|
+
|
|
121
|
+
## 6. Tell the agent to use it
|
|
122
|
+
|
|
123
|
+
Add one line to the project's agent instructions (`AGENTS.md`, `CLAUDE.md`, `.clinerules`, Cursor
|
|
124
|
+
rules), after asking the user:
|
|
125
|
+
|
|
126
|
+
> At session start call `memory_brief` (MCP server `memory`) and follow it. Record decisions with
|
|
127
|
+
> `memory_save`; before `/compact` or a long pause, call `memory_checkpoint`.
|
|
128
|
+
|
|
129
|
+
Claude Code without the plugin can also inject the brief automatically with a SessionStart hook in
|
|
130
|
+
`~/.claude/settings.json` (global: ask first):
|
|
131
|
+
|
|
132
|
+
```json
|
|
133
|
+
{ "hooks": { "SessionStart": [ { "hooks": [ { "type": "command", "command": "memory-boost hook session-start" } ] } ] } }
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## 7. Report back
|
|
137
|
+
|
|
138
|
+
Tell the user: the installed version, where the memory home is, which config file you changed and
|
|
139
|
+
the exact entry, the result of the check in step 5, and the first lines of `memory-boost drift`.
|
|
140
|
+
|
|
141
|
+
## Uninstall
|
|
142
|
+
|
|
143
|
+
`uv tool uninstall memory-boost`, remove the `memory` entry from the MCP config, and delete the
|
|
144
|
+
memory home only if the user asks (it holds their notes).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "memory-boost"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.2.0"
|
|
4
4
|
description = "Memory that reviews itself: a markdown wiki for coding agents over MCP, plus drift reports on the wiki and digests of your own sessions."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -17,7 +17,10 @@ classifiers = [
|
|
|
17
17
|
"Programming Language :: Python :: 3",
|
|
18
18
|
"Topic :: Software Development",
|
|
19
19
|
]
|
|
20
|
-
dependencies = ["mcp>=1.
|
|
20
|
+
dependencies = ["mcp>=1.10,<2"]
|
|
21
|
+
|
|
22
|
+
[project.optional-dependencies]
|
|
23
|
+
semantic = ["sqlite-vec>=0.1.6"]
|
|
21
24
|
|
|
22
25
|
[project.scripts]
|
|
23
26
|
memory-boost = "memory_boost.cli:main"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""Measure recall quality (nDCG@10, hit@5, MRR) and latency (p50) per query split.
|
|
2
|
+
|
|
3
|
+
--queries points to JSON shaped as {"<split>": [{"q": str, "gold": [key, ...]}]}.
|
|
4
|
+
A key is a page stem (decisions/foo.md -> "foo") or the project name for log.md entries.
|
|
5
|
+
The queries file is supplied by the user and is not versioned in this repo.
|
|
6
|
+
Run with MEMORY_BOOST_HOME pointing at the wiki to evaluate; --mode picks fts|semantic|hybrid.
|
|
7
|
+
"""
|
|
8
|
+
import argparse
|
|
9
|
+
import json
|
|
10
|
+
import math
|
|
11
|
+
import statistics
|
|
12
|
+
import time
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
from memory_boost import core
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def recall_keys(query: str, historic: bool, mode: str | None) -> list[str]:
|
|
19
|
+
keys: list[str] = []
|
|
20
|
+
for r in core.recall(query, limit=10, include_historic=historic, mode=mode):
|
|
21
|
+
key = r["project"] if r["kind"] == "log" else Path(r["path"]).stem
|
|
22
|
+
if key not in keys:
|
|
23
|
+
keys.append(key)
|
|
24
|
+
return keys[:10]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def score(keys: list[str], gold: list[str]) -> dict[str, float]:
|
|
28
|
+
gold_set = set(gold)
|
|
29
|
+
rank = next((i + 1 for i, k in enumerate(keys) if k in gold_set), None)
|
|
30
|
+
dcg = sum(1 / math.log2(i + 2) for i, k in enumerate(keys) if k in gold_set)
|
|
31
|
+
idcg = sum(1 / math.log2(i + 2) for i in range(min(len(gold_set), 10)))
|
|
32
|
+
return {
|
|
33
|
+
"ndcg": dcg / idcg if idcg else 0.0,
|
|
34
|
+
"hit5": float(rank is not None and rank <= 5),
|
|
35
|
+
"mrr": 1 / rank if rank else 0.0,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def main() -> None:
|
|
40
|
+
ap = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
|
41
|
+
ap.add_argument("--queries", type=Path, required=True, help="JSON file with query splits")
|
|
42
|
+
ap.add_argument("--historic", action="store_true", help="include historic pages")
|
|
43
|
+
ap.add_argument("--mode", choices=core.RECALL_MODES, default=None, help="recall mode to evaluate")
|
|
44
|
+
args = ap.parse_args()
|
|
45
|
+
splits = json.loads(args.queries.read_text(encoding="utf-8"))
|
|
46
|
+
for split, items in splits.items():
|
|
47
|
+
scores, times = [], []
|
|
48
|
+
for it in items:
|
|
49
|
+
t0 = time.perf_counter()
|
|
50
|
+
keys = recall_keys(it["q"], args.historic, args.mode)
|
|
51
|
+
times.append((time.perf_counter() - t0) * 1000)
|
|
52
|
+
scores.append(score(keys, it["gold"]))
|
|
53
|
+
n = len(scores) or 1
|
|
54
|
+
mean = {m: sum(s[m] for s in scores) / n for m in ("ndcg", "hit5", "mrr")}
|
|
55
|
+
p50 = statistics.median(times) if times else 0.0
|
|
56
|
+
print(f"{split}: nDCG@10 {mean['ndcg']:.3f} hit@5 {mean['hit5']:.3f} MRR {mean['mrr']:.3f} "
|
|
57
|
+
f"p50 {p50:.0f} ms")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
if __name__ == "__main__":
|
|
61
|
+
main()
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Render docs/logo-400.png (Cline / Glama logo) in the docs/social.png palette.
|
|
2
|
+
|
|
3
|
+
uv run --no-project --with pillow python scripts/render-logo.py docs/logo-400.png
|
|
4
|
+
"""
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
from PIL import Image, ImageDraw, ImageFont
|
|
8
|
+
|
|
9
|
+
out = sys.argv[1]
|
|
10
|
+
S = 4 # supersample
|
|
11
|
+
W = 400 * S
|
|
12
|
+
img = Image.new("RGB", (W, W), "#1e1e2e")
|
|
13
|
+
d = ImageDraw.Draw(img)
|
|
14
|
+
bold = "/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf"
|
|
15
|
+
reg = "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf"
|
|
16
|
+
pad = 40 * S
|
|
17
|
+
d.rounded_rectangle([pad - 4*S, 92*S, W - pad + 4*S, 300*S], radius=18*S,
|
|
18
|
+
fill="#181825", outline="#313244", width=2*S)
|
|
19
|
+
f_big = ImageFont.truetype(bold, 78 * S)
|
|
20
|
+
f_small = ImageFont.truetype(reg, 24 * S)
|
|
21
|
+
d.text((pad + 16*S, 110*S), "memory", font=f_big, fill="#f5e0dc")
|
|
22
|
+
d.text((pad + 16*S, 195*S), "-boost", font=f_big, fill="#f5e0dc")
|
|
23
|
+
d.text((pad + 16*S, 48*S), "$ drift", font=f_small, fill="#89b4fa")
|
|
24
|
+
d.text((pad + 16*S, 318*S), "reads it back.", font=f_small, fill="#a6e3a1")
|
|
25
|
+
img.resize((400, 400), Image.LANCZOS).save(out, optimize=True)
|
|
@@ -43,7 +43,7 @@ assert init["result"]["serverInfo"]["name"], init
|
|
|
43
43
|
call({"jsonrpc": "2.0", "method": "notifications/initialized"}, reply=False)
|
|
44
44
|
tools = {t["name"] for t in call({"jsonrpc": "2.0", "id": 2, "method": "tools/list"})["result"]["tools"]}
|
|
45
45
|
p.terminate()
|
|
46
|
-
assert len(tools) ==
|
|
46
|
+
assert len(tools) == 9 and {"memory_drift", "memory_shelf"} <= tools, tools
|
|
47
47
|
print("mcp tools:", ", ".join(sorted(tools)))
|
|
48
48
|
EOF
|
|
49
49
|
step OK
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
10
|
"websiteUrl": "https://github.com/arnaugonzalez/memory-boost",
|
|
11
|
-
"version": "0.
|
|
11
|
+
"version": "0.2.0",
|
|
12
12
|
"packages": [
|
|
13
13
|
{
|
|
14
14
|
"registryType": "pypi",
|
|
15
15
|
"identifier": "memory-boost",
|
|
16
|
-
"version": "0.
|
|
16
|
+
"version": "0.2.0",
|
|
17
17
|
"runtimeHint": "uvx",
|
|
18
18
|
"packageArguments": [{ "type": "positional", "value": "serve" }],
|
|
19
19
|
"transport": { "type": "stdio" }
|