stackmem 1.0.21 → 1.0.22

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/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # stackmem
2
2
 
3
- AI agents forget everything between sessions. Every new chat re-derives decisions, re-breaks constraints that were already settled, and re-debugs errors that were already fixed last week.
3
+ Persistent memory for AI coding agents. Zero config. Installs in 60 seconds.
4
4
 
5
- stackmem is a CLI and an MCP server that stores that context in Supabase and hands it back at the start of the next session. A git post-commit hook captures most of it automatically.
5
+ ## The problem
6
+
7
+ Every session with an AI coding agent starts from zero. You re-explain the same stack, the same constraints, the same "we tried that and it didn't work" — and the agent repeats mistakes it already made last week, because nothing it learned last session survived the chat closing.
6
8
 
7
9
  ## Install
8
10
 
@@ -10,196 +12,116 @@ stackmem is a CLI and an MCP server that stores that context in Supabase and han
10
12
  npm install -g stackmem
11
13
  ```
12
14
 
13
- Then in any git repo:
14
-
15
- ```
16
- cm init <project> .
17
- ```
18
-
19
- `cm init <project> .` does three things automatically:
20
-
21
- 1. Installs a git post-commit hook
22
- 2. Registers the stackmem MCP server with Claude Code
23
- 3. Writes a CLAUDE.md to the project
24
-
25
- After that, memories load automatically when you open Claude Code and save automatically on every commit. No further setup needed.
26
-
27
- ## Usage
28
-
29
- ```
30
- cm start <project>
31
- cm save <project> <type> <content> [--force]
32
- cm fix <project> <problem> <solution>
33
- cm analyze <project> <path>
34
- cm search <project> <query>
35
- cm resolve <project> <memory-id>
36
- cm delete <project> <memory-id>
37
- cm context <project> <task>
38
- cm compress <project>
39
- cm init <project> <path>
40
- cm help
41
- ```
42
-
43
- ### cm start
44
-
45
- ```
46
- $ cm start myapp
47
- Loaded 2 memory(ies) for "myapp".
48
-
49
- Decisions (1)
50
- -------------
51
- [294fba3a-aef3-472a-933f-b6bfd41c7cfa] Use Supabase for persistence layer
52
- linked: 793a0053-83b6-463a-9e6d-df8b7c2fbed8
53
-
54
- Constraints (1)
55
- ---------------
56
- [793a0053-83b6-463a-9e6d-df8b7c2fbed8] Service role key must never be exposed to a client
57
- linked: 294fba3a-aef3-472a-933f-b6bfd41c7cfa
58
- ```
59
-
60
- ### cm save
61
-
62
- `type` is one of `decision`, `rejection`, `constraint`, `discovery`.
63
-
64
- ```
65
- $ cm save myapp decision "Use ilike search across memories and execution_log"
66
- Saved decision [294fba3a-aef3-472a-933f-b6bfd41c7cfa] for "myapp".
67
- ```
68
-
69
- If the new content contradicts something already stored, it asks first.
70
-
71
- ```
72
- $ cm save myapp decision "We switched from Supabase to Postgres directly"
73
- Conflict detected:
74
- Old: Use Supabase for persistence layer
75
- New: We switched from Supabase to Postgres directly
76
-
77
- Keep old or replace? (k/r): r
78
- Replaced with new memory [b1a2c3d4-5678-90ab-cdef-1234567890ab].
79
- ```
80
-
81
- `--force` skips the prompt and always replaces. Use it from scripts.
82
-
83
- ```
84
- $ cm save myapp decision "We switched from Supabase to Postgres directly" --force
85
- Replaced with new memory [b1a2c3d4-5678-90ab-cdef-1234567890ab].
86
- Saved decision [b1a2c3d4-5678-90ab-cdef-1234567890ab] for "myapp".
87
- ```
88
-
89
- ### cm fix
90
-
91
- ```
92
- $ cm fix myapp "tsc failed with Node16 module resolution error" "switched moduleResolution to Node16"
93
- Fix recorded for "myapp".
94
- ```
95
-
96
- ### cm analyze
15
+ ## Setup
97
16
 
98
17
  ```
