claude-memory-agent 2.0.1 → 2.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.
Files changed (97) hide show
  1. package/README.md +206 -206
  2. package/agent_card.py +186 -0
  3. package/bin/cli.js +327 -185
  4. package/bin/lib/banner.js +39 -0
  5. package/bin/lib/environment.js +166 -0
  6. package/bin/lib/installer.js +291 -0
  7. package/bin/lib/models.js +95 -0
  8. package/bin/lib/steps/advanced.js +101 -0
  9. package/bin/lib/steps/confirm.js +87 -0
  10. package/bin/lib/steps/model.js +57 -0
  11. package/bin/lib/steps/provider.js +65 -0
  12. package/bin/lib/steps/scope.js +59 -0
  13. package/bin/lib/steps/server.js +74 -0
  14. package/bin/lib/ui.js +75 -0
  15. package/bin/onboarding.js +164 -0
  16. package/bin/postinstall.js +35 -270
  17. package/config.py +103 -4
  18. package/dashboard.html +4902 -2689
  19. package/hooks/extract_memories.py +439 -0
  20. package/hooks/grounding-hook.py +422 -348
  21. package/hooks/pre_compact_hook.py +76 -0
  22. package/hooks/session_end.py +293 -192
  23. package/hooks/session_end_hook.py +149 -0
  24. package/hooks/session_start.py +227 -227
  25. package/hooks/stop_hook.py +372 -0
  26. package/install.py +972 -902
  27. package/main.py +5240 -2859
  28. package/mcp_server.py +451 -0
  29. package/package.json +58 -47
  30. package/requirements.txt +12 -8
  31. package/services/__init__.py +50 -50
  32. package/services/adaptive_ranker.py +272 -0
  33. package/services/agent_catalog.json +153 -0
  34. package/services/agent_registry.py +245 -730
  35. package/services/claude_md_sync.py +320 -4
  36. package/services/consolidation.py +417 -0
  37. package/services/curator.py +1606 -0
  38. package/services/database.py +4118 -2485
  39. package/services/embedding_pipeline.py +262 -0
  40. package/services/embeddings.py +493 -85
  41. package/services/memory_decay.py +408 -0
  42. package/services/native_memory_paths.py +86 -0
  43. package/services/native_memory_sync.py +496 -0
  44. package/services/response_manager.py +183 -0
  45. package/services/terminal_ui.py +199 -0
  46. package/services/tier_manager.py +235 -0
  47. package/services/websocket.py +26 -6
  48. package/skills/__init__.py +21 -1
  49. package/skills/confidence_tracker.py +441 -0
  50. package/skills/context.py +675 -0
  51. package/skills/curator.py +348 -0
  52. package/skills/search.py +444 -213
  53. package/skills/session_review.py +605 -0
  54. package/skills/store.py +484 -179
  55. package/terminal_dashboard.py +474 -0
  56. package/update_system.py +829 -817
  57. package/hooks/__pycache__/auto-detect-response.cpython-312.pyc +0 -0
  58. package/hooks/__pycache__/auto_capture.cpython-312.pyc +0 -0
  59. package/hooks/__pycache__/session_end.cpython-312.pyc +0 -0
  60. package/hooks/__pycache__/session_start.cpython-312.pyc +0 -0
  61. package/services/__pycache__/__init__.cpython-312.pyc +0 -0
  62. package/services/__pycache__/agent_registry.cpython-312.pyc +0 -0
  63. package/services/__pycache__/auth.cpython-312.pyc +0 -0
  64. package/services/__pycache__/auto_inject.cpython-312.pyc +0 -0
  65. package/services/__pycache__/claude_md_sync.cpython-312.pyc +0 -0
  66. package/services/__pycache__/cleanup.cpython-312.pyc +0 -0
  67. package/services/__pycache__/compaction_flush.cpython-312.pyc +0 -0
  68. package/services/__pycache__/confidence.cpython-312.pyc +0 -0
  69. package/services/__pycache__/daily_log.cpython-312.pyc +0 -0
  70. package/services/__pycache__/database.cpython-312.pyc +0 -0
  71. package/services/__pycache__/embeddings.cpython-312.pyc +0 -0
  72. package/services/__pycache__/insights.cpython-312.pyc +0 -0
  73. package/services/__pycache__/llm_analyzer.cpython-312.pyc +0 -0
  74. package/services/__pycache__/memory_md_sync.cpython-312.pyc +0 -0
  75. package/services/__pycache__/retry_queue.cpython-312.pyc +0 -0
  76. package/services/__pycache__/timeline.cpython-312.pyc +0 -0
  77. package/services/__pycache__/vector_index.cpython-312.pyc +0 -0
  78. package/services/__pycache__/websocket.cpython-312.pyc +0 -0
  79. package/skills/__pycache__/__init__.cpython-312.pyc +0 -0
  80. package/skills/__pycache__/admin.cpython-312.pyc +0 -0
  81. package/skills/__pycache__/checkpoint.cpython-312.pyc +0 -0
  82. package/skills/__pycache__/claude_md.cpython-312.pyc +0 -0
  83. package/skills/__pycache__/cleanup.cpython-312.pyc +0 -0
  84. package/skills/__pycache__/grounding.cpython-312.pyc +0 -0
  85. package/skills/__pycache__/insights.cpython-312.pyc +0 -0
  86. package/skills/__pycache__/natural_language.cpython-312.pyc +0 -0
  87. package/skills/__pycache__/retrieve.cpython-312.pyc +0 -0
  88. package/skills/__pycache__/search.cpython-312.pyc +0 -0
  89. package/skills/__pycache__/state.cpython-312.pyc +0 -0
  90. package/skills/__pycache__/store.cpython-312.pyc +0 -0
  91. package/skills/__pycache__/summarize.cpython-312.pyc +0 -0
  92. package/skills/__pycache__/timeline.cpython-312.pyc +0 -0
  93. package/skills/__pycache__/verification.cpython-312.pyc +0 -0
  94. package/test_automation.py +0 -221
  95. package/test_complete.py +0 -338
  96. package/test_full.py +0 -322
  97. package/verify_db.py +0 -134
