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.
- package/README.md +206 -206
- package/agent_card.py +186 -0
- package/bin/cli.js +327 -185
- package/bin/lib/banner.js +39 -0
- package/bin/lib/environment.js +166 -0
- package/bin/lib/installer.js +291 -0
- package/bin/lib/models.js +95 -0
- package/bin/lib/steps/advanced.js +101 -0
- package/bin/lib/steps/confirm.js +87 -0
- package/bin/lib/steps/model.js +57 -0
- package/bin/lib/steps/provider.js +65 -0
- package/bin/lib/steps/scope.js +59 -0
- package/bin/lib/steps/server.js +74 -0
- package/bin/lib/ui.js +75 -0
- package/bin/onboarding.js +164 -0
- package/bin/postinstall.js +35 -270
- package/config.py +103 -4
- package/dashboard.html +4902 -2689
- package/hooks/extract_memories.py +439 -0
- package/hooks/grounding-hook.py +422 -348
- package/hooks/pre_compact_hook.py +76 -0
- package/hooks/session_end.py +293 -192
- package/hooks/session_end_hook.py +149 -0
- package/hooks/session_start.py +227 -227
- package/hooks/stop_hook.py +372 -0
- package/install.py +972 -902
- package/main.py +5240 -2859
- package/mcp_server.py +451 -0
- package/package.json +58 -47
- package/requirements.txt +12 -8
- package/services/__init__.py +50 -50
- package/services/adaptive_ranker.py +272 -0
- package/services/agent_catalog.json +153 -0
- package/services/agent_registry.py +245 -730
- package/services/claude_md_sync.py +320 -4
- package/services/consolidation.py +417 -0
- package/services/curator.py +1606 -0
- package/services/database.py +4118 -2485
- package/services/embedding_pipeline.py +262 -0
- package/services/embeddings.py +493 -85
- package/services/memory_decay.py +408 -0
- package/services/native_memory_paths.py +86 -0
- package/services/native_memory_sync.py +496 -0
- package/services/response_manager.py +183 -0
- package/services/terminal_ui.py +199 -0
- package/services/tier_manager.py +235 -0
- package/services/websocket.py +26 -6
- package/skills/__init__.py +21 -1
- package/skills/confidence_tracker.py +441 -0
- package/skills/context.py +675 -0
- package/skills/curator.py +348 -0
- package/skills/search.py +444 -213
- package/skills/session_review.py +605 -0
- package/skills/store.py +484 -179
- package/terminal_dashboard.py +474 -0
- package/update_system.py +829 -817
- package/hooks/__pycache__/auto-detect-response.cpython-312.pyc +0 -0
- package/hooks/__pycache__/auto_capture.cpython-312.pyc +0 -0
- package/hooks/__pycache__/session_end.cpython-312.pyc +0 -0
- package/hooks/__pycache__/session_start.cpython-312.pyc +0 -0
- package/services/__pycache__/__init__.cpython-312.pyc +0 -0
- package/services/__pycache__/agent_registry.cpython-312.pyc +0 -0
- package/services/__pycache__/auth.cpython-312.pyc +0 -0
- package/services/__pycache__/auto_inject.cpython-312.pyc +0 -0
- package/services/__pycache__/claude_md_sync.cpython-312.pyc +0 -0
- package/services/__pycache__/cleanup.cpython-312.pyc +0 -0
- package/services/__pycache__/compaction_flush.cpython-312.pyc +0 -0
- package/services/__pycache__/confidence.cpython-312.pyc +0 -0
- package/services/__pycache__/daily_log.cpython-312.pyc +0 -0
- package/services/__pycache__/database.cpython-312.pyc +0 -0
- package/services/__pycache__/embeddings.cpython-312.pyc +0 -0
- package/services/__pycache__/insights.cpython-312.pyc +0 -0
- package/services/__pycache__/llm_analyzer.cpython-312.pyc +0 -0
- package/services/__pycache__/memory_md_sync.cpython-312.pyc +0 -0
- package/services/__pycache__/retry_queue.cpython-312.pyc +0 -0
- package/services/__pycache__/timeline.cpython-312.pyc +0 -0
- package/services/__pycache__/vector_index.cpython-312.pyc +0 -0
- package/services/__pycache__/websocket.cpython-312.pyc +0 -0
- package/skills/__pycache__/__init__.cpython-312.pyc +0 -0
- package/skills/__pycache__/admin.cpython-312.pyc +0 -0
- package/skills/__pycache__/checkpoint.cpython-312.pyc +0 -0
- package/skills/__pycache__/claude_md.cpython-312.pyc +0 -0
- package/skills/__pycache__/cleanup.cpython-312.pyc +0 -0
- package/skills/__pycache__/grounding.cpython-312.pyc +0 -0
- package/skills/__pycache__/insights.cpython-312.pyc +0 -0
- package/skills/__pycache__/natural_language.cpython-312.pyc +0 -0
- package/skills/__pycache__/retrieve.cpython-312.pyc +0 -0
- package/skills/__pycache__/search.cpython-312.pyc +0 -0
- package/skills/__pycache__/state.cpython-312.pyc +0 -0
- package/skills/__pycache__/store.cpython-312.pyc +0 -0
- package/skills/__pycache__/summarize.cpython-312.pyc +0 -0
- package/skills/__pycache__/timeline.cpython-312.pyc +0 -0
- package/skills/__pycache__/verification.cpython-312.pyc +0 -0
- package/test_automation.py +0 -221
- package/test_complete.py +0 -338
- package/test_full.py +0 -322
- 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()
|