99
- $ cm analyze myapp .
100
- Indexed 7 file(s):
101
- functions: 24
102
- classes: 0
18
+ cd myproject
19
+ cm init myapp .
103
20
  ```
104
21
 
105
- Runs tree-sitter over the project and writes an AST index to `.coding-memory/ast-index.db`.
106
-
107
- ### cm search
108
-
109
- Checks memories and past fixes in the same query.
110
-
111
22
  ```
112
- $ cm search myapp "module resolution"
113
- Memories (0)
114
- No results found
23
+ ✓ .gitignore created
24
+ ✓ Git hook installed
25
+ ✓ MCP server registered
26
+ ✓ CLAUDE.md written
27
+ ✓ .cursorrules written
28
+ ✓ .windsurfrules written
29
+ ✓ Seeded 2 memories from project scan
30
+ ✓ Backend connection verified
115
31
 
116
- Past Fixes (1)
117
- Problem: tsc failed with Node16 module resolution error
118
- Solution: switched moduleResolution to Node16
32
+ stackmem is live. Open Claude Code and ask "what do you know about this project?" to verify.
119
33
  ```
120
34
 
121
- ### cm resolve / cm delete
35
+ That's it. Open Claude Code and ask "what do you know about this project?" to verify.
122
36
 
123
- ```
124
- $ cm resolve myapp 294fba3a-aef3-472a-933f-b6bfd41c7cfa
125
- Resolved memory [294fba3a-aef3-472a-933f-b6bfd41c7cfa]
37
+ ## How it works
126
38
 
127
- $ cm delete myapp 793a0053-83b6-463a-9e6d-df8b7c2fbed8
128
- Deleted memory [793a0053-83b6-463a-9e6d-df8b7c2fbed8]
129
- ```
39
+ Four layers, each feeding the next:
130
40
 
131
- `delete` also removes any memory_links pointing at that id.
41
+ - **Capture** — a git post-commit hook saves memories automatically on every commit: removed dependencies, new config files, auth-related files, TODOs, schema changes, and the commit message itself when it's substantive. No manual annotation. **97.9% automation rate** across stackmem's own real development history.
42
+ - **Semantic organization** — hybrid containment-trigram scoring deduplicates new memories against existing ones, links related memories bidirectionally, and resolves contradictions ("we switched from X to Y") automatically.
43
+ - **Temporal ranking** — an exponential decay score ranks memories by recency and access frequency, then a 2000-token budget decides what actually gets injected.
44
+ - **Delivery** — an MCP server, an 18-command CLI, and the Memory Vault web dashboard all read from the same store and deliver it back into every new session.
132
45
 
133
- ### cm context
46
+ ## Claude Code (automatic)
134
47
 
135
- ```
136
- $ cm context myapp "fix the module resolution error in the build"
137
- ## Project Context: myapp
138
- ### Task: fix the module resolution error in the build
48
+ `cm init` registers the stackmem MCP server in `~/.claude.json`. Memories load automatically at the start of every session — nothing to configure, nothing to remember to run.
139
49
 
140
- **Constraints**
141
- - Service role key must never be exposed to a client
50
+ ## Cursor and Windsurf (automatic)
142
51
 
143
- **Discoveries**
144
- - schema change: migrations/003_add_access_count.sql
52
+ `cm init` writes `.cursorrules` and `.windsurfrules` directly from your project's live memories, and the git hook keeps them current — `cm sync` regenerates and commits both files automatically after every push. You never have to remember to refresh them by hand.
145
53
 
