lemma-mcp 0.8.8 → 0.10.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.
Files changed (113) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +94 -335
  3. package/dist/db/database.d.ts +12 -0
  4. package/dist/db/database.d.ts.map +1 -0
  5. package/dist/db/database.js +77 -0
  6. package/dist/db/database.js.map +1 -0
  7. package/dist/db/index.d.ts +6 -0
  8. package/dist/db/index.d.ts.map +1 -0
  9. package/dist/db/index.js +17 -0
  10. package/dist/db/index.js.map +1 -0
  11. package/dist/db/library-store.d.ts +117 -0
  12. package/dist/db/library-store.d.ts.map +1 -0
  13. package/dist/db/library-store.js +635 -0
  14. package/dist/db/library-store.js.map +1 -0
  15. package/dist/db/memory-store.d.ts +44 -0
  16. package/dist/db/memory-store.d.ts.map +1 -0
  17. package/dist/db/memory-store.js +414 -0
  18. package/dist/db/memory-store.js.map +1 -0
  19. package/dist/db/migration.d.ts +8 -0
  20. package/dist/db/migration.d.ts.map +1 -0
  21. package/dist/db/migration.js +243 -0
  22. package/dist/db/migration.js.map +1 -0
  23. package/dist/db/schema.d.ts +3 -0
  24. package/dist/db/schema.d.ts.map +1 -0
  25. package/dist/db/schema.js +231 -0
  26. package/dist/db/schema.js.map +1 -0
  27. package/dist/guides/core.d.ts +15 -0
  28. package/dist/guides/core.d.ts.map +1 -1
  29. package/dist/guides/core.js +438 -116
  30. package/dist/guides/core.js.map +1 -1
  31. package/dist/guides/index.d.ts +2 -1
  32. package/dist/guides/index.d.ts.map +1 -1
  33. package/dist/guides/index.js +2 -1
  34. package/dist/guides/index.js.map +1 -1
  35. package/dist/guides/seed.d.ts +7 -0
  36. package/dist/guides/seed.d.ts.map +1 -0
  37. package/dist/guides/seed.js +190 -0
  38. package/dist/guides/seed.js.map +1 -0
  39. package/dist/index.js +13 -5
  40. package/dist/index.js.map +1 -1
  41. package/dist/intelligence/conflict.d.ts +6 -0
  42. package/dist/intelligence/conflict.d.ts.map +1 -0
  43. package/dist/intelligence/conflict.js +149 -0
  44. package/dist/intelligence/conflict.js.map +1 -0
  45. package/dist/intelligence/index.d.ts +6 -0
  46. package/dist/intelligence/index.d.ts.map +1 -0
  47. package/dist/intelligence/index.js +5 -0
  48. package/dist/intelligence/index.js.map +1 -0
  49. package/dist/intelligence/proactive.d.ts +9 -0
  50. package/dist/intelligence/proactive.d.ts.map +1 -0
  51. package/dist/intelligence/proactive.js +265 -0
  52. package/dist/intelligence/proactive.js.map +1 -0
  53. package/dist/intelligence/semantic.d.ts +23 -0
  54. package/dist/intelligence/semantic.d.ts.map +1 -0
  55. package/dist/intelligence/semantic.js +152 -0
  56. package/dist/intelligence/semantic.js.map +1 -0
  57. package/dist/intelligence/session-analytics.d.ts +6 -0
  58. package/dist/intelligence/session-analytics.d.ts.map +1 -0
  59. package/dist/intelligence/session-analytics.js +162 -0
  60. package/dist/intelligence/session-analytics.js.map +1 -0
  61. package/dist/intelligence/types.d.ts +43 -0
  62. package/dist/intelligence/types.d.ts.map +1 -0
  63. package/dist/intelligence/types.js +2 -0
  64. package/dist/intelligence/types.js.map +1 -0
  65. package/dist/logger.js +1 -1
  66. package/dist/logger.js.map +1 -1
  67. package/dist/memory/config.d.ts.map +1 -1
  68. package/dist/memory/config.js +7 -1
  69. package/dist/memory/config.js.map +1 -1
  70. package/dist/memory/core.d.ts +31 -3
  71. package/dist/memory/core.d.ts.map +1 -1
  72. package/dist/memory/core.js +608 -105
  73. package/dist/memory/core.js.map +1 -1
  74. package/dist/memory/index.d.ts +1 -1
  75. package/dist/memory/index.d.ts.map +1 -1
  76. package/dist/memory/index.js +1 -1
  77. package/dist/memory/index.js.map +1 -1
  78. package/dist/memory/seed.d.ts.map +1 -1
  79. package/dist/memory/seed.js +39 -44
  80. package/dist/memory/seed.js.map +1 -1
  81. package/dist/server/agents-md.d.ts +7 -0
  82. package/dist/server/agents-md.d.ts.map +1 -0
  83. package/dist/server/agents-md.js +184 -0
  84. package/dist/server/agents-md.js.map +1 -0
  85. package/dist/server/handlers.d.ts +21 -0
  86. package/dist/server/handlers.d.ts.map +1 -1
  87. package/dist/server/handlers.js +661 -239
  88. package/dist/server/handlers.js.map +1 -1
  89. package/dist/server/index.d.ts +1 -3
  90. package/dist/server/index.d.ts.map +1 -1
  91. package/dist/server/index.js +133 -228
  92. package/dist/server/index.js.map +1 -1
  93. package/dist/server/system-prompt.d.ts +5 -2
  94. package/dist/server/system-prompt.d.ts.map +1 -1
  95. package/dist/server/system-prompt.js +186 -94
  96. package/dist/server/system-prompt.js.map +1 -1
  97. package/dist/server/tools.d.ts.map +1 -1
  98. package/dist/server/tools.js +84 -5
  99. package/dist/server/tools.js.map +1 -1
  100. package/dist/server/traffic-log.d.ts +5 -0
  101. package/dist/server/traffic-log.d.ts.map +1 -0
  102. package/dist/server/traffic-log.js +180 -0
  103. package/dist/server/traffic-log.js.map +1 -0
  104. package/dist/sessions/core.d.ts.map +1 -1
  105. package/dist/sessions/core.js +140 -49
  106. package/dist/sessions/core.js.map +1 -1
  107. package/dist/sessions/virtual.d.ts +11 -1
  108. package/dist/sessions/virtual.d.ts.map +1 -1
  109. package/dist/sessions/virtual.js +226 -4
  110. package/dist/sessions/virtual.js.map +1 -1
  111. package/dist/types.d.ts +5 -1
  112. package/dist/types.d.ts.map +1 -1
  113. package/package.json +65 -63
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Lemma Project Contributors
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.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Lemma Project Contributors
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 CHANGED
@@ -2,11 +2,11 @@
2
2
  <img src="assets/logo.png" width="200" alt="Lemma Logo">
