empathy-framework 4.6.6__py3-none-any.whl → 4.7.1__py3-none-any.whl

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 (273) hide show
  1. empathy_framework-4.7.1.dist-info/METADATA +690 -0
  2. empathy_framework-4.7.1.dist-info/RECORD +379 -0
  3. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/top_level.txt +1 -2
  4. empathy_healthcare_plugin/monitors/monitoring/__init__.py +9 -9
  5. empathy_llm_toolkit/agent_factory/__init__.py +6 -6
  6. empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +7 -10
  7. empathy_llm_toolkit/agents_md/__init__.py +22 -0
  8. empathy_llm_toolkit/agents_md/loader.py +218 -0
  9. empathy_llm_toolkit/agents_md/parser.py +271 -0
  10. empathy_llm_toolkit/agents_md/registry.py +307 -0
  11. empathy_llm_toolkit/commands/__init__.py +51 -0
  12. empathy_llm_toolkit/commands/context.py +375 -0
  13. empathy_llm_toolkit/commands/loader.py +301 -0
  14. empathy_llm_toolkit/commands/models.py +231 -0
  15. empathy_llm_toolkit/commands/parser.py +371 -0
  16. empathy_llm_toolkit/commands/registry.py +429 -0
  17. empathy_llm_toolkit/config/__init__.py +8 -8
  18. empathy_llm_toolkit/config/unified.py +3 -7
  19. empathy_llm_toolkit/context/__init__.py +22 -0
  20. empathy_llm_toolkit/context/compaction.py +455 -0
  21. empathy_llm_toolkit/context/manager.py +434 -0
  22. empathy_llm_toolkit/hooks/__init__.py +24 -0
  23. empathy_llm_toolkit/hooks/config.py +306 -0
  24. empathy_llm_toolkit/hooks/executor.py +289 -0
  25. empathy_llm_toolkit/hooks/registry.py +302 -0
  26. empathy_llm_toolkit/hooks/scripts/__init__.py +39 -0
  27. empathy_llm_toolkit/hooks/scripts/evaluate_session.py +201 -0
  28. empathy_llm_toolkit/hooks/scripts/first_time_init.py +285 -0
  29. empathy_llm_toolkit/hooks/scripts/pre_compact.py +207 -0
  30. empathy_llm_toolkit/hooks/scripts/session_end.py +183 -0
  31. empathy_llm_toolkit/hooks/scripts/session_start.py +163 -0
  32. empathy_llm_toolkit/hooks/scripts/suggest_compact.py +225 -0
  33. empathy_llm_toolkit/learning/__init__.py +30 -0
  34. empathy_llm_toolkit/learning/evaluator.py +438 -0
  35. empathy_llm_toolkit/learning/extractor.py +514 -0
  36. empathy_llm_toolkit/learning/storage.py +560 -0
  37. empathy_llm_toolkit/providers.py +4 -11
  38. empathy_llm_toolkit/security/__init__.py +17 -17
  39. empathy_llm_toolkit/utils/tokens.py +2 -5
  40. empathy_os/__init__.py +202 -70
  41. empathy_os/cache_monitor.py +5 -3
  42. empathy_os/cli/__init__.py +11 -55
  43. empathy_os/cli/__main__.py +29 -15
  44. empathy_os/cli/commands/inspection.py +21 -12
  45. empathy_os/cli/commands/memory.py +4 -12
  46. empathy_os/cli/commands/profiling.py +198 -0
  47. empathy_os/cli/commands/utilities.py +27 -7
  48. empathy_os/cli.py +28 -57
  49. empathy_os/cli_unified.py +525 -1164
  50. empathy_os/cost_tracker.py +9 -3
  51. empathy_os/dashboard/server.py +200 -2
  52. empathy_os/hot_reload/__init__.py +7 -7
  53. empathy_os/hot_reload/config.py +6 -7
  54. empathy_os/hot_reload/integration.py +35 -35
  55. empathy_os/hot_reload/reloader.py +57 -57
  56. empathy_os/hot_reload/watcher.py +28 -28
  57. empathy_os/hot_reload/websocket.py +2 -2
  58. empathy_os/memory/__init__.py +11 -4
  59. empathy_os/memory/claude_memory.py +1 -1
  60. empathy_os/memory/cross_session.py +8 -12
  61. empathy_os/memory/edges.py +6 -6
  62. empathy_os/memory/file_session.py +770 -0
  63. empathy_os/memory/graph.py +30 -30
  64. empathy_os/memory/nodes.py +6 -6
  65. empathy_os/memory/short_term.py +15 -9
  66. empathy_os/memory/unified.py +606 -140
  67. empathy_os/meta_workflows/agent_creator.py +3 -9
  68. empathy_os/meta_workflows/cli_meta_workflows.py +113 -53
  69. empathy_os/meta_workflows/form_engine.py +6 -18
  70. empathy_os/meta_workflows/intent_detector.py +64 -24
  71. empathy_os/meta_workflows/models.py +3 -1
  72. empathy_os/meta_workflows/pattern_learner.py +13 -31
  73. empathy_os/meta_workflows/plan_generator.py +55 -47
  74. empathy_os/meta_workflows/session_context.py +2 -3
  75. empathy_os/meta_workflows/workflow.py +20 -51
  76. empathy_os/models/cli.py +2 -2
  77. empathy_os/models/tasks.py +1 -2
  78. empathy_os/models/telemetry.py +4 -1
  79. empathy_os/models/token_estimator.py +3 -1
  80. empathy_os/monitoring/alerts.py +938 -9
  81. empathy_os/monitoring/alerts_cli.py +346 -183
  82. empathy_os/orchestration/execution_strategies.py +12 -29
  83. empathy_os/orchestration/pattern_learner.py +20 -26
  84. empathy_os/orchestration/real_tools.py +6 -15
  85. empathy_os/platform_utils.py +2 -1
  86. empathy_os/plugins/__init__.py +2 -2
  87. empathy_os/plugins/base.py +64 -64
  88. empathy_os/plugins/registry.py +32 -32
  89. empathy_os/project_index/index.py +49 -15
  90. empathy_os/project_index/models.py +1 -2
  91. empathy_os/project_index/reports.py +1 -1
  92. empathy_os/project_index/scanner.py +1 -0
  93. empathy_os/redis_memory.py +10 -7
  94. empathy_os/resilience/__init__.py +1 -1
  95. empathy_os/resilience/health.py +10 -10
  96. empathy_os/routing/__init__.py +7 -7
  97. empathy_os/routing/chain_executor.py +37 -37
  98. empathy_os/routing/classifier.py +36 -36
  99. empathy_os/routing/smart_router.py +40 -40
  100. empathy_os/routing/{wizard_registry.py → workflow_registry.py} +47 -47
  101. empathy_os/scaffolding/__init__.py +8 -8
  102. empathy_os/scaffolding/__main__.py +1 -1
  103. empathy_os/scaffolding/cli.py +28 -28
  104. empathy_os/socratic/__init__.py +3 -19
  105. empathy_os/socratic/ab_testing.py +25 -36
  106. empathy_os/socratic/blueprint.py +38 -38
  107. empathy_os/socratic/cli.py +34 -20
  108. empathy_os/socratic/collaboration.py +30 -28
  109. empathy_os/socratic/domain_templates.py +9 -1
  110. empathy_os/socratic/embeddings.py +17 -13
  111. empathy_os/socratic/engine.py +135 -70
  112. empathy_os/socratic/explainer.py +70 -60
  113. empathy_os/socratic/feedback.py +24 -19
  114. empathy_os/socratic/forms.py +15 -10
  115. empathy_os/socratic/generator.py +51 -35
  116. empathy_os/socratic/llm_analyzer.py +25 -23
  117. empathy_os/socratic/mcp_server.py +99 -159
  118. empathy_os/socratic/session.py +19 -13
  119. empathy_os/socratic/storage.py +98 -67
  120. empathy_os/socratic/success.py +38 -27
  121. empathy_os/socratic/visual_editor.py +51 -39
  122. empathy_os/socratic/web_ui.py +99 -66
  123. empathy_os/telemetry/cli.py +3 -1
  124. empathy_os/telemetry/usage_tracker.py +1 -3
  125. empathy_os/test_generator/__init__.py +3 -3
  126. empathy_os/test_generator/cli.py +28 -28
  127. empathy_os/test_generator/generator.py +64 -66
  128. empathy_os/test_generator/risk_analyzer.py +11 -11
  129. empathy_os/vscode_bridge 2.py +173 -0
  130. empathy_os/vscode_bridge.py +173 -0
  131. empathy_os/workflows/__init__.py +212 -120
  132. empathy_os/workflows/batch_processing.py +8 -24
  133. empathy_os/workflows/bug_predict.py +1 -1
  134. empathy_os/workflows/code_review.py +20 -5
  135. empathy_os/workflows/code_review_pipeline.py +13 -8
  136. empathy_os/workflows/keyboard_shortcuts/workflow.py +6 -2
  137. empathy_os/workflows/manage_documentation.py +1 -0
  138. empathy_os/workflows/orchestrated_health_check.py +6 -11
  139. empathy_os/workflows/orchestrated_release_prep.py +3 -3
  140. empathy_os/workflows/pr_review.py +18 -10
  141. empathy_os/workflows/progressive/README 2.md +454 -0
  142. empathy_os/workflows/progressive/__init__ 2.py +92 -0
  143. empathy_os/workflows/progressive/__init__.py +2 -12
  144. empathy_os/workflows/progressive/cli 2.py +242 -0
  145. empathy_os/workflows/progressive/cli.py +14 -37
  146. empathy_os/workflows/progressive/core 2.py +488 -0
  147. empathy_os/workflows/progressive/core.py +12 -12
  148. empathy_os/workflows/progressive/orchestrator 2.py +701 -0
  149. empathy_os/workflows/progressive/orchestrator.py +166 -144
  150. empathy_os/workflows/progressive/reports 2.py +528 -0
  151. empathy_os/workflows/progressive/reports.py +22 -31
  152. empathy_os/workflows/progressive/telemetry 2.py +280 -0
  153. empathy_os/workflows/progressive/telemetry.py +8 -14
  154. empathy_os/workflows/progressive/test_gen 2.py +514 -0
  155. empathy_os/workflows/progressive/test_gen.py +29 -48
  156. empathy_os/workflows/progressive/workflow 2.py +628 -0
  157. empathy_os/workflows/progressive/workflow.py +31 -70
  158. empathy_os/workflows/release_prep.py +21 -6
  159. empathy_os/workflows/release_prep_crew.py +1 -0
  160. empathy_os/workflows/secure_release.py +13 -6
  161. empathy_os/workflows/security_audit.py +8 -3
  162. empathy_os/workflows/test_coverage_boost_crew.py +3 -2
  163. empathy_os/workflows/test_maintenance_crew.py +1 -0
  164. empathy_os/workflows/test_runner.py +16 -12
  165. empathy_software_plugin/SOFTWARE_PLUGIN_README.md +25 -703
  166. empathy_software_plugin/cli.py +0 -122
  167. patterns/README.md +119 -0
  168. patterns/__init__.py +95 -0
  169. patterns/behavior.py +298 -0
  170. patterns/code_review_memory.json +441 -0
  171. patterns/core.py +97 -0
  172. patterns/debugging.json +3763 -0
  173. patterns/empathy.py +268 -0
  174. patterns/health_check_memory.json +505 -0
  175. patterns/input.py +161 -0
  176. patterns/memory_graph.json +8 -0
  177. patterns/refactoring_memory.json +1113 -0
  178. patterns/registry.py +663 -0
  179. patterns/security_memory.json +8 -0
  180. patterns/structural.py +415 -0
  181. patterns/validation.py +194 -0
  182. coach_wizards/__init__.py +0 -45
  183. coach_wizards/accessibility_wizard.py +0 -91
  184. coach_wizards/api_wizard.py +0 -91
  185. coach_wizards/base_wizard.py +0 -209
  186. coach_wizards/cicd_wizard.py +0 -91
  187. coach_wizards/code_reviewer_README.md +0 -60
  188. coach_wizards/code_reviewer_wizard.py +0 -180
  189. coach_wizards/compliance_wizard.py +0 -91
  190. coach_wizards/database_wizard.py +0 -91
  191. coach_wizards/debugging_wizard.py +0 -91
  192. coach_wizards/documentation_wizard.py +0 -91
  193. coach_wizards/generate_wizards.py +0 -347
  194. coach_wizards/localization_wizard.py +0 -173
  195. coach_wizards/migration_wizard.py +0 -91
  196. coach_wizards/monitoring_wizard.py +0 -91
  197. coach_wizards/observability_wizard.py +0 -91
  198. coach_wizards/performance_wizard.py +0 -91
  199. coach_wizards/prompt_engineering_wizard.py +0 -661
  200. coach_wizards/refactoring_wizard.py +0 -91
  201. coach_wizards/scaling_wizard.py +0 -90
  202. coach_wizards/security_wizard.py +0 -92
  203. coach_wizards/testing_wizard.py +0 -91
  204. empathy_framework-4.6.6.dist-info/METADATA +0 -1597
  205. empathy_framework-4.6.6.dist-info/RECORD +0 -410
  206. empathy_llm_toolkit/wizards/__init__.py +0 -43
  207. empathy_llm_toolkit/wizards/base_wizard.py +0 -364
  208. empathy_llm_toolkit/wizards/customer_support_wizard.py +0 -190
  209. empathy_llm_toolkit/wizards/healthcare_wizard.py +0 -378
  210. empathy_llm_toolkit/wizards/patient_assessment_README.md +0 -64
  211. empathy_llm_toolkit/wizards/patient_assessment_wizard.py +0 -193
  212. empathy_llm_toolkit/wizards/technology_wizard.py +0 -209
  213. empathy_os/wizard_factory_cli.py +0 -170
  214. empathy_software_plugin/wizards/__init__.py +0 -42
  215. empathy_software_plugin/wizards/advanced_debugging_wizard.py +0 -395
  216. empathy_software_plugin/wizards/agent_orchestration_wizard.py +0 -511
  217. empathy_software_plugin/wizards/ai_collaboration_wizard.py +0 -503
  218. empathy_software_plugin/wizards/ai_context_wizard.py +0 -441
  219. empathy_software_plugin/wizards/ai_documentation_wizard.py +0 -503
  220. empathy_software_plugin/wizards/base_wizard.py +0 -288
  221. empathy_software_plugin/wizards/book_chapter_wizard.py +0 -519
  222. empathy_software_plugin/wizards/code_review_wizard.py +0 -604
  223. empathy_software_plugin/wizards/debugging/__init__.py +0 -50
  224. empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +0 -414
  225. empathy_software_plugin/wizards/debugging/config_loaders.py +0 -446
  226. empathy_software_plugin/wizards/debugging/fix_applier.py +0 -469
  227. empathy_software_plugin/wizards/debugging/language_patterns.py +0 -385
  228. empathy_software_plugin/wizards/debugging/linter_parsers.py +0 -470
  229. empathy_software_plugin/wizards/debugging/verification.py +0 -369
  230. empathy_software_plugin/wizards/enhanced_testing_wizard.py +0 -537
  231. empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +0 -816
  232. empathy_software_plugin/wizards/multi_model_wizard.py +0 -501
  233. empathy_software_plugin/wizards/pattern_extraction_wizard.py +0 -422
  234. empathy_software_plugin/wizards/pattern_retriever_wizard.py +0 -400
  235. empathy_software_plugin/wizards/performance/__init__.py +0 -9
  236. empathy_software_plugin/wizards/performance/bottleneck_detector.py +0 -221
  237. empathy_software_plugin/wizards/performance/profiler_parsers.py +0 -278
  238. empathy_software_plugin/wizards/performance/trajectory_analyzer.py +0 -429
  239. empathy_software_plugin/wizards/performance_profiling_wizard.py +0 -305
  240. empathy_software_plugin/wizards/prompt_engineering_wizard.py +0 -425
  241. empathy_software_plugin/wizards/rag_pattern_wizard.py +0 -461
  242. empathy_software_plugin/wizards/security/__init__.py +0 -32
  243. empathy_software_plugin/wizards/security/exploit_analyzer.py +0 -290
  244. empathy_software_plugin/wizards/security/owasp_patterns.py +0 -241
  245. empathy_software_plugin/wizards/security/vulnerability_scanner.py +0 -604
  246. empathy_software_plugin/wizards/security_analysis_wizard.py +0 -322
  247. empathy_software_plugin/wizards/security_learning_wizard.py +0 -740
  248. empathy_software_plugin/wizards/tech_debt_wizard.py +0 -726
  249. empathy_software_plugin/wizards/testing/__init__.py +0 -27
  250. empathy_software_plugin/wizards/testing/coverage_analyzer.py +0 -459
  251. empathy_software_plugin/wizards/testing/quality_analyzer.py +0 -525
  252. empathy_software_plugin/wizards/testing/test_suggester.py +0 -533
  253. empathy_software_plugin/wizards/testing_wizard.py +0 -274
  254. wizards/__init__.py +0 -82
  255. wizards/admission_assessment_wizard.py +0 -644
  256. wizards/care_plan.py +0 -321
  257. wizards/clinical_assessment.py +0 -769
  258. wizards/discharge_planning.py +0 -77
  259. wizards/discharge_summary_wizard.py +0 -468
  260. wizards/dosage_calculation.py +0 -497
  261. wizards/incident_report_wizard.py +0 -454
  262. wizards/medication_reconciliation.py +0 -85
  263. wizards/nursing_assessment.py +0 -171
  264. wizards/patient_education.py +0 -654
  265. wizards/quality_improvement.py +0 -705
  266. wizards/sbar_report.py +0 -324
  267. wizards/sbar_wizard.py +0 -608
  268. wizards/shift_handoff_wizard.py +0 -535
  269. wizards/soap_note_wizard.py +0 -679
  270. wizards/treatment_plan.py +0 -15
  271. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/WHEEL +0 -0
  272. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/entry_points.txt +0 -0
  273. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,429 @@