146
- *(41/2000 tokens used)*
147
54
  ```
55
+ # stackmem — project memory (auto-updated)
56
+ ## Project: myapp
148
57
 
149
- Top 5 memories relevant to a task, ranked by relevance and decay, capped at 2000 tokens. Feed this to an agent instead of the whole project's memory.
58
+ ### Constraints
59
+ - required env vars: DATABASE_URL, API_KEY
150
60
 
151
- ### cm compress
61
+ ### Discoveries
62
+ - tech stack: express
152
63
 
153
- ```
154
- $ cm compress myapp
155
- Compressed 4 memories into 1 summary
156
- Compressed 3 memories into 1 summary
157
- Compression complete. 2 clusters compressed.
64
+ ---
65
+ *Last updated: 10/13/2026, 5:37:45 PM*
66
+ *Run `cm start` for full details with decay scores*
158
67
  ```
159
68
 
160
- Needs 20+ unresolved memories. Also runs automatically once a project crosses that count.
69
+ ## CLI commands (all 18)
161
70
 
162
- ### cm init
71
+ | Command | Description |
72
+ |---|---|
73
+ | `cm start [project]` | Load all unresolved memories, decay-ranked and budget-capped, grouped by type with linked memory ids. |
74
+ | `cm save [project] <type> <content>` | Save a new memory (`decision`, `constraint`, `discovery`, or `rejection`). Links to related memories automatically; prompts on contradiction unless `--force`. |
75
+ | `cm fix [project] <problem> <solution>` | Record a problem and its solution for future reference. |
76
+ | `cm analyze [project] <path>` | Build a Tree-Sitter AST index (files, functions, classes) for the codebase. |
77
+ | `cm search [--project <name>] <query>` | Search memories and past fixes for a project matching a query. |
78
+ | `cm resolve [project] <memory-id>` | Mark a memory as resolved. |
79
+ | `cm delete [project] <memory-id>` | Delete a memory and any links referencing it. |
80
+ | `cm inspect [project] <memory-id>` | Show a single memory's full detail: type, content, decay score, access count, linked memories, and related fixes. |
81
+ | `cm compress [project]` | Cluster related memories (needs 20+) and collapse clusters of 3+ into a summary memory. |
82
+ | `cm init <project> <path>` | Install the git hook, register the MCP server, seed memories from the project scan, and write `.gitignore`, `CLAUDE.md`, `.cursorrules`, and `.windsurfrules`. |
83
+ | `cm sync` | Regenerate `.cursorrules` and `.windsurfrules` from current memories and recent fixes. |
84
+ | `cm context [--project <name>] <task>` | Return the top 5 memories most relevant to a specific task, capped at 2000 tokens. |
85
+ | `cm session-end [project]` | Capture what happened in a session and extract memories, errors, and rejected approaches. |
86
+ | `cm doctor` | Check every integration point — backend, MCP registration, `.stackmem`, git hook, memory count — and report what's broken. |
87
+ | `cm undo [project]` | Delete the most recently saved unresolved memory. |
88
+ | `cm export [filename]` | Export all unresolved memories, fixes, and links to a JSON file. |
89
+ | `cm import [project] <filename>` | Import memories and fixes from a file produced by `cm export`. |
90
+ | `cm help` | Show the full help message. |
163
91
 
164
- ```
165
- $ cm init myapp .
166
- coding-memory hook installed for project myapp at .
167
- ```
92
+ ## The Memory Vault
168
93
 
169
- Installs a post-commit hook that calls `dist/cli.js save` after every commit with the commit message, plus whatever the diff turns up: removed imports, new env vars, new auth files, package.json changes, new config files, schema files, TODOs.
94
+ `stackmem-vault.vercel.app`
170
95
 
171
- ### cm help
96
+ Sign in with GitHub. View every project you track, each with its memory count and last activity. Four tabs per project: **Memories** (typed, with decay scores and resolve/delete actions), **Fixes** (problem/solution pairs), **Graph** (a D3.js force-directed view of your actual knowledge network — nodes are memories, edges are semantic links), and **Timeline** (every memory chronologically, including resolved ones). A global search bar queries memories and fixes across every project at once.
172
97
 
173
- ```
174
- $ cm help
175
- cm — coding memory CLI
98
+ ## How memory works
176
99
 
177
- cm start <project>
178
- Load all unresolved memories for a project, sorted by decay
179
- score and capped at a 2000 token context budget.
100
+ Memories are decisions, constraints, discoveries, and rejections, scoped to a project. Fixes are stored separately as a problem string and the solution that closed it, so the same error doesn't cost another 20 minutes next month.
180
101
 
