superlocalmemory 2.8.5 → 3.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 (434) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +9 -1
  3. package/NOTICE +63 -0
  4. package/README.md +165 -480
  5. package/bin/slm +17 -449
  6. package/bin/slm-npm +2 -2
  7. package/bin/slm.bat +4 -2
  8. package/conftest.py +5 -0
  9. package/docs/api-reference.md +284 -0
  10. package/docs/architecture.md +149 -0
  11. package/docs/auto-memory.md +150 -0
  12. package/docs/cli-reference.md +276 -0
  13. package/docs/compliance.md +191 -0
  14. package/docs/configuration.md +182 -0
  15. package/docs/getting-started.md +102 -0
  16. package/docs/ide-setup.md +261 -0
  17. package/docs/mcp-tools.md +220 -0
  18. package/docs/migration-from-v2.md +170 -0
  19. package/docs/profiles.md +173 -0
  20. package/docs/troubleshooting.md +310 -0
  21. package/{configs → ide/configs}/antigravity-mcp.json +3 -3
  22. package/ide/configs/chatgpt-desktop-mcp.json +16 -0
  23. package/{configs → ide/configs}/claude-desktop-mcp.json +3 -3
  24. package/{configs → ide/configs}/codex-mcp.toml +4 -4
  25. package/{configs → ide/configs}/continue-mcp.yaml +4 -3
  26. package/{configs → ide/configs}/continue-skills.yaml +6 -6
  27. package/ide/configs/cursor-mcp.json +15 -0
  28. package/{configs → ide/configs}/gemini-cli-mcp.json +2 -2
  29. package/{configs → ide/configs}/jetbrains-mcp.json +2 -2
  30. package/{configs → ide/configs}/opencode-mcp.json +2 -2
  31. package/{configs → ide/configs}/perplexity-mcp.json +2 -2
  32. package/{configs → ide/configs}/vscode-copilot-mcp.json +2 -2
  33. package/{configs → ide/configs}/windsurf-mcp.json +3 -3
  34. package/{configs → ide/configs}/zed-mcp.json +2 -2
  35. package/{hooks → ide/hooks}/context-hook.js +9 -20
  36. package/ide/hooks/memory-list-skill.js +70 -0
  37. package/ide/hooks/memory-profile-skill.js +101 -0
  38. package/ide/hooks/memory-recall-skill.js +62 -0
  39. package/ide/hooks/memory-remember-skill.js +68 -0
  40. package/ide/hooks/memory-reset-skill.js +160 -0
  41. package/{hooks → ide/hooks}/post-recall-hook.js +2 -2
  42. package/ide/integrations/langchain/README.md +106 -0
  43. package/ide/integrations/langchain/langchain_superlocalmemory/__init__.py +9 -0
  44. package/ide/integrations/langchain/langchain_superlocalmemory/chat_message_history.py +201 -0
  45. package/ide/integrations/langchain/pyproject.toml +38 -0
  46. package/{src/learning → ide/integrations/langchain}/tests/__init__.py +1 -0
  47. package/ide/integrations/langchain/tests/test_chat_message_history.py +215 -0
  48. package/ide/integrations/langchain/tests/test_security.py +117 -0
  49. package/ide/integrations/llamaindex/README.md +81 -0
  50. package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/__init__.py +9 -0
  51. package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/base.py +316 -0
  52. package/ide/integrations/llamaindex/pyproject.toml +43 -0
  53. package/{src/lifecycle → ide/integrations/llamaindex}/tests/__init__.py +1 -2
  54. package/ide/integrations/llamaindex/tests/test_chat_store.py +294 -0
  55. package/ide/integrations/llamaindex/tests/test_security.py +241 -0
  56. package/{skills → ide/skills}/slm-build-graph/SKILL.md +6 -6
  57. package/{skills → ide/skills}/slm-list-recent/SKILL.md +5 -5
  58. package/{skills → ide/skills}/slm-recall/SKILL.md +5 -5
  59. package/{skills → ide/skills}/slm-remember/SKILL.md +6 -6
  60. package/{skills → ide/skills}/slm-show-patterns/SKILL.md +7 -7
  61. package/{skills → ide/skills}/slm-status/SKILL.md +9 -9
  62. package/{skills → ide/skills}/slm-switch-profile/SKILL.md +9 -9
  63. package/package.json +13 -22
  64. package/pyproject.toml +85 -0
  65. package/scripts/build-dmg.sh +417 -0
  66. package/scripts/install-skills.ps1 +334 -0
  67. package/{install.ps1 → scripts/install.ps1} +36 -4
  68. package/{install.sh → scripts/install.sh} +14 -13
  69. package/scripts/postinstall.js +2 -2
  70. package/scripts/start-dashboard.ps1 +52 -0
  71. package/scripts/start-dashboard.sh +41 -0
  72. package/scripts/sync-wiki.ps1 +127 -0
  73. package/scripts/sync-wiki.sh +82 -0
  74. package/scripts/test-dmg.sh +161 -0
  75. package/scripts/test-npm-package.ps1 +252 -0
  76. package/scripts/test-npm-package.sh +207 -0
  77. package/scripts/verify-install.ps1 +294 -0
  78. package/scripts/verify-install.sh +266 -0
  79. package/src/superlocalmemory/__init__.py +0 -0
  80. package/src/superlocalmemory/attribution/__init__.py +9 -0
  81. package/src/superlocalmemory/attribution/mathematical_dna.py +235 -0
  82. package/src/superlocalmemory/attribution/signer.py +153 -0
  83. package/src/superlocalmemory/attribution/watermark.py +189 -0
  84. package/src/superlocalmemory/cli/__init__.py +5 -0
  85. package/src/superlocalmemory/cli/commands.py +245 -0
  86. package/src/superlocalmemory/cli/main.py +89 -0
  87. package/src/superlocalmemory/cli/migrate_cmd.py +55 -0
  88. package/src/superlocalmemory/cli/post_install.py +99 -0
  89. package/src/superlocalmemory/cli/setup_wizard.py +129 -0
  90. package/src/superlocalmemory/compliance/__init__.py +0 -0
  91. package/src/superlocalmemory/compliance/abac.py +204 -0
  92. package/src/superlocalmemory/compliance/audit.py +314 -0
  93. package/src/superlocalmemory/compliance/eu_ai_act.py +131 -0
  94. package/src/superlocalmemory/compliance/gdpr.py +294 -0
  95. package/src/superlocalmemory/compliance/lifecycle.py +158 -0
  96. package/src/superlocalmemory/compliance/retention.py +232 -0
  97. package/src/superlocalmemory/compliance/scheduler.py +148 -0
  98. package/src/superlocalmemory/core/__init__.py +0 -0
  99. package/src/superlocalmemory/core/config.py +391 -0
  100. package/src/superlocalmemory/core/embeddings.py +293 -0
  101. package/src/superlocalmemory/core/engine.py +701 -0
  102. package/src/superlocalmemory/core/hooks.py +65 -0
  103. package/src/superlocalmemory/core/maintenance.py +172 -0
  104. package/src/superlocalmemory/core/modes.py +140 -0
  105. package/src/superlocalmemory/core/profiles.py +234 -0
  106. package/src/superlocalmemory/core/registry.py +117 -0
  107. package/src/superlocalmemory/dynamics/__init__.py +0 -0
  108. package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +223 -0
  109. package/src/superlocalmemory/encoding/__init__.py +0 -0
  110. package/src/superlocalmemory/encoding/consolidator.py +485 -0
  111. package/src/superlocalmemory/encoding/emotional.py +125 -0
  112. package/src/superlocalmemory/encoding/entity_resolver.py +525 -0
  113. package/src/superlocalmemory/encoding/entropy_gate.py +104 -0
  114. package/src/superlocalmemory/encoding/fact_extractor.py +775 -0
  115. package/src/superlocalmemory/encoding/foresight.py +91 -0
  116. package/src/superlocalmemory/encoding/graph_builder.py +302 -0
  117. package/src/superlocalmemory/encoding/observation_builder.py +160 -0
  118. package/src/superlocalmemory/encoding/scene_builder.py +183 -0
  119. package/src/superlocalmemory/encoding/signal_inference.py +90 -0
  120. package/src/superlocalmemory/encoding/temporal_parser.py +426 -0
  121. package/src/superlocalmemory/encoding/type_router.py +235 -0
  122. package/src/superlocalmemory/hooks/__init__.py +3 -0
  123. package/src/superlocalmemory/hooks/auto_capture.py +111 -0
  124. package/src/superlocalmemory/hooks/auto_recall.py +93 -0
  125. package/src/superlocalmemory/hooks/ide_connector.py +204 -0
  126. package/src/superlocalmemory/hooks/rules_engine.py +99 -0
  127. package/src/superlocalmemory/infra/__init__.py +3 -0
  128. package/src/superlocalmemory/infra/auth_middleware.py +82 -0
  129. package/src/superlocalmemory/infra/backup.py +317 -0
  130. package/src/superlocalmemory/infra/cache_manager.py +267 -0
  131. package/src/superlocalmemory/infra/event_bus.py +381 -0
  132. package/src/superlocalmemory/infra/rate_limiter.py +135 -0
  133. package/src/{webhook_dispatcher.py → superlocalmemory/infra/webhook_dispatcher.py} +104 -101
  134. package/src/superlocalmemory/learning/__init__.py +0 -0
  135. package/src/superlocalmemory/learning/adaptive.py +172 -0
  136. package/src/superlocalmemory/learning/behavioral.py +490 -0
  137. package/src/superlocalmemory/learning/behavioral_listener.py +94 -0
  138. package/src/superlocalmemory/learning/bootstrap.py +298 -0
  139. package/src/superlocalmemory/learning/cross_project.py +399 -0
  140. package/src/superlocalmemory/learning/database.py +376 -0
  141. package/src/superlocalmemory/learning/engagement.py +323 -0
  142. package/src/superlocalmemory/learning/features.py +138 -0
  143. package/src/superlocalmemory/learning/feedback.py +316 -0
  144. package/src/superlocalmemory/learning/outcomes.py +255 -0
  145. package/src/superlocalmemory/learning/project_context.py +366 -0
  146. package/src/superlocalmemory/learning/ranker.py +155 -0
  147. package/src/superlocalmemory/learning/source_quality.py +303 -0
  148. package/src/superlocalmemory/learning/workflows.py +309 -0
  149. package/src/superlocalmemory/llm/__init__.py +0 -0
  150. package/src/superlocalmemory/llm/backbone.py +316 -0
  151. package/src/superlocalmemory/math/__init__.py +0 -0
  152. package/src/superlocalmemory/math/fisher.py +356 -0
  153. package/src/superlocalmemory/math/langevin.py +398 -0
  154. package/src/superlocalmemory/math/sheaf.py +257 -0
  155. package/src/superlocalmemory/mcp/__init__.py +0 -0
  156. package/src/superlocalmemory/mcp/resources.py +245 -0
  157. package/src/superlocalmemory/mcp/server.py +61 -0
  158. package/src/superlocalmemory/mcp/tools.py +18 -0
  159. package/src/superlocalmemory/mcp/tools_core.py +305 -0
  160. package/src/superlocalmemory/mcp/tools_v28.py +223 -0
  161. package/src/superlocalmemory/mcp/tools_v3.py +286 -0
  162. package/src/superlocalmemory/retrieval/__init__.py +0 -0
  163. package/src/superlocalmemory/retrieval/agentic.py +295 -0
  164. package/src/superlocalmemory/retrieval/ann_index.py +223 -0
  165. package/src/superlocalmemory/retrieval/bm25_channel.py +185 -0
  166. package/src/superlocalmemory/retrieval/bridge_discovery.py +170 -0
  167. package/src/superlocalmemory/retrieval/engine.py +390 -0
  168. package/src/superlocalmemory/retrieval/entity_channel.py +179 -0
  169. package/src/superlocalmemory/retrieval/fusion.py +78 -0
  170. package/src/superlocalmemory/retrieval/profile_channel.py +105 -0
  171. package/src/superlocalmemory/retrieval/reranker.py +154 -0
  172. package/src/superlocalmemory/retrieval/semantic_channel.py +232 -0
  173. package/src/superlocalmemory/retrieval/strategy.py +96 -0
  174. package/src/superlocalmemory/retrieval/temporal_channel.py +175 -0
  175. package/src/superlocalmemory/server/__init__.py +1 -0
  176. package/src/superlocalmemory/server/api.py +248 -0
  177. package/src/superlocalmemory/server/routes/__init__.py +4 -0
  178. package/src/superlocalmemory/server/routes/agents.py +107 -0
  179. package/src/superlocalmemory/server/routes/backup.py +91 -0
  180. package/src/superlocalmemory/server/routes/behavioral.py +127 -0
  181. package/src/superlocalmemory/server/routes/compliance.py +160 -0
  182. package/src/superlocalmemory/server/routes/data_io.py +188 -0
  183. package/src/superlocalmemory/server/routes/events.py +183 -0
  184. package/src/superlocalmemory/server/routes/helpers.py +85 -0
  185. package/src/superlocalmemory/server/routes/learning.py +273 -0
  186. package/src/superlocalmemory/server/routes/lifecycle.py +116 -0
  187. package/src/superlocalmemory/server/routes/memories.py +399 -0
  188. package/src/superlocalmemory/server/routes/profiles.py +219 -0
  189. package/src/superlocalmemory/server/routes/stats.py +346 -0
  190. package/src/superlocalmemory/server/routes/v3_api.py +365 -0
  191. package/src/superlocalmemory/server/routes/ws.py +82 -0
  192. package/src/superlocalmemory/server/security_middleware.py +57 -0
  193. package/src/superlocalmemory/server/ui.py +245 -0
  194. package/src/superlocalmemory/storage/__init__.py +0 -0
  195. package/src/superlocalmemory/storage/access_control.py +182 -0
  196. package/src/superlocalmemory/storage/database.py +594 -0
  197. package/src/superlocalmemory/storage/migrations.py +303 -0
  198. package/src/superlocalmemory/storage/models.py +406 -0
  199. package/src/superlocalmemory/storage/schema.py +726 -0
  200. package/src/superlocalmemory/storage/v2_migrator.py +317 -0
  201. package/src/superlocalmemory/trust/__init__.py +0 -0
  202. package/src/superlocalmemory/trust/gate.py +130 -0
  203. package/src/superlocalmemory/trust/provenance.py +124 -0
  204. package/src/superlocalmemory/trust/scorer.py +347 -0
  205. package/src/superlocalmemory/trust/signals.py +153 -0
  206. package/ui/index.html +278 -5
  207. package/ui/js/auto-settings.js +70 -0
  208. package/ui/js/dashboard.js +90 -0
  209. package/ui/js/fact-detail.js +92 -0
  210. package/ui/js/feedback.js +2 -2
  211. package/ui/js/ide-status.js +102 -0
  212. package/ui/js/math-health.js +98 -0
  213. package/ui/js/recall-lab.js +127 -0
  214. package/ui/js/settings.js +2 -2
  215. package/ui/js/trust-dashboard.js +73 -0
  216. package/api_server.py +0 -724
  217. package/bin/aider-smart +0 -72
  218. package/bin/superlocalmemoryv2-learning +0 -4
  219. package/bin/superlocalmemoryv2-list +0 -3
  220. package/bin/superlocalmemoryv2-patterns +0 -4
  221. package/bin/superlocalmemoryv2-profile +0 -3
  222. package/bin/superlocalmemoryv2-recall +0 -3
  223. package/bin/superlocalmemoryv2-remember +0 -3
  224. package/bin/superlocalmemoryv2-reset +0 -3
  225. package/bin/superlocalmemoryv2-status +0 -3
  226. package/configs/chatgpt-desktop-mcp.json +0 -16
  227. package/configs/cursor-mcp.json +0 -15
  228. package/docs/SECURITY-QUICK-REFERENCE.md +0 -214
  229. package/hooks/memory-list-skill.js +0 -139
  230. package/hooks/memory-profile-skill.js +0 -273
  231. package/hooks/memory-recall-skill.js +0 -114
  232. package/hooks/memory-remember-skill.js +0 -127
  233. package/hooks/memory-reset-skill.js +0 -274
  234. package/mcp_server.py +0 -1800
  235. package/requirements-core.txt +0 -22
  236. package/requirements-learning.txt +0 -12
  237. package/requirements.txt +0 -12
  238. package/src/agent_registry.py +0 -411
  239. package/src/auth_middleware.py +0 -61
  240. package/src/auto_backup.py +0 -459
  241. package/src/behavioral/__init__.py +0 -49
  242. package/src/behavioral/behavioral_listener.py +0 -203
  243. package/src/behavioral/behavioral_patterns.py +0 -275
  244. package/src/behavioral/cross_project_transfer.py +0 -206
  245. package/src/behavioral/outcome_inference.py +0 -194
  246. package/src/behavioral/outcome_tracker.py +0 -193
  247. package/src/behavioral/tests/__init__.py +0 -4
  248. package/src/behavioral/tests/test_behavioral_integration.py +0 -108
  249. package/src/behavioral/tests/test_behavioral_patterns.py +0 -150
  250. package/src/behavioral/tests/test_cross_project_transfer.py +0 -142
  251. package/src/behavioral/tests/test_mcp_behavioral.py +0 -139
  252. package/src/behavioral/tests/test_mcp_report_outcome.py +0 -117
  253. package/src/behavioral/tests/test_outcome_inference.py +0 -107
  254. package/src/behavioral/tests/test_outcome_tracker.py +0 -96
  255. package/src/cache_manager.py +0 -518
  256. package/src/compliance/__init__.py +0 -48
  257. package/src/compliance/abac_engine.py +0 -149
  258. package/src/compliance/abac_middleware.py +0 -116
  259. package/src/compliance/audit_db.py +0 -215
  260. package/src/compliance/audit_logger.py +0 -148
  261. package/src/compliance/retention_manager.py +0 -289
  262. package/src/compliance/retention_scheduler.py +0 -186
  263. package/src/compliance/tests/__init__.py +0 -4
  264. package/src/compliance/tests/test_abac_enforcement.py +0 -95
  265. package/src/compliance/tests/test_abac_engine.py +0 -124
  266. package/src/compliance/tests/test_abac_mcp_integration.py +0 -118
  267. package/src/compliance/tests/test_audit_db.py +0 -123
  268. package/src/compliance/tests/test_audit_logger.py +0 -98
  269. package/src/compliance/tests/test_mcp_audit.py +0 -128
  270. package/src/compliance/tests/test_mcp_retention_policy.py +0 -125
  271. package/src/compliance/tests/test_retention_manager.py +0 -131
  272. package/src/compliance/tests/test_retention_scheduler.py +0 -99
  273. package/src/compression/__init__.py +0 -25
  274. package/src/compression/cli.py +0 -150
  275. package/src/compression/cold_storage.py +0 -217
  276. package/src/compression/config.py +0 -72
  277. package/src/compression/orchestrator.py +0 -133
  278. package/src/compression/tier2_compressor.py +0 -228
  279. package/src/compression/tier3_compressor.py +0 -153
  280. package/src/compression/tier_classifier.py +0 -148
  281. package/src/db_connection_manager.py +0 -536
  282. package/src/embedding_engine.py +0 -63
  283. package/src/embeddings/__init__.py +0 -47
  284. package/src/embeddings/cache.py +0 -70
  285. package/src/embeddings/cli.py +0 -113
  286. package/src/embeddings/constants.py +0 -47
  287. package/src/embeddings/database.py +0 -91
  288. package/src/embeddings/engine.py +0 -247
  289. package/src/embeddings/model_loader.py +0 -145
  290. package/src/event_bus.py +0 -562
  291. package/src/graph/__init__.py +0 -36
  292. package/src/graph/build_helpers.py +0 -74
  293. package/src/graph/cli.py +0 -87
  294. package/src/graph/cluster_builder.py +0 -188
  295. package/src/graph/cluster_summary.py +0 -148
  296. package/src/graph/constants.py +0 -47
  297. package/src/graph/edge_builder.py +0 -162
  298. package/src/graph/entity_extractor.py +0 -95
  299. package/src/graph/graph_core.py +0 -226
  300. package/src/graph/graph_search.py +0 -231
  301. package/src/graph/hierarchical.py +0 -207
  302. package/src/graph/schema.py +0 -99
  303. package/src/graph_engine.py +0 -52
  304. package/src/hnsw_index.py +0 -628
  305. package/src/hybrid_search.py +0 -46
  306. package/src/learning/__init__.py +0 -217
  307. package/src/learning/adaptive_ranker.py +0 -682
  308. package/src/learning/bootstrap/__init__.py +0 -69
  309. package/src/learning/bootstrap/constants.py +0 -93
  310. package/src/learning/bootstrap/db_queries.py +0 -316
  311. package/src/learning/bootstrap/sampling.py +0 -82
  312. package/src/learning/bootstrap/text_utils.py +0 -71
  313. package/src/learning/cross_project_aggregator.py +0 -857
  314. package/src/learning/db/__init__.py +0 -40
  315. package/src/learning/db/constants.py +0 -44
  316. package/src/learning/db/schema.py +0 -279
  317. package/src/learning/engagement_tracker.py +0 -628
  318. package/src/learning/feature_extractor.py +0 -708
  319. package/src/learning/feedback_collector.py +0 -806
  320. package/src/learning/learning_db.py +0 -915
  321. package/src/learning/project_context_manager.py +0 -572
  322. package/src/learning/ranking/__init__.py +0 -33
  323. package/src/learning/ranking/constants.py +0 -84
  324. package/src/learning/ranking/helpers.py +0 -278
  325. package/src/learning/source_quality_scorer.py +0 -676
  326. package/src/learning/synthetic_bootstrap.py +0 -755
  327. package/src/learning/tests/test_adaptive_ranker.py +0 -325
  328. package/src/learning/tests/test_adaptive_ranker_v28.py +0 -60
  329. package/src/learning/tests/test_aggregator.py +0 -306
  330. package/src/learning/tests/test_auto_retrain_v28.py +0 -35
  331. package/src/learning/tests/test_e2e_ranking_v28.py +0 -82
  332. package/src/learning/tests/test_feature_extractor_v28.py +0 -93
  333. package/src/learning/tests/test_feedback_collector.py +0 -294
  334. package/src/learning/tests/test_learning_db.py +0 -602
  335. package/src/learning/tests/test_learning_db_v28.py +0 -110
  336. package/src/learning/tests/test_learning_init_v28.py +0 -48
  337. package/src/learning/tests/test_outcome_signals.py +0 -48
  338. package/src/learning/tests/test_project_context.py +0 -292
  339. package/src/learning/tests/test_schema_migration.py +0 -319
  340. package/src/learning/tests/test_signal_inference.py +0 -397
  341. package/src/learning/tests/test_source_quality.py +0 -351
  342. package/src/learning/tests/test_synthetic_bootstrap.py +0 -429
  343. package/src/learning/tests/test_workflow_miner.py +0 -318
  344. package/src/learning/workflow_pattern_miner.py +0 -655
  345. package/src/lifecycle/__init__.py +0 -54
  346. package/src/lifecycle/bounded_growth.py +0 -239
  347. package/src/lifecycle/compaction_engine.py +0 -226
  348. package/src/lifecycle/lifecycle_engine.py +0 -355
  349. package/src/lifecycle/lifecycle_evaluator.py +0 -257
  350. package/src/lifecycle/lifecycle_scheduler.py +0 -130
  351. package/src/lifecycle/retention_policy.py +0 -285
  352. package/src/lifecycle/tests/test_bounded_growth.py +0 -193
  353. package/src/lifecycle/tests/test_compaction.py +0 -179
  354. package/src/lifecycle/tests/test_lifecycle_engine.py +0 -137
  355. package/src/lifecycle/tests/test_lifecycle_evaluation.py +0 -177
  356. package/src/lifecycle/tests/test_lifecycle_scheduler.py +0 -127
  357. package/src/lifecycle/tests/test_lifecycle_search.py +0 -109
  358. package/src/lifecycle/tests/test_mcp_compact.py +0 -149
  359. package/src/lifecycle/tests/test_mcp_lifecycle_status.py +0 -114
  360. package/src/lifecycle/tests/test_retention_policy.py +0 -162
  361. package/src/mcp_tools_v28.py +0 -281
  362. package/src/memory/__init__.py +0 -36
  363. package/src/memory/cli.py +0 -205
  364. package/src/memory/constants.py +0 -39
  365. package/src/memory/helpers.py +0 -28
  366. package/src/memory/schema.py +0 -166
  367. package/src/memory-profiles.py +0 -595
  368. package/src/memory-reset.py +0 -491
  369. package/src/memory_compression.py +0 -989
  370. package/src/memory_store_v2.py +0 -1155
  371. package/src/migrate_v1_to_v2.py +0 -629
  372. package/src/pattern_learner.py +0 -34
  373. package/src/patterns/__init__.py +0 -24
  374. package/src/patterns/analyzers.py +0 -251
  375. package/src/patterns/learner.py +0 -271
  376. package/src/patterns/scoring.py +0 -171
  377. package/src/patterns/store.py +0 -225
  378. package/src/patterns/terminology.py +0 -140
  379. package/src/provenance_tracker.py +0 -312
  380. package/src/qualixar_attribution.py +0 -139
  381. package/src/qualixar_watermark.py +0 -78
  382. package/src/query_optimizer.py +0 -511
  383. package/src/rate_limiter.py +0 -83
  384. package/src/search/__init__.py +0 -20
  385. package/src/search/cli.py +0 -77
  386. package/src/search/constants.py +0 -26
  387. package/src/search/engine.py +0 -241
  388. package/src/search/fusion.py +0 -122
  389. package/src/search/index_loader.py +0 -114
  390. package/src/search/methods.py +0 -162
  391. package/src/search_engine_v2.py +0 -401
  392. package/src/setup_validator.py +0 -482
  393. package/src/subscription_manager.py +0 -391
  394. package/src/tree/__init__.py +0 -59
  395. package/src/tree/builder.py +0 -185
  396. package/src/tree/nodes.py +0 -202
  397. package/src/tree/queries.py +0 -257
  398. package/src/tree/schema.py +0 -80
  399. package/src/tree_manager.py +0 -19
  400. package/src/trust/__init__.py +0 -45
  401. package/src/trust/constants.py +0 -66
  402. package/src/trust/queries.py +0 -157
  403. package/src/trust/schema.py +0 -95
  404. package/src/trust/scorer.py +0 -299
  405. package/src/trust/signals.py +0 -95
  406. package/src/trust_scorer.py +0 -44
  407. package/ui/app.js +0 -1588
  408. package/ui/js/graph-cytoscape-monolithic-backup.js +0 -1168
  409. package/ui/js/graph-cytoscape.js +0 -1168
  410. package/ui/js/graph-d3-backup.js +0 -32
  411. package/ui/js/graph.js +0 -32
  412. package/ui_server.py +0 -266
  413. /package/docs/{ACCESSIBILITY.md → v2-archive/ACCESSIBILITY.md} +0 -0
  414. /package/docs/{ARCHITECTURE.md → v2-archive/ARCHITECTURE.md} +0 -0
  415. /package/docs/{CLI-COMMANDS-REFERENCE.md → v2-archive/CLI-COMMANDS-REFERENCE.md} +0 -0
  416. /package/docs/{COMPRESSION-README.md → v2-archive/COMPRESSION-README.md} +0 -0
  417. /package/docs/{FRAMEWORK-INTEGRATIONS.md → v2-archive/FRAMEWORK-INTEGRATIONS.md} +0 -0
  418. /package/docs/{MCP-MANUAL-SETUP.md → v2-archive/MCP-MANUAL-SETUP.md} +0 -0
  419. /package/docs/{MCP-TROUBLESHOOTING.md → v2-archive/MCP-TROUBLESHOOTING.md} +0 -0
  420. /package/docs/{PATTERN-LEARNING.md → v2-archive/PATTERN-LEARNING.md} +0 -0
  421. /package/docs/{PROFILES-GUIDE.md → v2-archive/PROFILES-GUIDE.md} +0 -0
  422. /package/docs/{RESET-GUIDE.md → v2-archive/RESET-GUIDE.md} +0 -0
  423. /package/docs/{SEARCH-ENGINE-V2.2.0.md → v2-archive/SEARCH-ENGINE-V2.2.0.md} +0 -0
  424. /package/docs/{SEARCH-INTEGRATION-GUIDE.md → v2-archive/SEARCH-INTEGRATION-GUIDE.md} +0 -0
  425. /package/docs/{UI-SERVER.md → v2-archive/UI-SERVER.md} +0 -0
  426. /package/docs/{UNIVERSAL-INTEGRATION.md → v2-archive/UNIVERSAL-INTEGRATION.md} +0 -0
  427. /package/docs/{V2.2.0-OPTIONAL-SEARCH.md → v2-archive/V2.2.0-OPTIONAL-SEARCH.md} +0 -0
  428. /package/docs/{WINDOWS-INSTALL-README.txt → v2-archive/WINDOWS-INSTALL-README.txt} +0 -0
  429. /package/docs/{WINDOWS-POST-INSTALL.txt → v2-archive/WINDOWS-POST-INSTALL.txt} +0 -0
  430. /package/docs/{example_graph_usage.py → v2-archive/example_graph_usage.py} +0 -0
  431. /package/{completions → ide/completions}/slm.bash +0 -0
  432. /package/{completions → ide/completions}/slm.zsh +0 -0
  433. /package/{configs → ide/configs}/cody-commands.json +0 -0
  434. /package/{install-skills.sh → scripts/install-skills.sh} +0 -0