1
+ """Command Registry
2
+
3
+ Central registry for managing available commands.
4
+
5
+ Architectural patterns inspired by everything-claude-code by Affaan Mustafa.
6
+ See: https://github.com/affaan-m/everything-claude-code (MIT License)
7
+ See: ACKNOWLEDGMENTS.md for full attribution.
8
+
9
+ Copyright 2025 Smart AI Memory, LLC
10
+ Licensed under Fair Source 0.9
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import logging
16
+ from collections.abc import Iterator
17
+ from pathlib import Path
18
+ from typing import Any
19
+
20
+ from empathy_llm_toolkit.commands.loader import CommandLoader, get_default_commands_directory
21
+ from empathy_llm_toolkit.commands.models import CommandCategory, CommandConfig
22
+
23
+ logger = logging.getLogger(__name__)
24
+
25
+
26
+ class CommandRegistry:
27
+ """Central registry for command configurations.
28
+
29
+ Provides a single point of access for all available commands,
30
+ supporting both programmatic registration and directory loading.
31
+ Includes alias resolution for flexible command invocation.
32
+
33
+ Example:
34
+ # Create registry and load commands
35
+ registry = CommandRegistry()
36
+ registry.load_from_directory(".claude/commands/")
37
+
38
+ # Get a command by name
39
+ commit = registry.get("commit")
40
+
41
+ # Get by alias
42
+ compact = registry.get("comp") # Resolves alias
43
+
44
+ # Register a custom command
45
+ registry.register(my_custom_config)
46
+
47
+ # List all available commands
48
+ for name in registry.list_commands():
49
+ print(name)
50
+ """
51
+
52
+ _instance: CommandRegistry | None = None
53
+
54
+ def __init__(self):
55
+ """Initialize the registry."""
56
+ self._commands: dict[str, CommandConfig] = {}
57
+ self._aliases: dict[str, str] = {} # alias -> command name
58
+ self._loader: CommandLoader = CommandLoader()
59
+ self._load_paths: list[Path] = []
60
+
61
+ @classmethod
62
+ def get_instance(cls) -> CommandRegistry:
63
+ """Get the singleton registry instance.
64
+
65
+ Returns:
66
+ The global CommandRegistry instance
67
+
68
+ """
69
+ if cls._instance is None:
70
+ cls._instance = cls()
71
+ return cls._instance
72
+
73
+ @classmethod
74
+ def reset_instance(cls) -> None:
75
+ """Reset the singleton instance (mainly for testing)."""
76
+ cls._instance = None
77
+
78
+ def register(
79
+ self,
80
+ config: CommandConfig,
81
+ overwrite: bool = False,
82
+ ) -> None:
83
+ """Register a command configuration.
84
+
85
+ Args:
86
+ config: Command configuration to register
87
+ overwrite: If True, overwrite existing command with same name
88
+
89
+ Raises:
90
+ ValueError: If command name already exists and overwrite=False
91
+
92
+ """
93
+ if config.name in self._commands and not overwrite:
94
+ raise ValueError(
95
+ f"Command '{config.name}' already registered. Use overwrite=True to replace."
96
+ )
97
+
98
+ self._commands[config.name] = config
99
+
100
+ # Register aliases
101
+ for alias in config.aliases:
102
+ if alias in self._aliases and not overwrite:
103
+ logger.warning(
104
+ "Alias '%s' already registered for '%s', skipping",
105
+ alias,
106
+ self._aliases[alias],
107
+ )
108
+ continue
109
+ self._aliases[alias] = config.name
110
+
111
+ logger.debug("Registered command: %s", config.name)
112
+
113
+ def unregister(self, name: str) -> bool:
114
+ """Unregister a command by name.
115
+
116
+ Args:
117
+ name: Command name to remove
118
+
119
+ Returns:
120
+ True if command was found and removed
121
+
122
+ """
123
+ if name in self._commands:
124
+ config = self._commands[name]
125
+
126
+ # Remove aliases
127
+ for alias in config.aliases:
128
+ if self._aliases.get(alias) == name:
129
+ del self._aliases[alias]
130
+
131
+ del self._commands[name]
132
+ logger.debug("Unregistered command: %s", name)
133
+ return True
134
+ return False
135
+
136
+ def get(self, name: str) -> CommandConfig | None:
137
+ """Get a command configuration by name or alias.
138
+
139
+ Args:
140
+ name: Command name or alias
141
+
142
+ Returns:
143
+ Command config or None if not found
144
+
145
+ """
146
+ # Direct lookup
147
+ if name in self._commands:
148
+ return self._commands[name]
149
+
150
+ # Alias lookup
151
+ if name in self._aliases:
152
+ return self._commands.get(self._aliases[name])
153
+
154
+ return None
155
+
156
+ def get_required(self, name: str) -> CommandConfig:
157
+ """Get a command configuration, raising if not found.
158
+
159
+ Args:
160
+ name: Command name or alias
161
+
162
+ Returns:
163
+ Command configuration
164
+
165
+ Raises:
166
+ KeyError: If command not found
167
+
168
+ """
169
+ config = self.get(name)
170
+ if config is None:
171
+ available = ", ".join(sorted(self._commands.keys()))
172
+ raise KeyError(f"Command '{name}' not found. Available commands: {available}")
173
+ return config
174
+
175
+ def has(self, name: str) -> bool:
176
+ """Check if a command is registered.
177
+
178
+ Args:
179
+ name: Command name or alias
180
+
181
+ Returns:
182
+ True if command exists
183
+
184
+ """
185
+ return name in self._commands or name in self._aliases
186
+
187
+ def resolve_alias(self, name: str) -> str:
188
+ """Resolve an alias to command name.
189
+
190
+ Args:
191
+ name: Name or alias
192
+
193
+ Returns:
194
+ Resolved command name
195
+
196
+ """
197
+ return self._aliases.get(name, name)
198
+
199
+ def list_commands(self) -> list[str]:
200
+ """Get list of all registered command names.
201
+
202
+ Returns:
203
+ Sorted list of command names
204
+
205
+ """
206
+ return sorted(self._commands.keys())
207
+
208
+ def list_aliases(self) -> dict[str, str]:
209
+ """Get all registered aliases.
210
+
211
+ Returns:
212
+ Dictionary mapping aliases to command names
213
+
214
+ """
215
+ return dict(self._aliases)
216
+
217
+ def iter_commands(self) -> Iterator[CommandConfig]:
218
+ """Iterate over all registered commands.
219
+
220
+ Yields:
221
+ Command configurations
222
+
223
+ """
224
+ for name in sorted(self._commands.keys()):
225
+ yield self._commands[name]
226
+
227
+ def load_from_directory(
228
+ self,
229
+ directory: str | Path,
230
+ recursive: bool = False,
231
+ overwrite: bool = False,
232
+ ) -> int:
233
+ """Load commands from a directory.
234
+
235
+ Args:
236
+ directory: Directory containing .md command files
237
+ recursive: If True, scan subdirectories
238
+ overwrite: If True, overwrite existing commands
239
+
240
+ Returns:
241
+ Number of commands loaded
242
+
243
+ """
244
+ directory = Path(directory)
245
+ # Track loaded paths for reload (avoid duplicates)
246
+ if directory not in self._load_paths:
247
+ self._load_paths.append(directory)
248
+
249
+ commands = self._loader.load_directory(directory, recursive=recursive)
250
+
251
+ loaded = 0
252
+ for _name, config in commands.items():
253
+ try:
254
+ self.register(config, overwrite=overwrite)
255
+ loaded += 1
256
+ except ValueError as e:
257
+ logger.warning("Skipping command: %s", e)
258
+
259
+ logger.info("Loaded %d command(s) from %s", loaded, directory)
260
+ return loaded
261
+
262
+ def load_from_file(
263
+ self,
264
+ file_path: str | Path,
265
+ overwrite: bool = False,
266
+ ) -> CommandConfig:
267
+ """Load a single command from a file.
268
+
269
+ Args:
270
+ file_path: Path to command markdown file
271
+ overwrite: If True, overwrite existing command
272
+
273
+ Returns:
274
+ Loaded command configuration
275
+
276
+ """
277
+ config = self._loader.load(file_path)
278
+ self.register(config, overwrite=overwrite)
279
+ return config
280
+
281
+ def load_default_commands(self, overwrite: bool = False) -> int:
282
+ """Load commands from default directory.
283
+
284
+ Args:
285
+ overwrite: If True, overwrite existing commands
286
+
287
+ Returns:
288
+ Number of commands loaded
289
+
290
+ """
291
+ default_dir = get_default_commands_directory()
292
+
293
+ if not default_dir.exists():
294
+ logger.info("Default commands directory not found: %s", default_dir)
295
+ return 0
296
+
297
+ return self.load_from_directory(default_dir, overwrite=overwrite)
298
+
299
+ def reload(self) -> int:
300
+ """Reload all commands from previously loaded directories.
301
+
302
+ Returns:
303
+ Total number of commands after reload
304
+
305
+ """
306
+ self._commands.clear()
307
+ self._aliases.clear()
308
+
309
+ # Copy _load_paths and clear it to avoid duplicates when load_from_directory appends
310
+ paths_to_reload = list(self._load_paths)
311
+ self._load_paths.clear()
312
+
313
+ for directory in paths_to_reload:
314
+ if directory.exists():
315
+ self.load_from_directory(directory, overwrite=True)
316
+
317
+ return len(self._commands)
318
+
319
+ def get_by_category(self, category: CommandCategory) -> list[CommandConfig]:
320
+ """Get all commands with a specific category.
321
+
322
+ Args:
323
+ category: Category to filter by
324
+
325
+ Returns:
326
+ List of matching command configs
327
+
328
+ """
329
+ return [config for config in self._commands.values() if config.category == category]
330
+
331
+ def get_by_tag(self, tag: str) -> list[CommandConfig]:
332
+ """Get all commands with a specific tag.
333
+
334
+ Args:
335
+ tag: Tag to filter by
336
+
337
+ Returns:
338
+ List of matching command configs
339
+
340
+ """
341
+ tag = tag.lower()
342
+ return [
343
+ config
344
+ for config in self._commands.values()
345
+ if tag in [t.lower() for t in config.metadata.tags]
346
+ ]
347
+
348
+ def search(self, query: str) -> list[CommandConfig]:
349
+ """Search commands by name, description, or tags.
350
+
351
+ Args:
352
+ query: Search query
353
+
354
+ Returns:
355
+ List of matching commands
356
+
357
+ """
358
+ query = query.lower()
359
+ results: list[CommandConfig] = []
360
+
361
+ for config in self._commands.values():
362
+ if query in config.name.lower():
363
+ results.append(config)
364
+ elif query in config.description.lower():
365
+ results.append(config)
366
+ elif any(query in tag.lower() for tag in config.metadata.tags):
367
+ results.append(config)
368
+
369
+ return results
370
+
371
+ def get_summary(self) -> dict[str, Any]:
372
+ """Get a summary of registered commands.
373
+
374
+ Returns:
375
+ Summary dictionary
376
+
377
+ """
378
+ by_category: dict[str, int] = {}
379
+
380
+ for config in self._commands.values():
381
+ cat = config.category.value
382
+ by_category[cat] = by_category.get(cat, 0) + 1
383
+
384
+ return {
385
+ "total_commands": len(self._commands),
386
+ "total_aliases": len(self._aliases),
387
+ "command_names": self.list_commands(),
388
+ "by_category": by_category,
389
+ "load_paths": [str(p) for p in self._load_paths],
390
+ }
391
+
392
+ def format_help(self) -> str:
393
+ """Format help text listing all commands.
394
+
395
+ Returns:
396
+ Formatted help string
397
+
398
+ """
399
+ lines = ["# Available Commands", ""]
400
+
401
+ # Group by category
402
+ by_category: dict[CommandCategory, list[CommandConfig]] = {}
403
+ for config in self._commands.values():
404
+ cat = config.category
405
+ if cat not in by_category:
406
+ by_category[cat] = []
407
+ by_category[cat].append(config)
408
+
409
+ for category in CommandCategory:
410
+ commands = by_category.get(category, [])
411
+ if not commands:
412
+ continue
413
+
414
+ lines.append(f"## {category.value.title()}")
415
+ lines.append("")
416
+
417
+ for config in sorted(commands, key=lambda c: c.name):
418
+ lines.append(config.format_for_display())
419
+
420
+ lines.append("")
421
+
422
+ return "\n".join(lines)
423
+
424
+ def clear(self) -> None:
425
+ """Clear all registered commands."""
426
+ self._commands.clear()
427
+ self._aliases.clear()
428
+ self._load_paths.clear()
429
+ logger.debug("Cleared command registry")
@@ -7,14 +7,14 @@ Licensed under Fair Source License 0.9
7
7
  """
