claude-memory-agent 2.0.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 (100) hide show
  1. package/.env.example +107 -0
  2. package/README.md +200 -0
  3. package/agent_card.py +512 -0
  4. package/bin/cli.js +181 -0
  5. package/bin/postinstall.js +216 -0
  6. package/config.py +104 -0
  7. package/dashboard.html +2689 -0
  8. package/hooks/README.md +196 -0
  9. package/hooks/__pycache__/auto-detect-response.cpython-312.pyc +0 -0
  10. package/hooks/__pycache__/auto_capture.cpython-312.pyc +0 -0
  11. package/hooks/__pycache__/session_end.cpython-312.pyc +0 -0
  12. package/hooks/__pycache__/session_start.cpython-312.pyc +0 -0
  13. package/hooks/auto-detect-response.py +348 -0
  14. package/hooks/auto_capture.py +255 -0
  15. package/hooks/detect-correction.py +173 -0
  16. package/hooks/grounding-hook.py +348 -0
  17. package/hooks/log-tool-use.py +234 -0
  18. package/hooks/log-user-request.py +208 -0
  19. package/hooks/pre-tool-decision.py +218 -0
  20. package/hooks/problem-detector.py +343 -0
  21. package/hooks/session_end.py +192 -0
  22. package/hooks/session_start.py +227 -0
  23. package/install.py +887 -0
  24. package/main.py +2859 -0
  25. package/manager.py +997 -0
  26. package/package.json +55 -0
  27. package/requirements.txt +8 -0
  28. package/run_server.py +136 -0
  29. package/services/__init__.py +50 -0
  30. package/services/__pycache__/__init__.cpython-312.pyc +0 -0
  31. package/services/__pycache__/agent_registry.cpython-312.pyc +0 -0
  32. package/services/__pycache__/auth.cpython-312.pyc +0 -0
  33. package/services/__pycache__/auto_inject.cpython-312.pyc +0 -0
  34. package/services/__pycache__/claude_md_sync.cpython-312.pyc +0 -0
  35. package/services/__pycache__/cleanup.cpython-312.pyc +0 -0
  36. package/services/__pycache__/compaction_flush.cpython-312.pyc +0 -0
  37. package/services/__pycache__/confidence.cpython-312.pyc +0 -0
  38. package/services/__pycache__/daily_log.cpython-312.pyc +0 -0
  39. package/services/__pycache__/database.cpython-312.pyc +0 -0
  40. package/services/__pycache__/embeddings.cpython-312.pyc +0 -0
  41. package/services/__pycache__/insights.cpython-312.pyc +0 -0
  42. package/services/__pycache__/llm_analyzer.cpython-312.pyc +0 -0
  43. package/services/__pycache__/memory_md_sync.cpython-312.pyc +0 -0
  44. package/services/__pycache__/retry_queue.cpython-312.pyc +0 -0
  45. package/services/__pycache__/timeline.cpython-312.pyc +0 -0
  46. package/services/__pycache__/vector_index.cpython-312.pyc +0 -0
  47. package/services/__pycache__/websocket.cpython-312.pyc +0 -0
  48. package/services/agent_registry.py +753 -0
  49. package/services/auth.py +331 -0
  50. package/services/auto_inject.py +250 -0
  51. package/services/claude_md_sync.py +275 -0
  52. package/services/cleanup.py +667 -0
  53. package/services/compaction_flush.py +447 -0
  54. package/services/confidence.py +301 -0
  55. package/services/daily_log.py +333 -0
  56. package/services/database.py +2485 -0
  57. package/services/embeddings.py +358 -0
  58. package/services/insights.py +632 -0
  59. package/services/llm_analyzer.py +595 -0
  60. package/services/memory_md_sync.py +409 -0
  61. package/services/retry_queue.py +453 -0
  62. package/services/timeline.py +579 -0
  63. package/services/vector_index.py +398 -0
  64. package/services/websocket.py +257 -0
  65. package/skills/__init__.py +6 -0
  66. package/skills/__pycache__/__init__.cpython-312.pyc +0 -0
  67. package/skills/__pycache__/admin.cpython-312.pyc +0 -0
  68. package/skills/__pycache__/checkpoint.cpython-312.pyc +0 -0
  69. package/skills/__pycache__/claude_md.cpython-312.pyc +0 -0
  70. package/skills/__pycache__/cleanup.cpython-312.pyc +0 -0
  71. package/skills/__pycache__/grounding.cpython-312.pyc +0 -0
  72. package/skills/__pycache__/insights.cpython-312.pyc +0 -0
  73. package/skills/__pycache__/natural_language.cpython-312.pyc +0 -0
  74. package/skills/__pycache__/retrieve.cpython-312.pyc +0 -0
  75. package/skills/__pycache__/search.cpython-312.pyc +0 -0
  76. package/skills/__pycache__/state.cpython-312.pyc +0 -0
  77. package/skills/__pycache__/store.cpython-312.pyc +0 -0
  78. package/skills/__pycache__/summarize.cpython-312.pyc +0 -0
  79. package/skills/__pycache__/timeline.cpython-312.pyc +0 -0
  80. package/skills/__pycache__/verification.cpython-312.pyc +0 -0
  81. package/skills/admin.py +469 -0
  82. package/skills/checkpoint.py +198 -0
  83. package/skills/claude_md.py +363 -0
  84. package/skills/cleanup.py +241 -0
  85. package/skills/grounding.py +801 -0
  86. package/skills/insights.py +231 -0
  87. package/skills/natural_language.py +277 -0
  88. package/skills/retrieve.py +67 -0
  89. package/skills/search.py +213 -0
  90. package/skills/state.py +182 -0
  91. package/skills/store.py +179 -0
  92. package/skills/summarize.py +588 -0
  93. package/skills/timeline.py +387 -0
  94. package/skills/verification.py +391 -0
  95. package/start_daemon.py +155 -0
  96. package/test_automation.py +221 -0
  97. package/test_complete.py +338 -0
  98. package/test_full.py +322 -0
  99. package/update_system.py +817 -0
  100. package/verify_db.py +134 -0
package/test_full.py ADDED
@@ -0,0 +1,322 @@
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())