pi-automem-bridge 0.2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 vaniteav
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,190 @@
1
+ <div align="center">
2
+
3
+ # pi-automem-bridge
4
+
5
+ The missing link between [pi](https://github.com/earendil-works/pi) and [AutoMem](https://github.com/verygoodplugins/automem). If you already have both set up, this package connects them — giving pi automatic long-term memory: startup recall, turn-level recall, policy-gated writes, and relationship tools.
6
+
7
+ ```bash
8
+ pi install npm:pi-automem-bridge
9
+ ```
10
+
11
+ [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/L2J320X82M)
12
+
13
+ </div>
14
+
15
+ ---
16
+
17
+ ## Before you begin
18
+
19
+ This package does not include pi or AutoMem — it connects them. You need both running independently first:
20
+
21
+ 1. **[pi](https://github.com/earendil-works/pi)** — the agent this extension runs inside
22
+ 2. **[AutoMem](https://github.com/verygoodplugins/automem)** — the graph-vector memory service (self-hosted or Railway)
23
+ 3. **[mcp-automem](https://github.com/verygoodplugins/mcp-automem)** — the MCP bridge that exposes AutoMem's tools over the MCP protocol
24
+
25
+ Once those three are in place, add `mcp-automem` to pi's MCP config and install this package. That's all the wiring this package needs.
26
+
27
+ ---
28
+
29
+ ## What it does
30
+
31
+ - **Startup recall** — at session start, queries AutoMem for your preferences, working style, and environment
32
+ - **Turn-level recall** — before each agent prompt, retrieves memories relevant to the current task and detected project
33
+ - **Silent injection** — memory context is injected into the system prompt, not the chat window
34
+ - **Policy-gated writes** — every memory write is validated, secret-scanned, deduplicated, and confirmed before storage
35
+ - **Relationship tools** — link memories to each other or record corrections with provenance history
36
+ - **Per-project tuning** — configure different recall limits and filters per detected project
37
+
38
+ ---
39
+
40
+ ## Getting started
41
+
42
+ **1. Add your AutoMem server to `~/.pi/agent/mcp.json`:**
43
+
44
+ ```json
45
+ {
46
+ "mcpServers": {
47
+ "automem": {
48
+ "url": "https://your-automem-server.example.com/mcp",
49
+ "headers": {
50
+ "Authorization": "Bearer ${AUTOMEM_TOKEN}"
51
+ }
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ Use `${ENV_VAR}` interpolation for secrets. Never hardcode credentials.
58
+
59
+ **2. Create `~/.pi/agent/automem.json`:**
60
+
61
+ ```json
62
+ {
63
+ "mcpServerName": "automem",
64
+ "startupRecall": {
65
+ "queries": [
66
+ "user preferences working style",
67
+ "current environment setup",
68
+ "active projects and recent decisions"
69
+ ]
70
+ },
71
+ "behavior": {
72
+ "displayRecall": "summary"
73
+ }
74
+ }
75
+ ```
76
+
77
+ **3. Start or reload pi.** Recall is now automatic.
78
+
79
+ ---
80
+
81
+ ## Commands
82
+
83
+ | Command | What it does |
84
+ |---|---|
85
+ | `/automem-status` | Health check — shows memory count and active config |
86
+ | `/automem-recall <query>` | Manual recall query for debugging |
87
+
88
+ ## Tools
89
+
90
+ | Tool | What it does |
91
+ |---|---|
92
+ | `automem_propose_memory` | Preview a memory candidate — validates, scans for secrets, checks for duplicates. Does not write. |
93
+ | `automem_commit_memory` | Store a policy-approved memory. Returns `DUPLICATE_DETECTED` if a similar memory exists. |
94
+ | `automem_update_memory` | Update an existing memory by ID. |
95
+ | `automem_link_memories` | Create a typed relationship between two existing memories. |
96
+ | `automem_correct_memory` | Store a correction and link old → new with a provenance relationship (EVOLVED_INTO or CONTRADICTS). |
97
+
98
+ ---
99
+
100
+ ## Write policy
101
+
102
+ Every write goes through: normalize → secret scan → policy check → dedupe → confirm/auto → store. Nothing bypasses this pipeline.
103
+
104
+ ```json
105
+ {
106
+ "writePolicy": {
107
+ "mode": "safe-auto",
108
+ "autoWriteCategories": ["technical-decision", "agent-pattern", "bug-fix", "tooling-lesson"],
109
+ "confirmCategories": ["personal", "financial", "private", "identity"],
110
+ "blockedCategories": ["secret", "credential", "api-key", "raw-transcript"],
111
+ "minImportanceToWrite": 0.7,
112
+ "dedupeBeforeWrite": true
113
+ }
114
+ }
115
+ ```
116
+
117
+ | Mode | Behavior |
118
+ |---|---|
119
+ | `safe-auto` | Auto-write configured low-risk categories; confirm everything else. **Default.** |
120
+ | `propose` | Propose all candidates; require explicit approval to commit. |
121
+ | `confirm-all` | Confirm every write individually. |
122
+ | `off` | Block all writes. |
123
+
124
+ ### Duplicate handling
125
+
126
+ When a commit finds a close match, `automem_commit_memory` returns `DUPLICATE_DETECTED` with the existing memory's ID. Options:
127
+ 1. Update it — re-call with `updateMemoryId` set to the returned ID
128
+ 2. Force a new store — set `dedupeQuery: ""` to skip the check
129
+ 3. Cancel — do nothing if the existing memory already covers it
130
+
131
+ ---
132
+
133
+ ## Recall display modes
134
+
135
+ | Mode | Behavior |
136
+ |---|---|
137
+ | `hidden` | Inject into system prompt only. Nothing shown in chat. |
138
+ | `summary` | Inject into system prompt + show a compact notification. |
139
+ | `full` | Show the full recall block. Useful for debugging. |
140
+
141
+ ---
142
+
143
+ ## Configuration reference
144
+
145
+ Config file: `~/.pi/agent/automem.json` (or `AUTOMEM_CONFIG_PATH`)
146
+
147
+ | Section | Purpose |
148
+ |---|---|
149
+ | `mcpServerName` | Which server in `mcp.json` to use |
150
+ | `startupRecall` | Queries, tags, limits, byte budget for session-start recall |
151
+ | `turnRecall` | Per-prompt recall: limits, memory types, relation/entity expansion |
152
+ | `projectDetection` | Map git repos and folder names to project tags for scoped recall |
153
+ | `projectOverrides` | Per-project overrides for turn recall limits and filters |
154
+ | `writePolicy` | Write mode, categories, importance threshold, dedupe settings |
155
+ | `behavior` | Display mode and content-length preferences |
156
+
157
+ See [`examples/config.minimal.json`](examples/config.minimal.json) and [`examples/config.advanced.json`](examples/config.advanced.json).
158
+
159
+ ---
160
+
161
+ ## Development
162
+
163
+ ```bash
164
+ git clone https://github.com/vaniteav/pi-automem-bridge.git
165
+ cd pi-automem-bridge
166
+ npm install
167
+ npm test # offline tests
168
+ npm run test:smoke # live smoke test (requires AutoMem)
169
+ npm run test:live # full round-trip write test (requires AutoMem)
170
+ ```
171
+
172
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for architecture notes, test descriptions, and release process.
173
+
174
+ ---
175
+
176
+ ## Credits
177
+
178
+ This package builds on two excellent open-source projects:
179
+
180
+ - **[pi](https://github.com/earendil-works/pi)** by [Earendil Works](https://github.com/earendil-works) — the extensible AI agent toolkit this package runs on
181
+ - **[AutoMem](https://github.com/verygoodplugins/automem)** by [Very Good Plugins](https://github.com/verygoodplugins) — the graph-vector memory service powering recall and storage
182
+ - **[mcp-automem](https://github.com/verygoodplugins/mcp-automem)** by [Very Good Plugins](https://github.com/verygoodplugins) — the MCP bridge this extension communicates through
183
+
184
+ ---
185
+
186
+ ## License
187
+
188
+ MIT — [vaniteav](https://github.com/vaniteav)
189
+
190
+ ---
@@ -0,0 +1,59 @@
1
+ {
2
+ "mcpServerName": "automem",
3
+ "startupRecall": {
4
+ "queries": [
5
+ "user preferences working style",
6
+ "agent operating guidelines",
7
+ "local development environment",
8
+ "active projects recent decisions"
9
+ ],
10
+ "tags": ["source:pi"],
11
+ "tagMode": "any",
12
+ "limit": 6,
13
+ "maxBytes": 5000
14
+ },
15
+ "turnRecall": {
16
+ "enabled": true,
17
+ "limit": 5,
18
+ "maxBytes": 3000,
19
+ "contextTypes": ["Preference", "Decision", "Pattern", "Insight", "Context"],
20
+ "expandRelations": true,
21
+ "expandEntities": true
22
+ },
23
+ "projectDetection": {
24
+ "tagPrefix": "project:",
25
+ "folderTags": {
26
+ "projects": ["project"],
27
+ "areas": ["area"],
28
+ "resources": ["resource"]
29
+ },
30
+ "gitRepoToTag": {
31
+ "my-project": "project:my-project"
32
+ }
33
+ },
34
+ "writePolicy": {
35
+ "mode": "safe-auto",
36
+ "autoWriteCategories": ["technical-decision", "agent-pattern", "bug-fix", "tooling-lesson"],
37
+ "confirmCategories": ["personal", "financial", "private", "identity"],
38
+ "blockedCategories": ["secret", "credential", "api-key", "raw-transcript"],
39
+ "alwaysTag": ["source:pi"],
40
+ "minImportanceToWrite": 0.7,
41
+ "dedupeBeforeWrite": true,
42
+ "dedupeLimit": 3
43
+ },
44
+ "behavior": {
45
+ "displayRecall": "hidden",
46
+ "maxContentLength": 2000,
47
+ "preferredContentLength": 500
48
+ },
49
+ "projectOverrides": {
50
+ "project:my-large-project": {
51
+ "limit": 10,
52
+ "maxBytes": 6000
53
+ },
54
+ "project:quick-scripts": {
55
+ "limit": 2,
56
+ "maxBytes": 1000
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "mcpServerName": "automem",
3
+ "startupRecall": {
4
+ "queries": ["my preferences and working style"],
5
+ "limit": 5
6
+ },
7
+ "writePolicy": {
8
+ "alwaysTag": ["source:pi"]
9
+ }
10
+ }
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "pi-automem-bridge",
3
+ "version": "0.2.0",
4
+ "description": "Automatic long-term memory recall and policy-gated writes for pi agents via AutoMem MCP",
5
+ "keywords": [
6
+ "pi-package",
7
+ "pi-extension",
8
+ "automem",
9
+ "mcp",
10
+ "memory",
11
+ "long-term-memory",
12
+ "semantic-memory",
13
+ "memory-write-policy",
14
+ "agent-memory"
15
+ ],
16
+ "license": "MIT",
17
+ "author": "vaniteav",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/vaniteav/pi-automem-bridge.git"
21
+ },
22
+ "peerDependencies": {
23
+ "@earendil-works/pi-coding-agent": ">=0.78.0",
24
+ "typebox": "*"
25
+ },
26
+ "scripts": {
27
+ "test": "tsx tests/unit.ts && tsx tests/write-policy.ts",
28
+ "test:smoke": "tsx tests/smoke.ts",
29
+ "test:live": "tsx tests/live-write.ts"
30
+ },
31
+ "devDependencies": {
32
+ "tsx": "^4.20.6"
33
+ },
34
+ "dependencies": {},
35
+ "pi": {
36
+ "extensions": [
37
+ "./src/index.ts"
38
+ ],
39
+ "skills": [
40
+ "./skills"
41
+ ],
42
+ "prompts": [
43
+ "./prompts"
44
+ ]
45
+ },
46
+ "bugs": {
47
+ "url": "https://github.com/vaniteav/pi-automem-bridge/issues"
48
+ },
49
+ "homepage": "https://github.com/vaniteav/pi-automem-bridge#readme",
50
+ "files": [
51
+ "src",
52
+ "skills",
53
+ "prompts",
54
+ "examples",
55
+ "README.md",
56
+ "LICENSE"
57
+ ]
58
+ }
@@ -0,0 +1,42 @@
1
+ # AutoMem Behavioral Guidelines
2
+
3
+ AutoMem is pi's long-term semantic memory, available automatically in this session.
4
+
5
+ ## What's already done for you
6
+
7
+ - **Startup recall** ran at session start — relevant memories about preferences, environment, and operating style are already loaded.
8
+ - **Turn-level recall** runs before every agent turn — memories related to the current project and prompt are automatically injected.
9
+ - The `/automem-status` command shows health and memory count.
10
+ - The `/automem-recall <query>` command does manual recall for debugging.
11
+
12
+ ## Recall behavior
13
+
14
+ - Startup recall runs at session start and turn-level recall runs before each agent turn.
15
+ - Use `/automem-recall <query>` for manual recall/debugging.
16
+ - If AutoMem is unreachable, pi works normally — the footer status indicator shows "AutoMem (offline)".
17
+
18
+ ## Write behavior
19
+
20
+ - Do **not** write raw session transcripts, long summaries, or incidental chatter.
21
+ - Use `automem_propose_memory` first for durable candidates. It validates type/tags/importance, scans for secrets, and checks for similar memories.
22
+ - Use `automem_commit_memory` only after explicit user approval, unless the category is in the safe-auto list (technical-decision, agent-pattern, bug-fix, tooling-lesson) — those auto-write by default.
23
+ - Good memory candidates are compact, intentional, and useful across sessions: decisions, preferences, repeated patterns, key insights, durable bug-fix lessons, and important project context.
24
+
25
+ ## Relationship tools
26
+
27
+ - `automem_link_memories` — create a typed relationship between two existing memories by ID. Requires both IDs and a `RelationshipType`. Use after recognizing that two stored memories are causally or semantically linked.
28
+ - `automem_correct_memory` — store a corrected version of an existing memory and link the old memory to the new one (EVOLVED_INTO or CONTRADICTS). Use when the original memory was wrong or outdated and you want to preserve the history. For simple in-place edits, use `automem_update_memory` instead.
29
+
30
+ ## Memory types
31
+
32
+ AutoMem uses 7 typed memories: Decision, Pattern, Preference, Style, Habit, Insight, Context.
33
+
34
+ ## Relationship types
35
+
36
+ The 11 relationship types are: RELATES_TO, LEADS_TO, OCCURRED_BEFORE, PREFERS_OVER, EXEMPLIFIES, CONTRADICTS, REINFORCES, INVALIDATED_BY, EVOLVED_INTO, DERIVED_FROM, PART_OF.
37
+
38
+ ## What NOT to do
39
+
40
+ - Never store secrets, API keys, credentials, or raw conversation transcripts in AutoMem.
41
+ - Never store unverified guesses as facts.
42
+ - If AutoMem content conflicts with live files or known current state, trust live state first.
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: automem-bridge
3
+ description: Long-term semantic memory for pi via AutoMem MCP. Provides startup recall, turn-level recall, project detection, and memory health status. Use when the session starts, when recalling context, or when checking AutoMem health.
4
+ ---
5
+
6
+ # AutoMem Core Extension
7
+
8
+ Long-term semantic memory for pi via AutoMem MCP.
9
+
10
+ ## Commands
11
+
12
+ - `/automem-status` — Show AutoMem health, memory count, and config summary
13
+ - `/automem-recall <query>` — Manually query AutoMem (debugging)
14
+ - `automem_propose_memory` — Validate/preview a durable memory candidate without writing
15
+ - `automem_commit_memory` — Store a policy-approved memory after confirmation or safe-auto policy
16
+ - `automem_link_memories` — Create a typed relationship between two existing memories
17
+ - `automem_correct_memory` — Store a correction and link old → new with provenance (EVOLVED_INTO/CONTRADICTS)
18
+
19
+ ## Config
20
+
21
+ Config lives at `~/.pi/agent/automem.json`. See the README for the full schema.
22
+
23
+ Key settings:
24
+ - `startupRecall.enabled` — Run recall at session start (default: true)
25
+ - `startupRecall.queries` — Queries to run at startup
26
+ - `turnRecall.enabled` — Run recall before each agent turn (default: true)
27
+ - `projectDetection.enabled` — Auto-detect project from git/cwd (default: true)
28
+
29
+ ## Status indicator
30
+
31
+ The footer shows:
32
+ - `● AutoMem (42)` — healthy, 42 memories
33
+ - `● AutoMem (offline)` — unreachable
34
+
35
+ ## Write policy
36
+
37
+ Default mode is safe-auto for the four low-risk categories (technical-decision, agent-pattern, bug-fix, tooling-lesson); all other writes require explicit approval. Store only compact durable knowledge: decisions, preferences, patterns, insights, and important context. Never store secrets, credentials, raw transcripts, or incidental chatter.
38
+
39
+ Use `automem_propose_memory` before committing. Use `automem_commit_memory` only after explicit user approval unless config enables safe-auto for the exact low-risk category.
40
+
41
+ If AutoMem is down, pi works normally with a warning.
@@ -0,0 +1,44 @@
1
+ /**
2
+ * /automem-recall - Manual recall for debugging.
3
+ */
4
+
5
+ import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
6
+ import { automemRecall, setAutoMemMcpServerName } from "../mcp-client";
7
+ import { loadConfig } from "../config";
8
+
9
+ export function registerRecallCommand(pi: {
10
+ registerCommand: (name: string, opts: {
11
+ description: string;
12
+ handler: (args: string, ctx: ExtensionCommandContext) => Promise<void>;
13
+ }) => void;
14
+ }) {
15
+ pi.registerCommand("automem-recall", {
16
+ description: "Manually query AutoMem: /automem-recall <query>",
17
+ handler: async function(args: string, ctx: ExtensionCommandContext) {
18
+ const query = args.trim();
19
+ if (!query) {
20
+ ctx.ui.notify("Usage: /automem-recall <query>", "warning");
21
+ return;
22
+ }
23
+
24
+ const config = loadConfig();
25
+ setAutoMemMcpServerName(config.mcpServerName);
26
+
27
+ try {
28
+ const result = await automemRecall(query, {
29
+ limit: config.startupRecall.limit,
30
+ tags: config.startupRecall.tags,
31
+ tagMode: config.startupRecall.tagMode,
32
+ });
33
+
34
+ const text = (result.content && result.content[0] && result.content[0].text)
35
+ ? result.content[0].text
36
+ : "(no results)";
37
+ const preview = text.length > 500 ? text.slice(0, 500) + "..." : text;
38
+ ctx.ui.notify('Results for "' + query + '":\n' + preview, "info");
39
+ } catch (err) {
40
+ ctx.ui.notify("Recall failed: " + err, "error");
41
+ }
42
+ },
43
+ });
44
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * /automem-status - Show AutoMem health, memory count, and config summary.
3
+ */
4
+
5
+ import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
6
+ import { automemHealth, setAutoMemMcpServerName } from "../mcp-client";
7
+ import { loadConfig } from "../config";
8
+
9
+ export function registerStatusCommand(pi: {
10
+ registerCommand: (name: string, opts: {
11
+ description: string;
12
+ handler: (args: string, ctx: ExtensionCommandContext) => Promise<void>;
13
+ }) => void;
14
+ }) {
15
+ pi.registerCommand("automem-status", {
16
+ description: "Show AutoMem health and memory count",
17
+ handler: async function(_args: string, ctx: ExtensionCommandContext) {
18
+ const config = loadConfig();
19
+ setAutoMemMcpServerName(config.mcpServerName);
20
+
21
+ ctx.ui.notify("Checking AutoMem...", "info");
22
+
23
+ const health = await automemHealth();
24
+
25
+ if (health.healthy) {
26
+ const count = health.memoryCount != null ? " (" + health.memoryCount + " memories)" : "";
27
+ ctx.ui.notify("AutoMem: healthy" + count, "success");
28
+ } else {
29
+ ctx.ui.notify("AutoMem: unhealthy - " + (health.error || "unknown error"), "error");
30
+ }
31
+
32
+ ctx.ui.notify(
33
+ "Config: startup=" + (config.startupRecall.enabled ? "on" : "off") +
34
+ " turn=" + (config.turnRecall.enabled ? "on" : "off") +
35
+ " project=" + (config.projectDetection.enabled ? "on" : "off"),
36
+ "info",
37
+ );
38
+ },
39
+ });
40
+ }