3
3
  </p>
4
4
 
5
- # Lemma - Persistent Memory for LLMs via MCP
5
+ # Lemma Persistent Memory for LLMs via MCP
6
6
 
7
7
  [English](README.md) | [Türkçe](docs/README.tr.md)
8
8
 
9
- Lemma is an MCP server that gives LLMs persistent, cross-session memory. Memories are injected automatically into every session — no explicit tool call needed. Knowledge evolves through use: frequently accessed memories strengthen, unused ones fade, and patterns are promoted into reusable skills.
9
+ Lemma is an MCP server that gives LLMs persistent, cross-session memory. Memories are injected automatically into every session — no explicit tool call needed. Knowledge evolves through use: frequently accessed memories strengthen, unused ones fade, and patterns are promoted into reusable skills. An autonomous intelligence layer runs in the background — detecting conflicts, suggesting actions, and auto-linking related knowledge.
10
10
 
11
11
  ## Quick Start
12
12
 
@@ -14,7 +14,8 @@ Add Lemma to your MCP client configuration:
14
14
 
15
15
  **Claude Desktop (Windows):** `%APPDATA%\Claude\claude_desktop_config.json`
16
16
  **Claude Desktop (macOS):** `~/Library/Application Support/Claude/claude_desktop_config.json`
17
- **opencode:** `%APPDATA%\opencode\opencode.json`
17
+ **Claude Code (Linux):** `~/.claude.json` or `~/.claude/settings.json`
18
+ **opencode:** `~/.config/opencode/opencode.json` (Linux/macOS) or `%APPDATA%\opencode\opencode.json` (Windows)
18
19
 