181
- cm save <project> <type> <content> [--force]
182
- Save a new memory. Prompts before overwriting a contradiction
183
- unless --force is passed.
102
+ Every save checks new content against existing memories with a **hybrid score**: 0.7 × entity containment (shared terms over the size of the smaller set) + 0.3 × character-trigram Jaccard overlap. The trigram component catches lexical near-misses that containment alone can't — e.g. `"removed dependency: node:path"` vs `"removed dependency: node:url"`, which share identical entity sets but diverge in the actual package name. Above 0.85 with no negation word, it's a duplicate and gets skipped. With a negation word like "switched" or "no longer" and a score above 0.4, it's a contradiction.
184
103
 
185
- ...
186
- ```
187
-
188
- ## How it works
104
+ `cm save` stops and asks whether to keep the old memory or replace it, unless `--force` is passed. The MCP `save_memory` tool always replaces automatically, since nothing is watching stdin on that path.
189
105
 
190
- Memories are decisions, constraints, discoveries, and rejections, scoped to a project. Fixes are stored separately as a problem string and the solution that closed it, so the same tsc error doesn't cost another 20 minutes next month.
106
+ New memories are also compared against everything else and linked above a lower threshold of 0.15, using the same hybrid score. `cm start` and `cm context` show those links without any manual tagging.
191
107
 
192
- Every save checks new content against existing memories with a containment score: shared terms over the size of the smaller set. Above 0.85 with no negation word, it's a duplicate and gets skipped. With a negation word like "switched" or "no longer" and a score above 0.4, it's a contradiction.
108
+ Relevance decays over time: `score = (1 + ln(1 + accessCount)) * exp(-0.05 * daysSinceCreated)`. Frequently accessed memories decay slower, but nothing survives forever. The 0.05 constant works out to roughly a 14-day half life.
193
109
 
194
- cm save stops and asks whether to keep the old memory or replace it, unless `--force` is passed. The MCP `save_memory` tool always replaces automatically, since nothing is watching stdin on that path.
110
+ `cm start` and `cm context` cap output at 2000 tokens. They fill from the highest-ranked memory down until the next one would push past that limit.
195
111
 
196
- New memories are also compared against everything else and linked above a lower threshold of 0.15. `cm start` and `cm context` show those links without any manual tagging.
112
+ Past 20 unresolved memories, `cm compress` clusters related memories by hybrid score above 0.2 using union-find. Clusters of 3 or more collapse into a single summary memory.
197
113
 
198
- Relevance decays over time: `score = (1 + ln(1 + accessCount)) * exp(-0.05 * daysSinceCreated)`. Frequently accessed memories decay slower, but nothing survives forever. The 0.05 constant works out to roughly a 14-day half life.
114
+ ## Benchmark results
199
115
 
200
- `cm start` and `cm context` cap output at 2000 tokens. They fill from the highest-ranked memory down until the next one would push past that limit.
116
+ Measured against stackmem's own real production data — not synthetic fixtures.
201
117
 
202
- Past 20 unresolved memories, `cm compress` clusters related memories by containment score above 0.2 using union-find. Clusters of 3 or more collapse into a single summary memory.
118
+ | Metric | Result |
119
+ |---|---|
120
+ | Token reduction vs. full codebase dump | 99.4% (36,579 → 226 tokens) |
121
+ | Duplicate detection F1 | 0.974 (P=1.00, R=0.95) |
122
+ | Contradiction detection F1 | 0.947 (P=1.00, R=0.90) |
123
+ | Semantic linking SNR | 7.8x (linked: 0.69, random: 0.09) |
124
+ | Automation rate | 97.9% (47/48 memories auto-captured) |
203
125
 
204
126
  ## Research
205
127
 
@@ -210,3 +132,7 @@ Ideas taken from a few papers, not implementations of them.
210
132
  - A-MEM: Agentic Memory for LLM Agents (arXiv:2502.12110, NeurIPS 2025)
211
133
  - SWE-MeM: Learning Adaptive Memory Management for Long-Horizon Coding Agents (arXiv:2606.28434)
212
134
  - AtomMem: Learnable Dynamic Agentic Memory with Atomic Memory Operation (arXiv:2601.08323)
135
+
136
+ ## Paper
137
+
138
+ [stackmem: MCP, Tree-Sitter AST Graphs, Hybrid Containment-Trigram Scoring, and Temporal Decay for Persistent AI Coding Agent Memory](https://github.com/arushlagudu/coding-memory/blob/main/docs/paper.pdf)