@@ -1,595 +0,0 @@
1
- #!/usr/bin/env python3
2
- # SPDX-License-Identifier: MIT
3
- # Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
4
- """
5
- SuperLocalMemory V2 - Profile Management System (Column-Based)
6
-
7
- v2.4.0: Rewritten to use column-based profiles in a SINGLE database.
8
- All memories live in one memory.db with a 'profile' column.
9
- Switching profiles = updating config. No file copying. No data loss risk.
10
-
11
- Previous versions used separate database files per profile, which caused
12
- data loss when switching. This version is backward compatible and will
13
- auto-migrate old profile directories on first run.
14
-
15
- Allows users to maintain separate memory contexts:
16
- - Work profile: Professional coding memories
17
- - Personal profile: Personal projects and learning
18
- - Client-specific profiles: Different clients get isolated memories
19
- - Experimentation profile: Testing and experiments
20
- """
21
-
22
- import os
23
- import sys
24
- import json
25
- import sqlite3
26
- import hashlib
27
- from pathlib import Path
28
- from datetime import datetime
29
- import argparse
30
- import re
31
-
32
- MEMORY_DIR = Path.home() / ".claude-memory"
33
- DB_PATH = MEMORY_DIR / "memory.db"
34
- PROFILES_DIR = MEMORY_DIR / "profiles"
35
- CONFIG_FILE = MEMORY_DIR / "profiles.json"
36
-
37
-
38
- class ProfileManager:
39
- """
40
- Column-based profile manager. All memories in ONE database.
41
- Profile = a value in the 'profile' column of the memories table.
42
- Switching = updating which profile name is active in config.
43
- """
44
-
45
- def __init__(self):
46
- self.memory_dir = MEMORY_DIR
47
- self.db_path = DB_PATH
48
- self.config_file = CONFIG_FILE
49
-
50
- # Ensure memory directory exists
51
- self.memory_dir.mkdir(exist_ok=True)
52
-
53
- # Ensure profile column exists in DB
54
- self._ensure_profile_column()
55
-
56
- # Load or create config
57
- self.config = self._load_config()
58
-
59
- # Auto-migrate old profile directories if they exist
60
- self._migrate_old_profiles()
61
-
62
- def _ensure_profile_column(self):
63
- """Add 'profile' column to memories table if it doesn't exist."""
64
- if not self.db_path.exists():
65
- return
66
-
67
- conn = sqlite3.connect(self.db_path)
68
- cursor = conn.cursor()
69
-
70
- cursor.execute("PRAGMA table_info(memories)")
71
- columns = {row[1] for row in cursor.fetchall()}
72
-
73
- if 'profile' not in columns:
74
- cursor.execute("ALTER TABLE memories ADD COLUMN profile TEXT DEFAULT 'default'")
75
- cursor.execute("UPDATE memories SET profile = 'default' WHERE profile IS NULL")
76
- try:
77
- cursor.execute("CREATE INDEX IF NOT EXISTS idx_profile ON memories(profile)")
78
- except sqlite3.OperationalError:
79
- pass
80
- conn.commit()
81
-
82
- conn.close()
83
-
84
- def _migrate_old_profiles(self):
85
- """
86
- Backward compatibility: migrate old separate-DB profiles into the main DB.
87
- Old profiles stored in ~/.claude-memory/profiles/<name>/memory.db
88
- New profiles use a 'profile' column in the main memory.db
89
- """
90
- profiles_dir = MEMORY_DIR / "profiles"
91
- if not profiles_dir.exists():
92
- return
93
-
94
- migrated_any = False
95
- for profile_dir in profiles_dir.iterdir():
96
- if not profile_dir.is_dir():
97
- continue
98
-
99
- profile_db = profile_dir / "memory.db"
100
- if not profile_db.exists():
101
- continue
102
-
103
- profile_name = profile_dir.name
104
- marker_file = profile_dir / ".migrated_to_column"
105
-
106
- # Skip if already migrated
107
- if marker_file.exists():
108
- continue
109
-
110
- # Import memories from old profile DB
111
- try:
112
- self._import_from_old_profile(profile_name, profile_db)
113
- # Mark as migrated
114
- marker_file.write_text(datetime.now().isoformat())
115
- migrated_any = True
116
- except Exception as e:
117
- print(f" Warning: Could not migrate profile '{profile_name}': {e}", file=sys.stderr)
118
-
119
- if migrated_any:
120
- print(" Profile migration complete (old separate DBs -> column-based)", file=sys.stderr)
121
-
122
- def _import_from_old_profile(self, profile_name, old_db_path):
123
- """Import memories from an old separate-DB profile into main DB."""
124
- if not self.db_path.exists():
125
- return
126
-
127
- main_conn = sqlite3.connect(self.db_path)
128
- main_cursor = main_conn.cursor()
129
-
130
- old_conn = sqlite3.connect(old_db_path)
131
- try:
132
- old_cursor = old_conn.cursor()
133
-
134
- # Get existing hashes
135
- main_cursor.execute("SELECT content_hash FROM memories WHERE content_hash IS NOT NULL")
136
- existing_hashes = {row[0] for row in main_cursor.fetchall()}
137
-
138
- # Get columns from old DB
139
- old_cursor.execute("PRAGMA table_info(memories)")
140
- old_columns = {row[1] for row in old_cursor.fetchall()}
141
-
142
- # Build SELECT based on available columns
143
- select_cols = ['content', 'summary', 'project_path', 'project_name', 'tags',
144
- 'category', 'memory_type', 'importance', 'created_at', 'updated_at',
145
- 'content_hash']
146
- available_cols = [c for c in select_cols if c in old_columns]
147
-
148
- if 'content' not in available_cols:
149
- return
150
-
151
- old_cursor.execute(f"SELECT {', '.join(available_cols)} FROM memories")
152
- rows = old_cursor.fetchall()
153
-
154
- imported = 0
155
- for row in rows:
156
- row_dict = dict(zip(available_cols, row))
157
- content = row_dict.get('content', '')
158
- content_hash = row_dict.get('content_hash')
159
-
160
- if not content:
161
- continue
162
-
163
- # Generate hash if missing
164
- if not content_hash:
165
- content_hash = hashlib.sha256(content.encode()).hexdigest()[:32]
166
-
167
- if content_hash in existing_hashes:
168
- continue
169
-
170
- try:
171
- main_cursor.execute('''
172
- INSERT INTO memories (content, summary, project_path, project_name, tags,
173
- category, memory_type, importance, created_at, updated_at,
174
- content_hash, profile)
175
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
176
- ''', (
177
- content,
178
- row_dict.get('summary'),
179
- row_dict.get('project_path'),
180
- row_dict.get('project_name'),
181
- row_dict.get('tags'),
182
- row_dict.get('category'),
183
- row_dict.get('memory_type', 'session'),
184
- row_dict.get('importance', 5),
185
- row_dict.get('created_at'),
186
- row_dict.get('updated_at'),
187
- content_hash,
188
- profile_name
189
- ))
190
- imported += 1
191
- existing_hashes.add(content_hash)
192
- except sqlite3.IntegrityError:
193
- pass
194
-
195
- main_conn.commit()
196
- finally:
197
- old_conn.close()
198
- main_conn.close()
199
-
200
- if imported > 0:
201
- # Add profile to config if not present
202
- config = self._load_config()
203
- if profile_name not in config.get('profiles', {}):
204
- config['profiles'][profile_name] = {
205
- 'name': profile_name,
206
- 'description': f'Memory profile: {profile_name} (migrated)',
207
- 'created_at': datetime.now().isoformat(),
208
- 'last_used': None
209
- }
210
- self._save_config(config)
211
-
212
- def _load_config(self):
213
- """Load profiles configuration."""
214
- if self.config_file.exists():
215
- with open(self.config_file, 'r') as f:
216
- return json.load(f)
217
- else:
218
- config = {
219
- 'profiles': {
220
- 'default': {
221
- 'name': 'default',
222
- 'description': 'Default memory profile',
223
- 'created_at': datetime.now().isoformat(),
224
- 'last_used': datetime.now().isoformat()
225
- }
226
- },
227
- 'active_profile': 'default'
228
- }
229
- self._save_config(config)
230
- return config
231
-
232
- def _save_config(self, config=None):
233
- """Save profiles configuration."""
234
- if config is None:
235
- config = self.config
236
-
237
- with open(self.config_file, 'w') as f:
238
- json.dump(config, f, indent=2)
239
-
240
- def _validate_profile_name(self, profile_name):
241
- """Validate profile name for security."""
242
- if not profile_name:
243
- raise ValueError("Profile name cannot be empty")
244
-
245
- if not re.match(r'^[a-zA-Z0-9_-]+$', profile_name):
246
- raise ValueError("Invalid profile name. Use only letters, numbers, dash, underscore.")
247
-
248
- if len(profile_name) > 50:
249
- raise ValueError("Profile name too long (max 50 characters)")
250
-
251
- if profile_name in ['.', '..']:
252
- raise ValueError(f"Reserved profile name: {profile_name}")
253
-
254
- def _get_memory_count(self, profile_name):
255
- """Get memory count for a specific profile."""
256
- if not self.db_path.exists():
257
- return 0
258
-
259
- conn = sqlite3.connect(self.db_path)
260
- try:
261
- cursor = conn.cursor()
262
- cursor.execute("SELECT COUNT(*) FROM memories WHERE profile = ?", (profile_name,))
263
- count = cursor.fetchone()[0]
264
- finally:
265
- conn.close()
266
- return count
267
-
268
- def get_active_profile(self) -> str:
269
- """Get the currently active profile name."""
270
- return self.config.get('active_profile', 'default')
271
-
272
- def list_profiles(self) -> list:
273
- """List all available profiles with memory counts."""
274
- print("\n" + "=" * 60)
275
- print("AVAILABLE MEMORY PROFILES")
276
- print("=" * 60)
277
-
278
- active = self.config.get('active_profile', 'default')
279
-
280
- if not self.config.get('profiles'):
281
- print("\n No profiles found. Create one with: create <name>")
282
- return
283
-
284
- print(f"\n{'Profile':20s} {'Description':30s} {'Memories':10s} {'Status':10s}")
285
- print("-" * 75)
286
-
287
- for name, info in self.config['profiles'].items():
288
- status = "ACTIVE" if name == active else ""
289
- desc = info.get('description', 'No description')[:30]
290
- marker = "-> " if name == active else " "
291
- count = self._get_memory_count(name)
292
- print(f"{marker}{name:17s} {desc:30s} {count:<10d} {status:10s}")
293
-
294
- print(f"\nTotal profiles: {len(self.config['profiles'])}")
295
- print(f"Active profile: {active}")
296
-
297
- def create_profile(self, name, description=None, from_current=False):
298
- """
299
- Create a new profile.
300
- Column-based: just adds to config. If from_current, copies memories.
301
- """
302
- print(f"\nCreating profile: {name}")
303
-
304
- self._validate_profile_name(name)
305
-
306
- if name in self.config['profiles']:
307
- print(f"Error: Profile '{name}' already exists")
308
- return False
309
-
310
- if from_current:
311
- # Copy current profile's memories to new profile
312
- active = self.config.get('active_profile', 'default')
313
- if self.db_path.exists():
314
- conn = sqlite3.connect(self.db_path)
315
- cursor = conn.cursor()
316
- cursor.execute("""
317
- INSERT INTO memories (content, summary, project_path, project_name, tags,
318
- category, parent_id, tree_path, depth, memory_type,
319
- importance, created_at, updated_at, last_accessed,
320
- access_count, content_hash, cluster_id, profile)
321
- SELECT content, summary, project_path, project_name, tags,
322
- category, parent_id, tree_path, depth, memory_type,
323
- importance, created_at, updated_at, last_accessed,
324
- access_count, NULL, cluster_id, ?
325
- FROM memories WHERE profile = ?
326
- """, (name, active))
327
- copied = cursor.rowcount
328
- conn.commit()
329
-
330
- # Generate new content hashes for copied memories
331
- cursor.execute("SELECT id, content FROM memories WHERE profile = ? AND content_hash IS NULL", (name,))
332
- for row in cursor.fetchall():
333
- new_hash = hashlib.sha256(row[1].encode()).hexdigest()[:32]
334
- try:
335
- cursor.execute("UPDATE memories SET content_hash = ? WHERE id = ?", (new_hash + f"_{name}", row[0]))
336
- except sqlite3.IntegrityError:
337
- pass
338
- conn.commit()
339
- conn.close()
340
-
341
- print(f" Copied {copied} memories from '{active}' profile")
342
- else:
343
- print(" No database found, creating empty profile")
344
- else:
345
- print(f" Empty profile created (memories will be saved here when active)")
346
-
347
- # Add to config
348
- self.config['profiles'][name] = {
349
- 'name': name,
350
- 'description': description or f'Memory profile: {name}',
351
- 'created_at': datetime.now().isoformat(),
352
- 'last_used': None,
353
- 'created_from': 'current' if from_current else 'empty'
354
- }
355
- self._save_config()
356
-
357
- print(f"Profile '{name}' created successfully")
358
- return True
359
-
360
- def switch_profile(self, name):
361
- """
362
- Switch to a different profile.
363
- Column-based: just updates the active_profile in config. Instant. No data risk.
364
- """
365
- if name not in self.config['profiles']:
366
- print(f"Error: Profile '{name}' not found")
367
- print(f" Available: {', '.join(self.config['profiles'].keys())}")
368
- return False
369
-
370
- current = self.config.get('active_profile', 'default')
371
-
372
- if current == name:
373
- print(f"Already using profile: {name}")
374
- return True
375
-
376
- # Column-based switch: just update config
377
- self.config['active_profile'] = name
378
- self.config['profiles'][name]['last_used'] = datetime.now().isoformat()
379
- self._save_config()
380
-
381
- count = self._get_memory_count(name)
382
- print(f"\nSwitched to profile: {name} ({count} memories)")
383
- print(f"Previous profile: {current}")
384
- return True
385
-
386
- def delete_profile(self, name, force=False):
387
- """Delete a profile. Moves memories to 'default' or deletes them."""
388
- if name not in self.config['profiles']:
389
- print(f"Error: Profile '{name}' not found")
390
- return False
391
-
392
- if name == 'default':
393
- print(f"Error: Cannot delete 'default' profile")
394
- return False
395
-
396
- if self.config.get('active_profile') == name:
397
- print(f"Error: Cannot delete active profile")
398
- print(f" Switch to another profile first: slm profile switch default")
399
- return False
400
-
401
- count = self._get_memory_count(name)
402
-
403
- if not force:
404
- print(f"\nWARNING: This will delete profile '{name}' ({count} memories)")
405
- print(f"Memories will be moved to 'default' profile before deletion.")
406
- response = input(f"Type profile name '{name}' to confirm: ")
407
-
408
- if response != name:
409
- print("Cancelled.")
410
- return False
411
-
412
- # Move memories to default profile
413
- if self.db_path.exists() and count > 0:
414
- conn = sqlite3.connect(self.db_path)
415
- try:
416
- cursor = conn.cursor()
417
- cursor.execute("UPDATE memories SET profile = 'default' WHERE profile = ?", (name,))
418
- moved = cursor.rowcount
419
- conn.commit()
420
- finally:
421
- conn.close()
422
- print(f" Moved {moved} memories to 'default' profile")
423
-
424
- # Remove from config
425
- del self.config['profiles'][name]
426
- self._save_config()
427
-
428
- print(f"Profile '{name}' deleted")
429
- return True
430
-
431
- def show_current(self):
432
- """Show current active profile with stats."""
433
- active = self.config.get('active_profile', 'default')
434
-
435
- if active in self.config['profiles']:
436
- info = self.config['profiles'][active]
437
-
438
- print("\n" + "=" * 60)
439
- print("CURRENT ACTIVE PROFILE")
440
- print("=" * 60)
441
- print(f"\nProfile: {active}")
442
- print(f"Description: {info.get('description', 'N/A')}")
443
- print(f"Created: {info.get('created_at', 'N/A')}")
444
- print(f"Last used: {info.get('last_used', 'N/A')}")
445
-
446
- count = self._get_memory_count(active)
447
- print(f"\nMemories in this profile: {count}")
448
-
449
- # Show total memories across all profiles
450
- if self.db_path.exists():
451
- conn = sqlite3.connect(self.db_path)
452
- try:
453
- cursor = conn.cursor()
454
- cursor.execute("SELECT COUNT(*) FROM memories")
455
- total = cursor.fetchone()[0]
456
- finally:
457
- conn.close()
458
- print(f"Total memories (all profiles): {total}")
459
- else:
460
- print(f"Warning: Current profile '{active}' not found in config")
461
- print("Resetting to 'default' profile...")
462
- self.config['active_profile'] = 'default'
463
- self._save_config()
464
-
465
- def rename_profile(self, old_name, new_name):
466
- """Rename a profile. Updates the column value in all memories."""
467
- if old_name not in self.config['profiles']:
468
- print(f"Error: Profile '{old_name}' not found")
469
- return False
470
-
471
- if new_name in self.config['profiles']:
472
- print(f"Error: Profile '{new_name}' already exists")
473
- return False
474
-
475
- if old_name == 'default':
476
- print(f"Error: Cannot rename 'default' profile")
477
- return False
478
-
479
- self._validate_profile_name(new_name)
480
-
481
- # Update profile column in all memories
482
- if self.db_path.exists():
483
- conn = sqlite3.connect(self.db_path)
484
- try:
485
- cursor = conn.cursor()
486
- cursor.execute("UPDATE memories SET profile = ? WHERE profile = ?", (new_name, old_name))
487
- updated = cursor.rowcount
488
- conn.commit()
489
- finally:
490
- conn.close()
491
- print(f" Updated {updated} memories")
492
-
493
- # Update config
494
- self.config['profiles'][new_name] = self.config['profiles'][old_name]
495
- self.config['profiles'][new_name]['name'] = new_name
496
- del self.config['profiles'][old_name]
497
-
498
- if self.config.get('active_profile') == old_name:
499
- self.config['active_profile'] = new_name
500
-
501
- self._save_config()
502
-
503
- print(f"Profile renamed: '{old_name}' -> '{new_name}'")
504
- return True
505
-
506
-
507
-
508
- def main():
509
- parser = argparse.ArgumentParser(
510
- description='SuperLocalMemory V2 - Profile Management (Column-Based)',
511
- formatter_class=argparse.RawDescriptionHelpFormatter,
512
- epilog='''
513
- Examples:
514
- # List all profiles
515
- python memory-profiles.py list
516
-
517
- # Show current profile
518
- python memory-profiles.py current
519
-
520
- # Create new empty profile
521
- python memory-profiles.py create work --description "Work projects"
522
-
523
- # Create profile from current memories
524
- python memory-profiles.py create personal --from-current
525
-
526
- # Switch to different profile (instant, no restart needed)
527
- python memory-profiles.py switch work
528
-
529
- # Delete a profile (memories moved to default)
530
- python memory-profiles.py delete old-profile
531
-
532
- # Rename profile
533
- python memory-profiles.py rename old-name new-name
534
-
535
- Architecture (v2.4.0):
536
- All profiles share ONE database (memory.db).
537
- Each memory has a 'profile' column.
538
- Switching profiles = changing config. Instant. Safe.
539
- '''
540
- )
541
-
542
- parser.add_argument('command',
543
- choices=['list', 'current', 'create', 'switch', 'delete', 'rename'],
544
- help='Profile command')
545
- parser.add_argument('name', nargs='?', help='Profile name')
546
- parser.add_argument('name2', nargs='?', help='Second name (for rename)')
547
- parser.add_argument('--description', help='Profile description')
548
- parser.add_argument('--from-current', action='store_true',
549
- help='Create from current profile memories')
550
- parser.add_argument('--force', action='store_true',
551
- help='Force operation without confirmation')
552
-
553
- args = parser.parse_args()
554
-
555
- manager = ProfileManager()
556
-
557
- if args.command == 'list':
558
- manager.list_profiles()
559
-
560
- elif args.command == 'current':
561
- manager.show_current()
562
-
563
- elif args.command == 'create':
564
- if not args.name:
565
- print("Error: Profile name required")
566
- print(" Usage: python memory-profiles.py create <name>")
567
- sys.exit(1)
568
-
569
- manager.create_profile(args.name, args.description, args.from_current)
570
-
571
- elif args.command == 'switch':
572
- if not args.name:
573
- print("Error: Profile name required")
574
- sys.exit(1)
575
-
576
- manager.switch_profile(args.name)
577
-
578
- elif args.command == 'delete':
579
- if not args.name:
580
- print("Error: Profile name required")
581
- sys.exit(1)
582
-
583
- manager.delete_profile(args.name, args.force)
584
-
585
- elif args.command == 'rename':
586
- if not args.name or not args.name2:
587
- print("Error: Both old and new names required")
588
- print(" Usage: python memory-profiles.py rename <old> <new>")
589
- sys.exit(1)
590
-
591
- manager.rename_profile(args.name, args.name2)
592
-
593
-
594
- if __name__ == '__main__':
595
- main()