19
20
  ```json
20
21
  {
@@ -29,121 +30,102 @@ Add Lemma to your MCP client configuration:
29
30
 
30
31
  > Using `@latest` ensures npx always fetches the newest version.
31
32
 
32
- **Requirements:** Node.js 18.0.0 or higher
33
+ **Requirements:** Node.js 20.0.0 or higher
33
34
 
34
- ## How It Works
35
-
36
- ### Universal Memory Injection
37
-
38
- Memories are injected into tool descriptions via `tools/list`. The LLM starts every session already knowing its most important memories — works on every MCP client.
39
-
40
- **3-layer architecture:**
41
- - Layer 1: Full content for top memories (token-budgeted)
42
- - Layer 2: Summary index for remaining memories
43
- - Layer 3: Active guides with learnings
35
+ ### CLI Usage
44
36
 
45
- ### Fragment Types
37
+ ```bash
38
+ lemma -lib # Library Mode: snapshot of your entire knowledge base
39
+ ```
46
40
 
47
- Every memory fragment has a type that classifies its nature:
41
+ Outputs a full analysis of all memories, guides, relations, stale fragments, distill candidates, and suggested actions. Useful for periodic maintenance and review.
48
42
 
49
- | Type | Use For | Example |
50
- |------|---------|---------|
51
- | `fact` | Technical info, API behavior, versions | "Node.js 22 has native fetch" |
52
- | `pattern` | Repeated solution, best practice | "React useEffect cleanup pattern" |
53
- | `lesson` | Learned from experience, debugging | "JSONL parse errors silently swallow broken lines" |
54
- | `warning` | Caution, gotcha, pitfall | "fs.writeFileSync blocks the event loop" |
55
- | `context` | Environment info, project setup | "This project uses Python 3.11 with py launcher" |
43
+ ## How It Works
56
44
 
57
- Default is `fact` if not specified.
45
+ Memories are injected into tool descriptions via `tools/list`. The LLM starts every session already knowing its most important memories — works on every MCP client.
58
46
 
59
- ### Memory ↔ Guide Pipeline
47
+ **3-layer injection:**
48
+ - Full content for top memories (token-budgeted)
49
+ - Summary index for remaining memories
50
+ - Active guides with learnings
60
51
 
61
- Knowledge flows through a two-way pipeline:
52
+ **Memory types:** `fact`, `pattern`, `lesson`, `warning`, `context`
62
53
 
63
- 1. **Memory** = WHAT you know facts, observations, technical details (`memory_add`)
64
- 2. **Guide** = HOW you work — accumulated experience, procedural skills (`guide_practice`, `guide_distill`)
54
+ **Knowledge pipeline:** Memory (what you know, `memory_add`) Pattern (`type: "pattern"`) → Guide (how you work, `guide_distill` → `guide_practice`)
65
55
 
66
- Connections are **bidirectional** and automatic:
67
- - `guide_distill` → links memory to guide AND guide to memory
68
- - `guide_practice` → session-read memories validate the guide
69
- - `memory_merge` → relations, guide links, and associations are inherited by the merged fragment
56
+ **AGENTS.md injection:** Lemma automatically injects a system prompt into your project's `AGENTS.md`, teaching the LLM how to use the memory system effectively. This ensures consistent behavior across all MCP clients.
70
57
 
71
- ### Response Hooks (Suggested Actions)
58
+ ## Autonomous Intelligence
72
59
 
73
- Tool responses include contextual `SUGGESTED ACTIONS` when meaningful connections are detected. For example:
60
+ Lemma runs intelligence in the background no manual triggering needed:
74
61
 
75
- - `memory_add` with topic overlap "Call `memory_relate` to link these fragments"
76
- - `memory_add` with type `pattern` "Call `guide_distill` to promote into a skill"
77
- - `memory_feedback` positive "Call `guide_distill` to convert into a reusable skill"
78
- - `session_end` with activity → Full review with relate + distill + practice suggestions
62
+ - **Conflict Detection:** Automatically checks new memories against existing knowledge for contradictions. Reports conflicts with suggestions to resolve.
63
+ - **Proactive Suggestions:** After adding memories or practicing guides, suggests actions like distilling patterns, merging duplicates, or refining low-performing guides.
64
+ - **Auto-linking:** Frequently co-read memories and topic-overlapping fragments are automatically connected with relations.
79
65
 
80
- Hooks only appear when there's meaningful context no noise in empty states.
66
+ Manual deep analysis is also available via dedicated tools.
81
67
 
82
- ### Learning System
68
+ ## Tools (24)
83
69
 
84
- Knowledge evolves through use with a biological memory model:
70
+ ### Memory (11)
85
71
 
86
- - **Shield**: Accessed items are protected from decay entirely
87
- - **Unused items** decay very slowly (0.002 per session)
88
- - **Negative feedback** reduces confidence by -0.02
89
- - **Associations**: Fragments used together build cross-references automatically
90
- - **No time-based decay**: Confidence only changes when the system is actively used
72
+ | Tool | Purpose |
73
+ |------|---------|
74
+ | `memory_read` | Read/search fragments. Summary mode or full detail by ID |
75
+ | `memory_add` | Save findings. Auto-redacts secrets, detects duplicates and conflicts |
76
+ | `memory_update` | Update fragment by ID |
77
+ | `memory_feedback` | Positive/negative feedback, adjusts confidence |
78
+ | `memory_forget` | Delete fragment |
79
+ | `memory_merge` | Merge fragments, inherit relations & guide links |
80
+ | `memory_relate` | Create typed links (`contradicts`, `supersedes`, `supports`, `related_to`) |
81
+ | `memory_stats` | Fragment counts, confidence, project breakdown |
82
+ | `memory_audit` | Integrity check for orphans, duplicates, anomalies |
83
+ | `memory_library` | Full knowledge base snapshot with analysis signals and suggestions |
91
84
 
92
- ### Memory Structure
85
+ ### Guides (8)
93
86
 
94
- | Field | Type | Description |
95
- |-------|------|-------------|
96
- | `id` | string | Unique identifier (`m` + 12 hex chars) |
97
- | `title` | string | Short title |
98
- | `fragment` | string | Synthesized memory text |
99
- | `type` | FragmentType | `fact`, `pattern`, `lesson`, `warning`, or `context` |
100
- | `project` | string | Project scope (`null` for global) |
101
- | `confidence` | float | Reliability 0.0-1.0 |
102
- | `source` | string | `"user"` or `"ai"` |
103
- | `relations` | MemoryRelation[] | Typed links to other fragments |
104
- | `related_guides` | string[] | Guide names this fragment informs |
105
- | `associatedWith` | string[] | IDs of co-accessed fragments |
106
- | `tags` | string[] | Context tags from usage |
107
- | `accessed` | int | Access count in current decay cycle |
87
+ | Tool | Purpose |
88
+ |------|---------|
89
+ | `guide_get` | Get guides sorted by usage, filter by category or task |
90
+ | `guide_practice` | Record guide usage. Auto-creates guide if missing |
91
+ | `guide_create` | Create guide with detailed manual |
92
+ | `guide_distill` | Transform memory guide learning (bidirectional link) |
93
+ | `guide_update` | Update guide properties, anti-patterns, pitfalls |
94
+ | `guide_forget` | Remove guide |
95
+ | `guide_merge` | Merge guides, inherit source memories |
108
96
 
109
- ### Guide Structure
97
+ ### Sessions (3)
110
98
 
111
- | Field | Type | Description |
112
- |-------|------|-------------|
113
- | `guide` | string | Guide name |
114
- | `category` | string | Category (e.g., `web-frontend`, `dev-tool`) |
115
- | `description` | string | Full manual/protocols |
116
- | `source_memories` | string[] | Memory IDs that spawned this guide |
117
- | `validated_by` | string[] | Memory IDs that validated this guide in practice |
118
- | `usage_count` | int | Times practiced |
119
- | `success_count` | int | Successful uses |
120
- | `failure_count` | int | Failed uses |
121
- | `learnings` | string[] | Accumulated learnings |
122
- | `contexts` | string[] | Contexts where used |
99
+ | Tool | Purpose |
100
+ |------|---------|
101
+ | `session_start` | Start traced session, pre-loads relevant context |
102
+ | `session_end` | End session with review, auto-linking, and suggestions |
103
+ | `session_stats` | Virtual session statistics |
123
104
 
124
- ### Virtual Sessions
105
+ ### Intelligence (4)
125
106
 
126
- Tool calls are automatically correlated into virtual sessions:
127
- - Auto-starts on first tool call, auto-finalizes after 30 min inactivity
128
- - Tracks technologies seen, guides used, memories created/accessed
129
- - No explicit `session_start`/`session_end` required
107
+ | Tool | Purpose |
108
+ |------|---------|
109
+ | `conflict_scan` | Scan all memories for contradictions |
110
+ | `proactive_analysis` | Full knowledge base analysis: stale, orphan, distill, deprecated |
111
+ | `project_analytics` | Cross-session project health, growth rate, skill coverage |
112
+ | `semantic_search` | TF-IDF similarity search across memories |
130
113
 
131
- ### Configuration
114
+ ## Configuration
132
115
 
133
116
  Optional config at `~/.lemma/config.json`:
134
117
 
135
118
  ```json