package/test_full.py DELETED
@@ -1,322 +0,0 @@
1
- """Complete test suite for all memory system features."""
2
- import asyncio
3
- import sys
4
- import os
5
- sys.path.insert(0, '.')
6
-
7
- async def test_all():
8
- print('=' * 70)
9
- print('COMPLETE MEMORY SYSTEM TEST SUITE')
10
- print('=' * 70)
11
-
12
- results = []
13
-
14
- # ===== ORIGINAL 12 FEATURES =====
15
- print('\n' + '-' * 70)
16
- print('SECTION A: ORIGINAL 12 FEATURES')
17
- print('-' * 70)
18
-
19
- # [1] Database with migrations
20
- print('\n[A1] Database & Migrations...')
21
- passed = 0
22
- try:
23
- from services.database import DatabaseService
24
- db = DatabaseService()
25
- await db.connect()
26
- await db.initialize_schema()
27
-
28
- # Check key tables exist
29
- cursor = db.conn.cursor()
30
- cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
31
- tables = [r[0] for r in cursor.fetchall()]
32
-
33
- required = ['memories', 'patterns', 'projects', 'anchors', 'timeline']
34
- for t in required:
35
- if t in tables:
36
- passed += 1
37
-
38
- await db.close()
39
- except Exception as e:
40
- print(f' ERROR: {e}')
41
-
42
- results.append(('A1. Database & Migrations', passed, len(required)))
43
- print(f' {passed}/{len(required)} tables verified')
44
-
45
- # [2] Embeddings Service
46
- print('\n[A2] Embeddings Service...')
47
- passed = 0
48
- try:
49
- from services.embeddings import EmbeddingsService
50
- passed += 1 # Import works
51
- except Exception as e:
52
- print(f' ERROR: {e}')
53
- results.append(('A2. Embeddings Service', passed, 1))
54
- print(f' {passed}/1 import verified')
55
-
56
- # [3] Session Management
57
- print('\n[A3] Session Management...')
58
- passed = 0
59
- try:
60
- from skills.session import create_session, get_active_session, end_session
61
- passed += 3
62
- except Exception as e:
63
- print(f' ERROR: {e}')
64
- results.append(('A3. Session Management', passed, 3))
65
- print(f' {passed}/3 functions verified')
66
-
67
- # [4] Timeline Service
68
- print('\n[A4] Timeline Service...')
69
- passed = 0
70
- try:
71
- from skills.timeline import log_event, get_recent_events, get_session_timeline
72
- passed += 3
73
- except Exception as e:
74
- print(f' ERROR: {e}')
75
- results.append(('A4. Timeline Service', passed, 3))
76
- print(f' {passed}/3 functions verified')
77
-
78
- # [5] Grounding System (Anchors)
79
- print('\n[A5] Grounding System...')
80
- passed = 0
81
- try:
82
- from services.grounding import GroundingService
83
- passed += 1
84
- except Exception as e:
85
- print(f' ERROR: {e}')
86
- results.append(('A5. Grounding System', passed, 1))
87
- print(f' {passed}/1 service verified')
88
-
89
- # [6] Insight Aggregation
90
- print('\n[A6] Insight Aggregation...')
91
- passed = 0
92
- try:
93
- from services.insight_aggregator import InsightAggregator
94
- passed += 1
95
- except Exception as e:
96
- print(f' ERROR: {e}')
97
- results.append(('A6. Insight Aggregation', passed, 1))
98
- print(f' {passed}/1 service verified')
99
-
100
- # [7] Auto-Conflict Detection
101
- print('\n[A7] Auto-Conflict Detection...')
102
- passed = 0
103
- try:
104
- from services.grounding import GroundingService
105
- # Check conflict table exists
106
- db = DatabaseService()
107
- await db.connect()
108
- cursor = db.conn.cursor()
109
- cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='anchor_conflicts'")
110
- if cursor.fetchone():
111
- passed += 1
112
- await db.close()
113
- except Exception as e:
114
- print(f' ERROR: {e}')
115
- results.append(('A7. Conflict Detection', passed, 1))
116
- print(f' {passed}/1 table verified')
117
-
118
- # [8] Memory Cleanup
119
- print('\n[A8] Memory Cleanup Service...')
120
- passed = 0
121
- try:
122
- from services.cleanup import CleanupService
123
- passed += 1
124
- except Exception as e:
125
- print(f' ERROR: {e}')
126
- results.append(('A8. Memory Cleanup', passed, 1))
127
- print(f' {passed}/1 service verified')
128
-
129
- # [9] Auth & Queue
130
- print('\n[A9] Auth & Queue Services...')
131
- passed = 0
132
- try:
133
- from services.auth import AuthService
134
- from services.queue import MemoryQueue
135
- passed += 2
136
- except Exception as e:
137
- print(f' ERROR: {e}')
138
- results.append(('A9. Auth & Queue', passed, 2))
139
- print(f' {passed}/2 services verified')
140
-
141
- # [10] Dashboard
142
- print('\n[A10] Dashboard...')
143
- passed = 0
144
- if os.path.exists('templates/dashboard.html'):
145
- passed += 1
146
- results.append(('A10. Dashboard', passed, 1))
147
- print(f' {passed}/1 file verified')
148
-
149
- # [11] Embedding Model Switching
150
- print('\n[A11] Embedding Model Switching...')
151
- passed = 0
152
- try:
153
- from skills.admin import get_embedding_status, switch_embedding_model
154
- passed += 2
155
- except Exception as e:
156
- print(f' ERROR: {e}')
157
- results.append(('A11. Model Switching', passed, 2))
158
- print(f' {passed}/2 functions verified')
159
-
160
- # [12] WebSocket Updates
161
- print('\n[A12] WebSocket Updates...')
162
- passed = 0
163
- try:
164
- from services.websocket import WebSocketManager, broadcast_event
165
- passed += 2
166
- except Exception as e:
167
- print(f' ERROR: {e}')
168
- results.append(('A12. WebSocket', passed, 2))
169
- print(f' {passed}/2 imports verified')
170
-
171
- # ===== 6 AUTOMATION FEATURES =====
172
- print('\n' + '-' * 70)
173
- print('SECTION B: AUTOMATION FEATURES')
174
- print('-' * 70)
175
-
176
- # [B1] Auto-Capture Hook
177
- print('\n[B1] Auto-Capture Hook...')
178
- passed = 0
179
- if os.path.exists('hooks/auto_capture.py'):
180
- passed += 1
181
- results.append(('B1. Auto-Capture Hook', passed, 1))
182
- print(f' {passed}/1 file verified')
183
-
184
- # [B2] Session Start/End Hooks
185
- print('\n[B2] Session Start/End Hooks...')
186
- passed = 0
187
- if os.path.exists('hooks/session_start.py'):
188
- passed += 1
189
- if os.path.exists('hooks/session_end.py'):
190
- passed += 1
191
- results.append(('B2. Session Hooks', passed, 2))
192
- print(f' {passed}/2 files verified')
193
-
194
- # [B3] Auto-Injector
195
- print('\n[B3] Auto-Injector Service...')
196
- passed = 0
197
- try:
198
- from services.auto_inject import AutoInjector, get_auto_injector
199
- passed += 2
200
- except Exception as e:
201
- print(f' ERROR: {e}')
202
- results.append(('B3. Auto-Injector', passed, 2))
203
- print(f' {passed}/2 imports verified')
204
-
205
- # [B4] Natural Language Interface
206
- print('\n[B4] Natural Language Interface...')
207
- passed = 0
208
- try:
209
- from skills.natural_language import parse_intent, process_natural_command
210
- # Quick test
211
- intent, _ = parse_intent('remember this: test')
212
- if intent == 'store':
213
- passed += 1
214
- intent, _ = parse_intent('show me past errors')
215
- if intent == 'list_errors':
216
- passed += 1
217
- except Exception as e:
218
- print(f' ERROR: {e}')
219
- results.append(('B4. Natural Language', passed, 2))
220
- print(f' {passed}/2 patterns verified')
221
-
222
- # [B5] CLAUDE.md Sync
223
- print('\n[B5] CLAUDE.md Sync...')
224
- passed = 0
225
- try:
226
- from services.claude_md_sync import ClaudeMdSync, get_claude_md_sync
227
- passed += 2
228
- except Exception as e:
229
- print(f' ERROR: {e}')
230
- results.append(('B5. CLAUDE.md Sync', passed, 2))
231
- print(f' {passed}/2 imports verified')
232
-
233
- # [B6] Confidence Scoring
234
- print('\n[B6] Confidence Scoring...')
235
- passed = 0
236
- try:
237
- from services.confidence import ConfidenceService, get_confidence_service
238
- passed += 2
239
- except Exception as e:
240
- print(f' ERROR: {e}')
241
- results.append(('B6. Confidence Scoring', passed, 2))
242
- print(f' {passed}/2 imports verified')
243
-
244
- # ===== MAIN.PY INTEGRATION =====
245
- print('\n' + '-' * 70)
246
- print('SECTION C: MAIN.PY INTEGRATION')
247
- print('-' * 70)
248
-
249
- print('\n[C1] API Endpoints...')
250
- passed = 0
251
- with open('main.py', 'r') as f:
252
- content = f.read()
253
-
254
- endpoints = [
255
- # Original endpoints
256
- '/health', '/dashboard', '/api/stats',
257
- # New automation endpoints
258
- '/api/inject', '/api/memory/natural',
259
- '/api/memory/{memory_id}/confidence',
260
- '/api/memory/{memory_id}/verify',
261
- '/api/claude-md/sync',
262
- '/ws',
263
- ]
264
- for ep in endpoints:
265
- if ep in content:
266
- passed += 1
267
- else:
268
- print(f' MISSING: {ep}')
269
-
270
- results.append(('C1. API Endpoints', passed, len(endpoints)))
271
- print(f' {passed}/{len(endpoints)} endpoints verified')
272
-
273
- # ===== SUMMARY =====
274
- print('\n' + '=' * 70)
275
- print('FINAL SUMMARY')
276
- print('=' * 70)
277
-
278
- total_passed = sum(r[1] for r in results)
279
- total_tests = sum(r[2] for r in results)
280
-
281
- section_a = [(n, p, t) for n, p, t in results if n.startswith('A')]
282
- section_b = [(n, p, t) for n, p, t in results if n.startswith('B')]
283
- section_c = [(n, p, t) for n, p, t in results if n.startswith('C')]
284
-
285
- print('\nSection A (Original 12 Features):')
286
- a_passed = sum(r[1] for r in section_a)
287
- a_total = sum(r[2] for r in section_a)
288
- for name, passed, total in section_a:
289
- status = 'PASS' if passed == total else 'PARTIAL' if passed > 0 else 'FAIL'
290
- print(f' [{status}] {name}: {passed}/{total}')
291
- print(f' Subtotal: {a_passed}/{a_total}')
292
-
293
- print('\nSection B (6 Automation Features):')
294
- b_passed = sum(r[1] for r in section_b)
295
- b_total = sum(r[2] for r in section_b)
296
- for name, passed, total in section_b:
297
- status = 'PASS' if passed == total else 'PARTIAL' if passed > 0 else 'FAIL'
298
- print(f' [{status}] {name}: {passed}/{total}')
299
- print(f' Subtotal: {b_passed}/{b_total}')
300
-
301
- print('\nSection C (Integration):')
302
- c_passed = sum(r[1] for r in section_c)
303
- c_total = sum(r[2] for r in section_c)
304
- for name, passed, total in section_c:
305
- status = 'PASS' if passed == total else 'PARTIAL' if passed > 0 else 'FAIL'
306
- print(f' [{status}] {name}: {passed}/{total}')
307
- print(f' Subtotal: {c_passed}/{c_total}')
308
-
309
- pct = 100 * total_passed // total_tests if total_tests > 0 else 0
310
- print(f'\n{"=" * 70}')
311
- print(f'TOTAL: {total_passed}/{total_tests} ({pct}%)')
312
- print(f'{"=" * 70}')
313
-
314
- if pct == 100:
315
- print('\n*** ALL TESTS PASSED! MEMORY SYSTEM FULLY OPERATIONAL ***')
316
- elif pct >= 90:
317
- print('\n*** MEMORY SYSTEM READY FOR USE ***')
318
-
319
- return pct
320
-
321
- if __name__ == '__main__':
322
- pct = asyncio.run(test_all())
package/verify_db.py DELETED
@@ -1,134 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Quick database verification tool - run this to see what's stored."""
3
- import sqlite3
4
- import json
5
- from datetime import datetime
6
-
7
- DB_PATH = "memories.db"
8
-
9
- def main():
10
- conn = sqlite3.connect(DB_PATH)
11
- conn.row_factory = sqlite3.Row
12
-
13
- print("\n" + "="*60)
14
- print(" CLAUDE MEMORY - DATABASE VERIFICATION")
15
- print("="*60)
16
-
17
- # Agent configs
18
- print("\n[AGENT CONFIGURATIONS]")
19
- print("-" * 40)
20
- cursor = conn.execute("""
21
- SELECT project_path, agent_id, enabled, updated_at
22
- FROM project_agent_config
23
- ORDER BY updated_at DESC
24
- LIMIT 10
25
- """)
26
- rows = cursor.fetchall()
27
- if rows:
28
- for row in rows:
29
- project = row["project_path"].split("\\")[-1] if "\\" in row["project_path"] else row["project_path"].split("/")[-1]
30
- status = "ON" if row["enabled"] else "OFF"
31
- print(f" [{status:3}] {row['agent_id']:<30} | {project}")
32
- print(f" Updated: {row['updated_at']}")
33
- else:
34
- print(" No configurations yet - toggle an agent in the dashboard!")
35
-
36
- # MCP configs
37
- print("\n[MCP CONFIGURATIONS]")
38
- print("-" * 40)
39
- cursor = conn.execute("""
40
- SELECT project_path, mcp_id, enabled, updated_at
41
- FROM project_mcp_config
42
- ORDER BY updated_at DESC
43
- LIMIT 10
44
- """)
45
- rows = cursor.fetchall()
46
- if rows:
47
- for row in rows:
48
- project = row["project_path"].split("\\")[-1] if "\\" in row["project_path"] else row["project_path"].split("/")[-1]
49
- status = "ON" if row["enabled"] else "OFF"
50
- print(f" [{status:3}] {row['mcp_id']:<30} | {project}")
51
- else:
52
- print(" No MCP configurations yet")
53
-
54
- # Hook configs
55
- print("\n[HOOK CONFIGURATIONS]")
56
- print("-" * 40)
57
- cursor = conn.execute("""
58
- SELECT project_path, hook_id, enabled, updated_at
59
- FROM project_hook_config
60
- ORDER BY updated_at DESC
61
- LIMIT 10
62
- """)
63
- rows = cursor.fetchall()
64
- if rows:
65
- for row in rows:
66
- project = row["project_path"].split("\\")[-1] if "\\" in row["project_path"] else row["project_path"].split("/")[-1]
67
- status = "ON" if row["enabled"] else "OFF"
68
- print(f" [{status:3}] {row['hook_id']:<30} | {project}")
69
- else:
70
- print(" No hook configurations yet")
71
-
72
- # Timeline events
73
- print("\n[RECENT TIMELINE EVENTS]")
74
- print("-" * 40)
75
- cursor = conn.execute("""
76
- SELECT event_type, summary, session_id, created_at, is_anchor
77
- FROM timeline_events
78
- ORDER BY created_at DESC
79
- LIMIT 15
80
- """)
81
- rows = cursor.fetchall()
82
- if rows:
83
- for row in rows:
84
- anchor = " [ANCHOR]" if row["is_anchor"] else ""
85
- print(f" [{row['event_type']:<12}] {row['summary'][:50]}...{anchor}")
86
- print(f" {row['created_at']}")
87
- else:
88
- print(" No timeline events yet")
89
-
90
- # Anchors only
91
- print("\n[ANCHORS (VERIFIED FACTS)]")
92
- print("-" * 40)
93
- cursor = conn.execute("""
94
- SELECT summary, details, created_at
95
- FROM timeline_events
96
- WHERE is_anchor = 1
97
- ORDER BY created_at DESC
98
- LIMIT 10
99
- """)
100
- rows = cursor.fetchall()
101
- if rows:
102
- for row in rows:
103
- print(f" * {row['summary']}")
104
- if row['details']:
105
- print(f" Details: {row['details'][:60]}...")
106
- else:
107
- print(" No anchors set yet")
108
-
109
- # Stats
110
- print("\n[STATISTICS]")
111
- print("-" * 40)
112
- cursor = conn.execute("SELECT COUNT(*) as c FROM memories")
113
- print(f" Total Memories: {cursor.fetchone()['c']}")
114
-
115
- cursor = conn.execute("SELECT COUNT(*) as c FROM timeline_events")
116
- print(f" Timeline Events: {cursor.fetchone()['c']}")
117
-
118
- cursor = conn.execute("SELECT COUNT(*) as c FROM project_agent_config")
119
- print(f" Agent Configs: {cursor.fetchone()['c']}")
120
-
121
- cursor = conn.execute("SELECT COUNT(*) as c FROM session_state")
122
- print(f" Sessions: {cursor.fetchone()['c']}")
123
-
124
- cursor = conn.execute("SELECT COUNT(*) as c FROM checkpoints")
125
- print(f" Checkpoints: {cursor.fetchone()['c']}")
126
-
127
- print("\n" + "="*60)
128
- print(" Run this again after toggling something in the dashboard!")
129
- print("="*60 + "\n")
130
-
131
- conn.close()
132
-
133
- if __name__ == "__main__":
134
- main()