8
8
 
9
9
  from empathy_llm_toolkit.config.unified import (
10
- AgentOperationError,
11
- BookProductionConfig,
12
- MemDocsConfig,
13
- ModelTier,
14
- Provider,
15
- RedisConfig,
16
- UnifiedAgentConfig,
17
- WorkflowMode,
10
+ AgentOperationError,
11
+ BookProductionConfig,
12
+ MemDocsConfig,
13
+ ModelTier,
14
+ Provider,
15
+ RedisConfig,
16
+ UnifiedAgentConfig,
17
+ WorkflowMode,
18
18
  )
19
19
 
20
20
  __all__ = [
@@ -14,7 +14,7 @@ Licensed under Fair Source License 0.9
14
14
  from enum import Enum
15
15
  from typing import Any, Literal
16
16
 
17
- from pydantic import BaseModel, Field, field_validator
17
+ from pydantic import BaseModel, ConfigDict, Field, field_validator
18
18
 
19
19
 
20
20
  class ModelTier(str, Enum):
@@ -178,10 +178,7 @@ class UnifiedAgentConfig(BaseModel):
178
178
  redis_config=RedisConfig(),
179
179
  )
180
180
 
181
- class Config:
182
- """Pydantic configuration."""
183
-
184
- use_enum_values = True
181
+ model_config = ConfigDict(use_enum_values=True)
185
182
 
