pi-memory 0.2.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jay Zeng
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,213 @@
1
+ # pi-memory
2
+
3
+ Memory extension for [pi](https://github.com/mariozechner/pi-mono) with semantic search powered by [qmd](https://github.com/tobi/qmd).
4
+
5
+ Thanks to https://github.com/skyfallsin/pi-mem for inspiration.
6
+
7
+ Persistent memory across coding sessions — long-term facts, daily logs, and a scratchpad checklist. Core memory works as plain markdown files. Optional qmd integration adds keyword, semantic, and hybrid search across all memory files, plus automatic selective injection of relevant past memories into every turn.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ # Install from npm (recommended)
13
+ pi install npm:pi-memory
14
+
15
+ # Install from local checkout
16
+ pi install ./pi-memory
17
+
18
+ # Optional (enables `memory_search` + selective injection, requires Bun)
19
+ command -v qmd >/dev/null 2>&1 || bun install -g https://github.com/tobi/qmd
20
+ ```
21
+
22
+ Or copy to your extensions directory:
23
+
24
+ ```bash
25
+ cp -r pi-memory ~/.pi/agent/extensions/pi-memory
26
+ ```
27
+
28
+ ### Optional: Enable search with qmd
29
+
30
+ When qmd is installed, the extension **automatically creates** the `pi-memory` collection and path contexts on first session start. No manual setup needed.
31
+
32
+ If you prefer manual setup:
33
+
34
+ ```bash
35
+ qmd collection add ~/.pi/agent/memory --name pi-memory
36
+ qmd context add /daily "Daily append-only work logs organized by date" -c pi-memory
37
+ qmd context add / "Curated long-term memory: decisions, preferences, facts, lessons" -c pi-memory
38
+ qmd embed
39
+ ```
40
+
41
+ Without qmd, all core tools (write/read/scratchpad) work normally. Only `memory_search` and selective injection require qmd.
42
+
43
+ ## Tools
44
+
45
+ | Tool | Description |
46
+ |------|-------------|
47
+ | `memory_write` | Write to MEMORY.md (long-term) or daily log |
48
+ | `memory_read` | Read any memory file or list daily logs |
49
+ | `scratchpad` | Add/done/undo/clear/list checklist items |
50
+ | `memory_search` | Search across all memory files (requires qmd) |
51
+
52
+ ### memory_search modes
53
+
54
+ | Mode | Speed | Method | Best for |
55
+ |------|-------|--------|----------|
56
+ | `keyword` | ~30ms | BM25 | Specific terms, dates, names, #tags, [[links]] |
57
+ | `semantic` | ~2s | Vector search | Related concepts, different wording |
58
+ | `deep` | ~10s | Hybrid + reranking | When other modes miss |
59
+
60
+ If the first search doesn't find what you need, try rephrasing or switching modes.
61
+
62
+ ## File layout
63
+
64
+ ```
65
+ ~/.pi/agent/memory/
66
+ MEMORY.md # Curated long-term memory
67
+ SCRATCHPAD.md # Checklist of things to fix/remember
68
+ daily/
69
+ 2026-02-15.md # Daily append-only log
70
+ 2026-02-14.md
71
+ ...
72
+ ```
73
+
74
+ ## How it works
75
+
76
+ ### Context injection
77
+
78
+ Before every agent turn, the following are injected into the system prompt (in priority order):
79
+
80
+ 1. **Open scratchpad items** (up to 2K chars)
81
+ 2. **Today's daily log** (up to 3K chars, tail)
82
+ 3. **Relevant memories via qmd search** (up to 2.5K chars) — searches using the user's current prompt to surface related past context
83
+ 4. **MEMORY.md** (up to 4K chars, middle-truncated)
84
+ 5. **Yesterday's daily log** (up to 3K chars, tail — lowest priority, trimmed first)
85
+
86
+ Total injection is capped at 16K chars. When qmd is unavailable, step 3 is skipped and the rest works as before.
87
+
88
+ ### Selective injection
89
+
90
+ When qmd is available, the extension automatically searches memory using the user's prompt before each turn. The top 3 keyword results are injected alongside the standard context. This surfaces relevant past decisions, preferences, and notes — even from daily logs older than yesterday — without the agent needing to explicitly call `memory_search`.
91
+
92
+ The search has a 3-second timeout and fails silently. If qmd is down or the query returns nothing, injection falls back to the standard behavior.
93
+
94
+ ### Tags and links
95
+
96
+ Use `#tags` and `[[wiki-links]]` in memory content to improve searchability:
97
+
98
+ ```markdown
99
+ #decision [[database-choice]] Chose PostgreSQL for all backend services.
100
+ #preference [[editor]] User prefers Neovim with LazyVim config.
101
+ #lesson [[api-versioning]] URL prefix versioning (/v1/) avoids CDN cache issues.
102
+ ```
103
+
104
+ These are content conventions, not enforced metadata. qmd's full-text indexing makes them searchable for free.
105
+
106
+ ### Session handoff
107
+
108
+ When the context window compacts, the extension automatically captures a handoff entry in today's daily log:
109
+
110
+ ```markdown
111
+ <!-- HANDOFF 2026-02-15 14:30:00 [a1b2c3d4] -->
112
+ ## Session Handoff
113
+ **Open scratchpad items:**
114
+ - [ ] Fix auth bug
115
+ - [ ] Review PR #42
116
+ **Recent daily log context:**
117
+ ...last 15 lines of today's log...
118
+ ```
119
+
120
+ This ensures in-progress context survives compaction and is visible in the next turn (via today's daily log injection).
121
+
122
+ ### Other behavior
123
+
124
+ - **Persistence**: Memory files are plain markdown on disk — readable, editable, and git-friendly.
125
+ - **Tool response previews**: Write/scratchpad tools return size-capped previews instead of full file contents.
126
+ - **qmd auto-setup**: On first session start with qmd available, the extension creates the collection and path contexts automatically.
127
+ - **qmd re-indexing**: After every write, a debounced `qmd update` runs in the background (fire-and-forget, non-blocking) unless disabled via `PI_MEMORY_QMD_UPDATE`.
128
+ - **Graceful degradation**: If qmd is not installed, core tools work fine. `memory_search` returns install instructions.
129
+
130
+ ### Configuration
131
+
132
+ | Variable | Values | Default | Description |
133
+ |----------|--------|---------|-------------|
134
+ | `PI_MEMORY_QMD_UPDATE` | `background`, `manual`, `off` | `background` | Controls automatic `qmd update` after writes |
135
+ | `PI_MEMORY_NO_SEARCH` | `1` | unset | Disable selective injection (for A/B testing) |
136
+
137
+ ## Running tests
138
+
139
+ ```bash
140
+ # Unit tests (no LLM, no qmd — fast, deterministic)
141
+ bun test/unit.ts
142
+
143
+ # End-to-end tests (requires pi + API key, optionally qmd)
144
+ bun test/e2e.ts
145
+
146
+ # Recall effectiveness eval (requires pi + API key + qmd)
147
+ bun test/eval-recall.ts
148
+
149
+ # Pin provider/model for cheaper eval runs
150
+ PI_E2E_PROVIDER=openai PI_E2E_MODEL=gpt-4o-mini bun test/eval-recall.ts
151
+
152
+ # Multiple runs for statistical robustness
153
+ EVAL_RUNS=3 bun test/eval-recall.ts
154
+ ```
155
+
156
+ All tests back up and restore existing memory files.
157
+
158
+ ### Test levels
159
+
160
+ | Level | File | Requirements | What it tests |
161
+ |-------|------|-------------|---------------|
162
+ | Unit | `test/unit.ts` | None | Context builder, truncation, handoff, scratchpad parsing |
163
+ | E2E | `test/e2e.ts` | pi + API key | Tool registration, write/recall, scratchpad lifecycle, search |
164
+ | Eval | `test/eval-recall.ts` | pi + API key + qmd | Recall accuracy with vs without selective injection |
165
+
166
+ ## Development
167
+
168
+ This is a single-file extension (`index.ts`). No build step required — pi loads TypeScript directly.
169
+
170
+ ```bash
171
+ # Test with pi directly
172
+ pi -p -e ./index.ts "remember: I prefer dark mode"
173
+
174
+ # Verify memory was written
175
+ cat ~/.pi/agent/memory/MEMORY.md
176
+ ```
177
+
178
+ ## Publishing (maintainers)
179
+
180
+ ```bash
181
+ # Confirm package name is available
182
+ npm view pi-memory
183
+
184
+ # Bump version (choose patch/minor/major)
185
+ npm version patch
186
+
187
+ # Publish to npm (public)
188
+ npm publish --access public
189
+
190
+ # Verify install
191
+ pi install npm:pi-memory
192
+ ```
193
+
194
+ ## Changelog
195
+
196
+ ### 0.2.0
197
+
198
+ - **Selective injection**: Before each turn, the user's prompt is searched against memory via qmd. Top results are injected into the system prompt alongside standard context, surfacing relevant past decisions without explicit tool calls.
199
+ - **qmd auto-setup**: The extension automatically creates the `pi-memory` collection and path contexts on session start when qmd is available. No manual `qmd collection add` needed.
200
+ - **Tags and links**: `memory_write` and context injection now encourage `#tags` and `[[wiki-links]]` as searchable content conventions.
201
+ - **Session handoff on compaction**: `session_before_compact` automatically writes a handoff entry to today's daily log with open scratchpad items and recent context, preserving in-progress state across context compaction.
202
+ - **Improved memory_search description**: Encourages iterative search (rephrasing, mode-switching) and mentions tags/links in keyword mode.
203
+ - **Context priority reordering**: Injection order is now scratchpad > today > search results > MEMORY.md > yesterday (previously MEMORY.md was first). MEMORY.md budget reduced from 6K to 4K to make room for search results (2.5K).
204
+ - **`PI_MEMORY_NO_SEARCH` env var**: Disable selective injection for A/B testing.
205
+ - **Unit tests**: Added `test/unit.ts` with 18 deterministic tests (no LLM/qmd needed).
206
+ - **Recall eval**: Added `test/eval-recall.ts` for measuring recall effectiveness with/without selective injection.
207
+
208
+ ### 0.1.0
209
+
210
+ - Initial release: `memory_write`, `memory_read`, `scratchpad`, `memory_search` tools.
211
+ - Context injection of MEMORY.md, scratchpad, and today/yesterday daily logs.
212
+ - qmd integration for keyword, semantic, and hybrid search.
213
+ - Debounced background `qmd update` after writes.