pi-automem-core 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,173 @@
1
+ # pi-automem-core
2
+
3
+ Long-term semantic memory for [pi](https://pi.dev) agents via [AutoMem](https://github.com/your-automem-link) MCP.
4
+
5
+ ```bash
6
+ pi install npm:pi-automem-core
7
+ ```
8
+
9
+ ---
10
+
11
+ ## What it does
12
+
13
+ - **Startup recall** — at session start, queries AutoMem for your preferences, working style, and environment
14
+ - **Turn-level recall** — before each agent prompt, retrieves memories relevant to the current task and detected project
15
+ - **Silent injection** — memory context is injected into the system prompt, not the chat window
16
+ - **Policy-gated writes** — every memory write is validated, secret-scanned, deduplicated, and confirmed before storage
17
+ - **Relationship tools** — link memories to each other or record corrections with provenance history
18
+ - **Per-project tuning** — configure different recall limits and filters per detected project
19
+
20
+ ---
21
+
22
+ ## Requirements
23
+
24
+ - pi with package support
25
+ - An AutoMem-compatible MCP server configured in `~/.pi/agent/mcp.json`
26
+
27
+ The extension reads your existing MCP config — it does not store credentials or server URLs.
28
+
29
+ ---
30
+
31
+ ## Getting started
32
+
33
+ **1. Add your AutoMem server to `~/.pi/agent/mcp.json`:**
34
+
35
+ ```json
36
+ {
37
+ "mcpServers": {
38
+ "automem": {
39
+ "url": "https://your-automem-server.example.com/mcp",
40
+ "headers": {
41
+ "Authorization": "Bearer ${AUTOMEM_TOKEN}"
42
+ }
43
+ }
44
+ }
45
+ }
46
+ ```
47
+
48
+ Use `${ENV_VAR}` interpolation for secrets. Never hardcode credentials.
49
+
50
+ **2. Create `~/.pi/agent/automem.json`:**
51
+
52
+ ```json
53
+ {
54
+ "mcpServerName": "automem",
55
+ "startupRecall": {
56
+ "queries": [
57
+ "user preferences working style",
58
+ "current environment setup",
59
+ "active projects and recent decisions"
60
+ ]
61
+ },
62
+ "behavior": {
63
+ "displayRecall": "summary"
64
+ }
65
+ }
66
+ ```
67
+
68
+ **3. Start or reload pi.** Recall is now automatic.
69
+
70
+ ---
71
+
72
+ ## Commands
73
+
74
+ | Command | What it does |
75
+ |---|---|
76
+ | `/automem-status` | Health check — shows memory count and active config |
77
+ | `/automem-recall <query>` | Manual recall query for debugging |
78
+
79
+ ## Tools
80
+
81
+ | Tool | What it does |
82
+ |---|---|
83
+ | `automem_propose_memory` | Preview a memory candidate — validates, scans for secrets, checks for duplicates. Does not write. |
84
+ | `automem_commit_memory` | Store a policy-approved memory. Returns `DUPLICATE_DETECTED` if a similar memory exists. |
85
+ | `automem_update_memory` | Update an existing memory by ID. |
86
+ | `automem_link_memories` | Create a typed relationship between two existing memories. |
87
+ | `automem_correct_memory` | Store a correction and link old → new with a provenance relationship (EVOLVED_INTO or CONTRADICTS). |
88
+
89
+ ---
90
+
91
+ ## Write policy
92
+
93
+ Every write goes through: normalize → secret scan → policy check → dedupe → confirm/auto → store. Nothing bypasses this pipeline.
94
+
95
+ ```json
96
+ {
97
+ "writePolicy": {
98
+ "mode": "safe-auto",
99
+ "autoWriteCategories": ["technical-decision", "agent-pattern", "bug-fix", "tooling-lesson"],
100
+ "confirmCategories": ["personal", "financial", "private", "identity"],
101
+ "blockedCategories": ["secret", "credential", "api-key", "raw-transcript"],
102
+ "minImportanceToWrite": 0.7,
103
+ "dedupeBeforeWrite": true
104
+ }
105
+ }
106
+ ```
107
+
108
+ | Mode | Behavior |
109
+ |---|---|
110
+ | `safe-auto` | Auto-write configured low-risk categories; confirm everything else. **Default.** |
111
+ | `propose` | Propose all candidates; require explicit approval to commit. |
112
+ | `confirm-all` | Confirm every write individually. |
113
+ | `off` | Block all writes. |
114
+
115
+ ### Duplicate handling
116
+
117
+ When a commit finds a close match, `automem_commit_memory` returns `DUPLICATE_DETECTED` with the existing memory's ID. Options:
118
+ 1. Update it — re-call with `updateMemoryId` set to the returned ID
119
+ 2. Force a new store — set `dedupeQuery: ""` to skip the check
120
+ 3. Cancel — do nothing if the existing memory already covers it
121
+
122
+ ---
123
+
124
+ ## Recall display modes
125
+
126
+ | Mode | Behavior |
127
+ |---|---|
128
+ | `hidden` | Inject into system prompt only. Nothing shown in chat. |
129
+ | `summary` | Inject into system prompt + show a compact notification. |
130
+ | `full` | Show the full recall block. Useful for debugging. |
131
+
132
+ ---
133
+
134
+ ## Configuration reference
135
+
136
+ Config file: `~/.pi/agent/automem.json` (or `AUTOMEM_CONFIG_PATH`)
137
+
138
+ | Section | Purpose |
139
+ |---|---|
140
+ | `mcpServerName` | Which server in `mcp.json` to use |
141
+ | `startupRecall` | Queries, tags, limits, byte budget for session-start recall |
142
+ | `turnRecall` | Per-prompt recall: limits, memory types, relation/entity expansion |
143
+ | `projectDetection` | Map git repos and folder names to project tags for scoped recall |
144
+ | `projectOverrides` | Per-project overrides for turn recall limits and filters |
145
+ | `writePolicy` | Write mode, categories, importance threshold, dedupe settings |
146
+ | `behavior` | Display mode and content-length preferences |
147
+
148
+ See [`examples/config.minimal.json`](examples/config.minimal.json) and [`examples/config.advanced.json`](examples/config.advanced.json).
149
+
150
+ ---
151
+
152
+ ## Development
153
+
154
+ ```bash
155
+ git clone https://github.com/vaniteav/pi-automem-core.git
156
+ cd pi-automem-core
157
+ npm install
158
+ npm test # offline tests
159
+ npm run test:phase1 # live smoke test (requires AutoMem)
160
+ npm run test:phase2:live # full round-trip write test (requires AutoMem)
161
+ ```
162
+
163
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for architecture notes, test descriptions, and release process.
164
+
165
+ ---
166
+
167
+ ## License
168
+
169
+ MIT — [vaniteav](https://github.com/vaniteav)
170
+
171
+ ---
172
+
173
+ [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/L2J320X82M)
@@ -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,60 @@
1
+ {
2
+ "name": "pi-automem-core",
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-core.git"
21
+ },
22
+ "peerDependencies": {
23
+ "@earendil-works/pi-coding-agent": ">=0.78.0",
24
+ "typebox": "*"
25
+ },
26
+ "scripts": {
27
+ "test:unit": "tsx tests/unit.ts",
28
+ "test:phase1": "tsx tests/phase1-smoke.ts",
29
+ "test:phase2": "tsx tests/phase2-policy.ts",
30
+ "test": "npm run test:unit && npm run test:phase2",
31
+ "test:phase2:live": "tsx tests/phase2-live-write.ts"
32
+ },
33
+ "devDependencies": {
34
+ "tsx": "^4.20.6"
35
+ },
36
+ "dependencies": {},
37
+ "pi": {
38
+ "extensions": [
39
+ "./src/index.ts"
40
+ ],
41
+ "skills": [
42
+ "./skills"
43
+ ],
44
+ "prompts": [
45
+ "./prompts"
46
+ ]
47
+ },
48
+ "bugs": {
49
+ "url": "https://github.com/vaniteav/pi-automem-core/issues"
50
+ },
51
+ "homepage": "https://github.com/vaniteav/pi-automem-core#readme",
52
+ "files": [
53
+ "src",
54
+ "skills",
55
+ "prompts",
56
+ "examples",
57
+ "README.md",
58
+ "LICENSE"
59
+ ]
60
+ }
@@ -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-core
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
+ }