186
183
 
187
184
  class MemDocsConfig(BaseModel):
@@ -291,5 +288,4 @@ class WorkflowConfig(BaseModel):
291
288
  # Framework options
292
289
  framework_options: dict[str, Any] = Field(default_factory=dict)
293
290
 
294
- class Config:
295
- use_enum_values = True
291
+ model_config = ConfigDict(use_enum_values=True)
@@ -0,0 +1,22 @@
1
+ """Context Management for Empathy Framework
2
+
3
+ Strategic compaction to preserve critical state through context window resets.
4
+ Ensures trust levels, detected patterns, and session continuity survive compaction events.
5
+
6
+ Architectural patterns inspired by everything-claude-code by Affaan Mustafa.
7
+ See: https://github.com/affaan-m/everything-claude-code (MIT License)
8
+ See: ACKNOWLEDGMENTS.md for full attribution.
9
+
10
+ Copyright 2025 Smart AI Memory, LLC
11
+ Licensed under Fair Source 0.9
12
+ """
13
+
14
+ from empathy_llm_toolkit.context.compaction import CompactionStateManager, CompactState, SBARHandoff
15
+ from empathy_llm_toolkit.context.manager import ContextManager
16
+
17
+ __all__ = [
18
+ "CompactionStateManager",
19
+ "CompactState",
20
+ "ContextManager",
21
+ "SBARHandoff",
22
+ ]