136
119
  {
137
120
  "token_budget": {
138
- "full_content": 3000,
121
+ "full_content": 5000,
139
122
  "summary_index": 1000,
140
123
  "guides_detail": 1000
141
124
  },
142
125
  "injection": {
143
126
  "max_full_content_fragments": 15,
144
127
  "max_summary_fragments": 30,
145
- "max_guides": 20,
146
- "max_guide_detail": 3
128
+ "max_guides": 20
147
129
  },
148
130
  "virtual_session": {
149
131
  "timeout_minutes": 30
@@ -151,274 +133,51 @@ Optional config at `~/.lemma/config.json`:
151
133
  }
152
134
  ```
153
135
 
154
- ### File Locations
136
+ ## File Locations
155
137
 
156
138
  | OS | Path |
157
139
  |---|---|
158
140
  | **Windows** | `C:\Users\{username}\.lemma\` |
159
- | **macOS** | `/Users/{username}/.lemma/` |
160
- | **Linux** | `/home/{username}/.lemma/` |
161
-
162
- Files: `memory.jsonl`, `guides.jsonl`, `config.json`, `sessions/`, `logs/`, `.bak` backups
163
-
164
- ---
165
-
166
- ## Available Tools (21)
167
-
168
- ### Memory Tools (11)
169
-
170
- #### `memory_read`
171
-
172
- Read memory fragments. SUMMARY MODE shows title + description; use `id` for full detail.
173
-
174
- **Parameters:**
175
- - `project` (string, optional): Project name to filter
176
- - `query` (string, optional): Semantic search keyword
177
- - `id` (string, optional): Get full detail for a specific fragment
178
- - `ids` (string[], optional): Get full details for multiple fragments at once
179
- - `context` (string, optional): Tag this access with a context (e.g., "debugging")
180
- - `all` (boolean, optional): Show fragments from all projects (default: false)
181
- - `minConfidence` (number, optional): Minimum confidence threshold (0-1)
182
- - `afterDate` (string, optional): ISO date — only fragments created on or after
183
- - `beforeDate` (string, optional): ISO date — only fragments created on or before
184
-
185
- #### `memory_add`
186
-
187
- **MANDATORY:** Call AFTER completing analysis to save findings. Automatically redacts secrets unless `confirm: true`.
188
-
189
- **Parameters:**
190
- - `fragment` (string, required): Memory text. Use structured markdown: `## [Topic]\n[Context]\n- [Key points]`
191
- - `title` (string, optional): Short title (max 80 chars)
192
- - `description` (string, optional): Short summary (max 150 chars)
193
- - `project` (string, optional): Project scope (null = global)
194
- - `source` (string, optional): "user" or "ai", default "ai"
195
- - `confirm` (boolean, optional): Store as-is even if secrets detected (default: false)
196
- - `type` (string, optional): Fragment type — `fact`, `pattern`, `lesson`, `warning`, or `context` (default: `fact`)
197
-
198
- #### `memory_update`
199
-
200
- Update an existing fragment by ID.
201
-
202
- **Parameters:**
203
- - `id` (string, required): Fragment ID
204
- - `title` (string, optional): New title
205
- - `fragment` (string, optional): New text
206
- - `confidence` (number, optional): New confidence 0-1
207
-
208
- #### `memory_feedback`
209
-
210
- Provide feedback on a memory fragment after use. Positive boosts confidence; negative reduces by -0.02.
211
-
212
- **Parameters:**
213
- - `id` (string, required): Fragment ID
214
- - `useful` (boolean, required): `true` if helpful, `false` if not
215
-
216
- #### `memory_forget`
217
-
218
- Remove a memory fragment by ID.
219
-
220
- **Parameters:**
221
- - `id` (string, required): Fragment ID
222
-
223
- #### `memory_merge`
224
-
225
- Merge multiple fragments into one. Relations, guide links, and associations are inherited by the merged fragment.
226
-
227
- **Parameters:**
228
- - `ids` (string[], required): Fragment IDs to merge
229
- - `title` (string, required): Title for merged fragment
230
- - `fragment` (string, required): Merged content
231
- - `project` (string, optional): Project scope
232
-
233
- #### `memory_relate`
234
-
235
- Create a typed relation between two memory fragments. Bidirectional — reverse relation auto-created.
236
-
237
- **Parameters:**
238
- - `sourceId` (string, required): Source fragment ID
239
- - `targetId` (string, required): Target fragment ID
240
- - `type` (string, required): `contradicts`, `supersedes`, `supports`, or `related_to`
241
- - `note` (string, optional): Note explaining the relation
242
-
243
- #### `memory_stats`
244
-
245
- Get memory store statistics.
246
-
247
- **Parameters:**
248
- - `project` (string, optional): Filter by project
249
-
250
- #### `memory_audit`
251
-
252
- Audit memory store for integrity issues.
253
-
254
- ### Guide Tools (8)
255
-
256
- #### `guide_get`
257
-
258
- Get guides with usage statistics, sorted by usage count.
259
-
260
- **Parameters:**
261
- - `category` (string, optional): Filter by category
262
- - `guide` (string, optional): Get detail for specific guide
263
- - `task` (string, optional): Task description to get relevant suggestions
141
+ | **macOS/Linux** | `~/.lemma/` |
264
142
 
265
- #### `guide_practice`
143
+ Files: `lemma.db` (SQLite), `config.json`, `sessions/`, `logs/`
266
144
 
267
- **MANDATORY:** Record guide usage during work.
145
+ ## Search
268
146
 
269
- **Parameters:**
270
- - `guide` (string, required): Guide name
271
- - `category` (string, required): Category
272
- - `description` (string, optional): Detailed manual/protocols
273
- - `contexts` (string[], required): Contexts where used
274
- - `learnings` (string[], required): New learnings discovered
275
- - `outcome` (string, optional): "success" or "failure"
147
+ Lemma uses **SQLite FTS5** full-text search for memory lookup, dedup, and topic overlap detection.
276
148
 
277
- #### `guide_create`
149
+ **Architecture:**
150
+ - `searchAndSortFragments()` — FTS5 full-text search, fallback to in-memory ranking
151
+ - `findSimilarFragment()` — FTS5 BM25-based dedup with keyword overlap fallback
152
+ - `findTopicOverlaps()` — FTS5 search + word overlap scoring for related fragment detection
278
153
 
279
- Create a guide with a detailed manual.
154
+ ## Data Storage
280
155
 
281
- **Parameters:**
282
- - `guide` (string, required): Guide name
283
- - `category` (string, required): Category
284
- - `description` (string, required): Full manual/protocols
285
- - `contexts` (string[], optional): Initial contexts
286
- - `learnings` (string[], optional): Initial learnings
156
+ All data is stored in a single SQLite database (`~/.lemma/lemma.db`):
287
157
 
288
- #### `guide_distill`
158
+ | Table | Purpose |
159
+ |-------|---------|
160
+ | `memories` | Memory fragments (FTS5 + metadata) |
161
+ | `guides` | Procedural knowledge with learnings |
162
+ | `sessions` | Session tracking and outcomes |
163
+ | `relations` | Typed links between memories |
164
+ | `guide_learnings` | Per-guide accumulated learnings |
165
+ | `guide_memory_links` | Bidirectional guide ↔ memory links |
289
166
 
290
- Transform a memory fragment into a guide's learning. Creates bidirectional link (memory ↔ guide).
167
+ Legacy JSONL files are automatically migrated on first run.
291
168
 
292
- **Parameters:**
293
- - `memory_id` (string, required): Memory fragment ID
294
- - `guide` (string, required): Target guide name
295
- - `category` (string, optional): Category (required if creating new guide)
296
-
297
- #### `guide_update`
298
-
299
- Update an existing guide's properties.
300
-
301
- **Parameters:**
302
- - `guide` (string, required): Current guide name
303
- - `new_name` (string, optional): New name
304
- - `category` (string, optional): New category
305
- - `description` (string, optional): New description/manual
306
- - `add_anti_patterns` (string[], optional): Add anti-patterns
307
- - `add_pitfalls` (string[], optional): Add known pitfalls
308
- - `superseded_by` (string, optional): Mark as superseded
309
- - `deprecated` (boolean, optional): Mark as deprecated
310
-
311
- #### `guide_forget`
312
-
313
- Remove a guide.
314
-
315
- **Parameters:**
316
- - `guide` (string, required): Guide name
317
-
318
- #### `guide_merge`
319
-
320
- Merge multiple guides into one. Source memories and validations are inherited.
321
-
322
- **Parameters:**
323
- - `guides` (string[], required): Guide names to merge
324
- - `guide` (string, required): Name for merged guide
325
- - `category` (string, required): Category
326
- - `description` (string, optional): Merged description
327
- - `contexts` (string[], optional): Merged contexts
328
- - `learnings` (string[], optional): Merged learnings
329
-
330
- ### Session Tools (2)
331
-
332
- #### `session_start`
333
-
334
- Start a traced work session. Pre-loads relevant guides and memories.
335
-
336
- **Parameters:**
337
- - `task_type` (string, required): "debugging", "implementation", "refactoring", "testing", "research", "documentation", "optimization", or "other"
338
- - `technologies` (string[], optional): Technologies involved
339
- - `initial_approach` (string, optional): Initial plan
340
-
341
- #### `session_end`
342
-
343
- End the current session. Shows SESSION REVIEW with activity summary and suggestions.
344
-
345
- **Parameters:**
346
- - `outcome` (string, required): "success", "partial", "failure", or "abandoned"
347
- - `final_approach` (string, optional): What approach worked
348
- - `lessons` (string[], optional): What was learned
349
-
350
- #### `session_stats`
351
-
352
- Get virtual session statistics.
353
-
354
- **Parameters:**
355
- - `count` (number, optional): Number of recent sessions (default 10)
356
-
357
- ---
358
-
359
- ## Manual Installation
360
-
361
- ```bash
362
- git clone https://github.com/xenitV1/lemma
363
- cd Lemma
364
- npm install
365
- ```
366
-
367
- ```json
368
- {
369
- "mcpServers": {
370
- "lemma": {
371
- "command": "node",
372
- "args": ["C:\\path\\to\\Lemma\\dist\\index.js"]
373
- }
374
- }
375
- }
376
- ```
377
-
378
- ## Development
379
-
380
- ```bash
381
- npm test # 481 tests
382
- npm run typecheck # TypeScript type checking
383
- npm run build # Compile to dist/
384
- ```
169
+ ## Security
385
170
 
386
- ### Project Structure
171
+ All data is stored locally in `~/.lemma/`. Nothing is sent to external servers. Secrets are automatically redacted from memory fragments (17 regex patterns for API keys, tokens, connection strings).
387
172
 
388
- ```
389
- Lemma/
390
- ├── src/
391
- │ ├── index.ts # MCP server entry point
392
- │ ├── types.ts # Shared TypeScript interfaces (MemoryFragment, Guide, FragmentType...)
393
- │ ├── memory/
394
- │ │ ├── core.ts # Core memory logic, decay, search, dedup, relations, associations
395
- │ │ ├── config.ts # User configuration loader
396
- │ │ ├── seed.ts # Built-in seed knowledge fragments
397
- │ │ └── privacy.ts # Secret scanning and redaction
398
- │ ├── guides/
399
- │ │ ├── core.ts # Core guides logic, fuzzy dedup, source_memories, validated_by
400
- │ │ └── task-map.ts # Task-to-guide mapping
401
- │ ├── server/
402
- │ │ ├── index.ts # Server setup, injection, notifications
403
- │ │ ├── handlers.ts # Tool handlers (21 tools) + response hooks
404
- │ │ ├── tools.ts # Tool definitions
405
- │ │ ├── hooks.ts # Hook system & prompt modifiers
406
- │ │ └── system-prompt.ts # Dynamic system prompt
407
- │ └── sessions/
408
- │ ├── core.ts # Session lifecycle
409
- │ └── virtual.ts # Virtual session tracking
410
- ├── tests/ # 36 test files, 481 tests
411
- ├── docs/ # Research papers and references
412
- ├── package.json
413
- ├── tsconfig.json
414
- ├── CHANGELOG.md
415
- └── README.md
416
- ```
417
-
418
- ## Security
173
+ ## Documentation
419
174
 
420
- All data is stored locally in `~/.lemma/`. Nothing is sent to external servers. Secrets are automatically redacted from memory fragments.
175
+ - [Development Guide](docs/development/DEVELOPMENT.md) Architecture, project structure, testing
176
+ - [Handlers Refactor](docs/development/HANDLERS-REFACTOR.md) — Targeted SQL migration plan
177
+ - [Roadmap](docs/development/ROADMAP.md) — v0.9, v0.10, v1.0 plans
178
+ - [Research](docs/research/README.md) — Academic papers that influenced Lemma's design
179
+ - [Changelog](CHANGELOG.md) — Version history
421
180
 
422
181
  ## License
423
182
 
424
- MIT License
183
+ MIT
@@ -0,0 +1,12 @@
1
+ import Database from "better-sqlite3";
2
+ export declare class LemmaDB {
3
+ readonly db: Database.Database;
4
+ private stmtCache;
5
+ constructor(dbPath?: string);
6
+ prepareCached(sql: string): Database.Statement;
7
+ close(): void;
8
+ }
9
+ export declare function setDataDir(dir: string): void;
10
+ export declare function getDb(dbPath?: string): LemmaDB;
11
+ export declare function closeDb(): void;
12
+ //# sourceMappingURL=database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAGA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAOtC,qBAAa,OAAO;IAClB,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC;IAC/B,OAAO,CAAC,SAAS,CAA8C;gBAEnD,MAAM,GAAE,MAAwB;IAoB5C,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAC,SAAS;IAS9C,KAAK,IAAI,IAAI;CAKd;AAMD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAO5C;AAED,wBAAgB,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAW9C;AAED,wBAAgB,OAAO,IAAI,IAAI,CAM9B"}
@@ -0,0 +1,77 @@
1
+ import path from "path";
2
+ import os from "os";
3
+ import fs from "fs";
4
+ import Database from "better-sqlite3";
5
+ import * as sqliteVec from "sqlite-vec";
6
+ import { logger } from "../logger.js";
7
+ import { runMigrations } from "./migration.js";
8
+ const DEFAULT_DB_PATH = path.join(os.homedir(), ".lemma", "lemma.db");
9
+ export class LemmaDB {
10
+ db;
11
+ stmtCache = new Map();
12
+ constructor(dbPath = DEFAULT_DB_PATH) {
13
+ const dir = path.dirname(dbPath);
14
+ if (!fs.existsSync(dir)) {
15
+ fs.mkdirSync(dir, { recursive: true });
16
+ }
17
+ this.db = new Database(dbPath);
18
+ sqliteVec.load(this.db);
19
+ this.db.pragma("journal_mode = WAL");
20
+ this.db.pragma("synchronous = NORMAL");
21
+ this.db.pragma("foreign_keys = ON");
22
+ this.db.pragma("busy_timeout = 5000");
23
+ this.db.pragma("cache_size = -64000");
24
+ this.db.pragma("temp_store = MEMORY");
25
+ logger.info("Database opened", { path: dbPath });
26
+ }
27
+ prepareCached(sql) {
28
+ let stmt = this.stmtCache.get(sql);
29
+ if (!stmt) {
30
+ stmt = this.db.prepare(sql);
31
+ this.stmtCache.set(sql, stmt);
32
+ }
33
+ return stmt;
34
+ }
35
+ close() {
36
+ this.stmtCache.clear();
37
+ this.db.close();
38
+ logger.info("Database closed");
39
+ }
40
+ }
41
+ let _instance = null;
42
+ let _currentPath = null;
43
+ let _dataDir = null;
44
+ export function setDataDir(dir) {
45
+ _dataDir = dir;
46
+ if (_instance) {
47
+ try {
48
+ _instance.close();
49
+ }
50
+ catch { }
51
+ _instance = null;
52
+ _currentPath = null;
53
+ }
54
+ }
55
+ export function getDb(dbPath) {
56
+ const resolvedPath = dbPath ?? (_dataDir ? path.join(_dataDir, "lemma.db") : DEFAULT_DB_PATH);
57
+ if (!_instance || _currentPath !== resolvedPath) {
58
+ if (_instance) {
59
+ try {
60
+ _instance.close();
61
+ }
62
+ catch { }
63
+ }
64
+ _instance = new LemmaDB(resolvedPath);
65
+ _currentPath = resolvedPath;
66
+ runMigrations(_instance);
67
+ }
68
+ return _instance;
69
+ }
70
+ export function closeDb() {
71
+ if (_instance) {
72
+ _instance.close();
73
+ _instance = null;
74
+ _currentPath = null;
75
+ }
76
+ }
77
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { getDb, closeDb, setDataDir, LemmaDB } from "./database.js";
2
+ export { SCHEMA_V1, MIGRATIONS } from "./schema.js";
3
+ export { runMigrations, migrateFromJsonl } from "./migration.js";
4
+ export { addMemory, getMemoryById, updateMemory, deleteMemory, searchMemories, addRelation, getRelations, boostConfidence, decayMemories, getMemoryStats, mergeMemories } from "./memory-store.js";
5
+ export declare function initDatabase(dbPath?: string): void;
6
+ //# sourceMappingURL=index.d.ts.map