empathy-framework 3.7.0__py3-none-any.whl → 3.8.0__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 (274) hide show
  1. coach_wizards/code_reviewer_README.md +60 -0
  2. coach_wizards/code_reviewer_wizard.py +180 -0
  3. {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/METADATA +148 -11
  4. empathy_framework-3.8.0.dist-info/RECORD +333 -0
  5. {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/top_level.txt +5 -1
  6. empathy_healthcare_plugin/monitors/__init__.py +9 -0
  7. empathy_healthcare_plugin/monitors/clinical_protocol_monitor.py +315 -0
  8. empathy_healthcare_plugin/monitors/monitoring/__init__.py +44 -0
  9. empathy_healthcare_plugin/monitors/monitoring/protocol_checker.py +300 -0
  10. empathy_healthcare_plugin/monitors/monitoring/protocol_loader.py +214 -0
  11. empathy_healthcare_plugin/monitors/monitoring/sensor_parsers.py +306 -0
  12. empathy_healthcare_plugin/monitors/monitoring/trajectory_analyzer.py +389 -0
  13. empathy_llm_toolkit/agent_factory/__init__.py +53 -0
  14. empathy_llm_toolkit/agent_factory/adapters/__init__.py +85 -0
  15. empathy_llm_toolkit/agent_factory/adapters/autogen_adapter.py +312 -0
  16. empathy_llm_toolkit/agent_factory/adapters/crewai_adapter.py +454 -0
  17. empathy_llm_toolkit/agent_factory/adapters/haystack_adapter.py +298 -0
  18. empathy_llm_toolkit/agent_factory/adapters/langchain_adapter.py +362 -0
  19. empathy_llm_toolkit/agent_factory/adapters/langgraph_adapter.py +333 -0
  20. empathy_llm_toolkit/agent_factory/adapters/native.py +228 -0
  21. empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +426 -0
  22. empathy_llm_toolkit/agent_factory/base.py +305 -0
  23. empathy_llm_toolkit/agent_factory/crews/__init__.py +67 -0
  24. empathy_llm_toolkit/agent_factory/crews/code_review.py +1113 -0
  25. empathy_llm_toolkit/agent_factory/crews/health_check.py +1246 -0
  26. empathy_llm_toolkit/agent_factory/crews/refactoring.py +1128 -0
  27. empathy_llm_toolkit/agent_factory/crews/security_audit.py +1018 -0
  28. empathy_llm_toolkit/agent_factory/decorators.py +286 -0
  29. empathy_llm_toolkit/agent_factory/factory.py +558 -0
  30. empathy_llm_toolkit/agent_factory/framework.py +192 -0
  31. empathy_llm_toolkit/agent_factory/memory_integration.py +324 -0
  32. empathy_llm_toolkit/agent_factory/resilient.py +320 -0
  33. empathy_llm_toolkit/cli/__init__.py +8 -0
  34. empathy_llm_toolkit/cli/sync_claude.py +487 -0
  35. empathy_llm_toolkit/code_health.py +150 -3
  36. empathy_llm_toolkit/config/__init__.py +29 -0
  37. empathy_llm_toolkit/config/unified.py +295 -0
  38. empathy_llm_toolkit/routing/__init__.py +32 -0
  39. empathy_llm_toolkit/routing/model_router.py +362 -0
  40. empathy_llm_toolkit/security/IMPLEMENTATION_SUMMARY.md +413 -0
  41. empathy_llm_toolkit/security/PHASE2_COMPLETE.md +384 -0
  42. empathy_llm_toolkit/security/PHASE2_SECRETS_DETECTOR_COMPLETE.md +271 -0
  43. empathy_llm_toolkit/security/QUICK_REFERENCE.md +316 -0
  44. empathy_llm_toolkit/security/README.md +262 -0
  45. empathy_llm_toolkit/security/__init__.py +62 -0
  46. empathy_llm_toolkit/security/audit_logger.py +929 -0
  47. empathy_llm_toolkit/security/audit_logger_example.py +152 -0
  48. empathy_llm_toolkit/security/pii_scrubber.py +640 -0
  49. empathy_llm_toolkit/security/secrets_detector.py +678 -0
  50. empathy_llm_toolkit/security/secrets_detector_example.py +304 -0
  51. empathy_llm_toolkit/security/secure_memdocs.py +1192 -0
  52. empathy_llm_toolkit/security/secure_memdocs_example.py +278 -0
  53. empathy_llm_toolkit/wizards/__init__.py +38 -0
  54. empathy_llm_toolkit/wizards/base_wizard.py +364 -0
  55. empathy_llm_toolkit/wizards/customer_support_wizard.py +190 -0
  56. empathy_llm_toolkit/wizards/healthcare_wizard.py +362 -0
  57. empathy_llm_toolkit/wizards/patient_assessment_README.md +64 -0
  58. empathy_llm_toolkit/wizards/patient_assessment_wizard.py +193 -0
  59. empathy_llm_toolkit/wizards/technology_wizard.py +194 -0
  60. empathy_os/__init__.py +52 -52
  61. empathy_os/adaptive/__init__.py +13 -0
  62. empathy_os/adaptive/task_complexity.py +127 -0
  63. empathy_os/cache/__init__.py +117 -0
  64. empathy_os/cache/base.py +166 -0
  65. empathy_os/cache/dependency_manager.py +253 -0
  66. empathy_os/cache/hash_only.py +248 -0
  67. empathy_os/cache/hybrid.py +390 -0
  68. empathy_os/cache/storage.py +282 -0
  69. empathy_os/cli.py +118 -8
  70. empathy_os/cli_unified.py +121 -1
  71. empathy_os/config/__init__.py +63 -0
  72. empathy_os/config/xml_config.py +239 -0
  73. empathy_os/config.py +2 -1
  74. empathy_os/dashboard/__init__.py +15 -0
  75. empathy_os/dashboard/server.py +743 -0
  76. empathy_os/memory/__init__.py +195 -0
  77. empathy_os/memory/claude_memory.py +466 -0
  78. empathy_os/memory/config.py +224 -0
  79. empathy_os/memory/control_panel.py +1298 -0
  80. empathy_os/memory/edges.py +179 -0
  81. empathy_os/memory/graph.py +567 -0
  82. empathy_os/memory/long_term.py +1194 -0
  83. empathy_os/memory/nodes.py +179 -0
  84. empathy_os/memory/redis_bootstrap.py +540 -0
  85. empathy_os/memory/security/__init__.py +31 -0
  86. empathy_os/memory/security/audit_logger.py +930 -0
  87. empathy_os/memory/security/pii_scrubber.py +640 -0
  88. empathy_os/memory/security/secrets_detector.py +678 -0
  89. empathy_os/memory/short_term.py +2119 -0
  90. empathy_os/memory/storage/__init__.py +15 -0
  91. empathy_os/memory/summary_index.py +583 -0
  92. empathy_os/memory/unified.py +619 -0
  93. empathy_os/metrics/__init__.py +12 -0
  94. empathy_os/metrics/prompt_metrics.py +190 -0
  95. empathy_os/models/__init__.py +136 -0
  96. empathy_os/models/__main__.py +13 -0
  97. empathy_os/models/cli.py +655 -0
  98. empathy_os/models/empathy_executor.py +354 -0
  99. empathy_os/models/executor.py +252 -0
  100. empathy_os/models/fallback.py +671 -0
  101. empathy_os/models/provider_config.py +563 -0
  102. empathy_os/models/registry.py +382 -0
  103. empathy_os/models/tasks.py +302 -0
  104. empathy_os/models/telemetry.py +548 -0
  105. empathy_os/models/token_estimator.py +378 -0
  106. empathy_os/models/validation.py +274 -0
  107. empathy_os/monitoring/__init__.py +52 -0
  108. empathy_os/monitoring/alerts.py +23 -0
  109. empathy_os/monitoring/alerts_cli.py +268 -0
  110. empathy_os/monitoring/multi_backend.py +271 -0
  111. empathy_os/monitoring/otel_backend.py +363 -0
  112. empathy_os/optimization/__init__.py +19 -0
  113. empathy_os/optimization/context_optimizer.py +272 -0
  114. empathy_os/plugins/__init__.py +28 -0
  115. empathy_os/plugins/base.py +361 -0
  116. empathy_os/plugins/registry.py +268 -0
  117. empathy_os/project_index/__init__.py +30 -0
  118. empathy_os/project_index/cli.py +335 -0
  119. empathy_os/project_index/crew_integration.py +430 -0
  120. empathy_os/project_index/index.py +425 -0
  121. empathy_os/project_index/models.py +501 -0
  122. empathy_os/project_index/reports.py +473 -0
  123. empathy_os/project_index/scanner.py +538 -0
  124. empathy_os/prompts/__init__.py +61 -0
  125. empathy_os/prompts/config.py +77 -0
  126. empathy_os/prompts/context.py +177 -0
  127. empathy_os/prompts/parser.py +285 -0
  128. empathy_os/prompts/registry.py +313 -0
  129. empathy_os/prompts/templates.py +208 -0
  130. empathy_os/resilience/__init__.py +56 -0
  131. empathy_os/resilience/circuit_breaker.py +256 -0
  132. empathy_os/resilience/fallback.py +179 -0
  133. empathy_os/resilience/health.py +300 -0
  134. empathy_os/resilience/retry.py +209 -0
  135. empathy_os/resilience/timeout.py +135 -0
  136. empathy_os/routing/__init__.py +43 -0
  137. empathy_os/routing/chain_executor.py +433 -0
  138. empathy_os/routing/classifier.py +217 -0
  139. empathy_os/routing/smart_router.py +234 -0
  140. empathy_os/routing/wizard_registry.py +307 -0
  141. empathy_os/trust/__init__.py +28 -0
  142. empathy_os/trust/circuit_breaker.py +579 -0
  143. empathy_os/validation/__init__.py +19 -0
  144. empathy_os/validation/xml_validator.py +281 -0
  145. empathy_os/wizard_factory_cli.py +170 -0
  146. empathy_os/workflows/__init__.py +360 -0
  147. empathy_os/workflows/base.py +1660 -0
  148. empathy_os/workflows/bug_predict.py +962 -0
  149. empathy_os/workflows/code_review.py +960 -0
  150. empathy_os/workflows/code_review_adapters.py +310 -0
  151. empathy_os/workflows/code_review_pipeline.py +720 -0
  152. empathy_os/workflows/config.py +600 -0
  153. empathy_os/workflows/dependency_check.py +648 -0
  154. empathy_os/workflows/document_gen.py +1069 -0
  155. empathy_os/workflows/documentation_orchestrator.py +1205 -0
  156. empathy_os/workflows/health_check.py +679 -0
  157. empathy_os/workflows/keyboard_shortcuts/__init__.py +39 -0
  158. empathy_os/workflows/keyboard_shortcuts/generators.py +386 -0
  159. empathy_os/workflows/keyboard_shortcuts/parsers.py +414 -0
  160. empathy_os/workflows/keyboard_shortcuts/prompts.py +295 -0
  161. empathy_os/workflows/keyboard_shortcuts/schema.py +193 -0
  162. empathy_os/workflows/keyboard_shortcuts/workflow.py +505 -0
  163. empathy_os/workflows/manage_documentation.py +804 -0
  164. empathy_os/workflows/new_sample_workflow1.py +146 -0
  165. empathy_os/workflows/new_sample_workflow1_README.md +150 -0
  166. empathy_os/workflows/perf_audit.py +687 -0
  167. empathy_os/workflows/pr_review.py +748 -0
  168. empathy_os/workflows/progress.py +445 -0
  169. empathy_os/workflows/progress_server.py +322 -0
  170. empathy_os/workflows/refactor_plan.py +693 -0
  171. empathy_os/workflows/release_prep.py +808 -0
  172. empathy_os/workflows/research_synthesis.py +404 -0
  173. empathy_os/workflows/secure_release.py +585 -0
  174. empathy_os/workflows/security_adapters.py +297 -0
  175. empathy_os/workflows/security_audit.py +1046 -0
  176. empathy_os/workflows/step_config.py +234 -0
  177. empathy_os/workflows/test5.py +125 -0
  178. empathy_os/workflows/test5_README.md +158 -0
  179. empathy_os/workflows/test_gen.py +1855 -0
  180. empathy_os/workflows/test_lifecycle.py +526 -0
  181. empathy_os/workflows/test_maintenance.py +626 -0
  182. empathy_os/workflows/test_maintenance_cli.py +590 -0
  183. empathy_os/workflows/test_maintenance_crew.py +821 -0
  184. empathy_os/workflows/xml_enhanced_crew.py +285 -0
  185. empathy_software_plugin/cli/__init__.py +120 -0
  186. empathy_software_plugin/cli/inspect.py +362 -0
  187. empathy_software_plugin/cli.py +3 -1
  188. empathy_software_plugin/wizards/__init__.py +42 -0
  189. empathy_software_plugin/wizards/advanced_debugging_wizard.py +392 -0
  190. empathy_software_plugin/wizards/agent_orchestration_wizard.py +511 -0
  191. empathy_software_plugin/wizards/ai_collaboration_wizard.py +503 -0
  192. empathy_software_plugin/wizards/ai_context_wizard.py +441 -0
  193. empathy_software_plugin/wizards/ai_documentation_wizard.py +503 -0
  194. empathy_software_plugin/wizards/base_wizard.py +288 -0
  195. empathy_software_plugin/wizards/book_chapter_wizard.py +519 -0
  196. empathy_software_plugin/wizards/code_review_wizard.py +606 -0
  197. empathy_software_plugin/wizards/debugging/__init__.py +50 -0
  198. empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +414 -0
  199. empathy_software_plugin/wizards/debugging/config_loaders.py +442 -0
  200. empathy_software_plugin/wizards/debugging/fix_applier.py +469 -0
  201. empathy_software_plugin/wizards/debugging/language_patterns.py +383 -0
  202. empathy_software_plugin/wizards/debugging/linter_parsers.py +470 -0
  203. empathy_software_plugin/wizards/debugging/verification.py +369 -0
  204. empathy_software_plugin/wizards/enhanced_testing_wizard.py +537 -0
  205. empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +816 -0
  206. empathy_software_plugin/wizards/multi_model_wizard.py +501 -0
  207. empathy_software_plugin/wizards/pattern_extraction_wizard.py +422 -0
  208. empathy_software_plugin/wizards/pattern_retriever_wizard.py +400 -0
  209. empathy_software_plugin/wizards/performance/__init__.py +9 -0
  210. empathy_software_plugin/wizards/performance/bottleneck_detector.py +221 -0
  211. empathy_software_plugin/wizards/performance/profiler_parsers.py +278 -0
  212. empathy_software_plugin/wizards/performance/trajectory_analyzer.py +429 -0
  213. empathy_software_plugin/wizards/performance_profiling_wizard.py +305 -0
  214. empathy_software_plugin/wizards/prompt_engineering_wizard.py +425 -0
  215. empathy_software_plugin/wizards/rag_pattern_wizard.py +461 -0
  216. empathy_software_plugin/wizards/security/__init__.py +32 -0
  217. empathy_software_plugin/wizards/security/exploit_analyzer.py +290 -0
  218. empathy_software_plugin/wizards/security/owasp_patterns.py +241 -0
  219. empathy_software_plugin/wizards/security/vulnerability_scanner.py +604 -0
  220. empathy_software_plugin/wizards/security_analysis_wizard.py +322 -0
  221. empathy_software_plugin/wizards/security_learning_wizard.py +740 -0
  222. empathy_software_plugin/wizards/tech_debt_wizard.py +726 -0
  223. empathy_software_plugin/wizards/testing/__init__.py +27 -0
  224. empathy_software_plugin/wizards/testing/coverage_analyzer.py +459 -0
  225. empathy_software_plugin/wizards/testing/quality_analyzer.py +531 -0
  226. empathy_software_plugin/wizards/testing/test_suggester.py +533 -0
  227. empathy_software_plugin/wizards/testing_wizard.py +274 -0
  228. hot_reload/README.md +473 -0
  229. hot_reload/__init__.py +62 -0
  230. hot_reload/config.py +84 -0
  231. hot_reload/integration.py +228 -0
  232. hot_reload/reloader.py +298 -0
  233. hot_reload/watcher.py +179 -0
  234. hot_reload/websocket.py +176 -0
  235. scaffolding/README.md +589 -0
  236. scaffolding/__init__.py +35 -0
  237. scaffolding/__main__.py +14 -0
  238. scaffolding/cli.py +240 -0
  239. test_generator/__init__.py +38 -0
  240. test_generator/__main__.py +14 -0
  241. test_generator/cli.py +226 -0
  242. test_generator/generator.py +325 -0
  243. test_generator/risk_analyzer.py +216 -0
  244. workflow_patterns/__init__.py +33 -0
  245. workflow_patterns/behavior.py +249 -0
  246. workflow_patterns/core.py +76 -0
  247. workflow_patterns/output.py +99 -0
  248. workflow_patterns/registry.py +255 -0
  249. workflow_patterns/structural.py +288 -0
  250. workflow_scaffolding/__init__.py +11 -0
  251. workflow_scaffolding/__main__.py +12 -0
  252. workflow_scaffolding/cli.py +206 -0
  253. workflow_scaffolding/generator.py +265 -0
  254. agents/code_inspection/patterns/inspection/recurring_B112.json +0 -18
  255. agents/code_inspection/patterns/inspection/recurring_F541.json +0 -16
  256. agents/code_inspection/patterns/inspection/recurring_FORMAT.json +0 -25
  257. agents/code_inspection/patterns/inspection/recurring_bug_20250822_def456.json +0 -16
  258. agents/code_inspection/patterns/inspection/recurring_bug_20250915_abc123.json +0 -16
  259. agents/code_inspection/patterns/inspection/recurring_bug_20251212_3c5b9951.json +0 -16
  260. agents/code_inspection/patterns/inspection/recurring_bug_20251212_97c0f72f.json +0 -16
  261. agents/code_inspection/patterns/inspection/recurring_bug_20251212_a0871d53.json +0 -16
  262. agents/code_inspection/patterns/inspection/recurring_bug_20251212_a9b6ec41.json +0 -16
  263. agents/code_inspection/patterns/inspection/recurring_bug_null_001.json +0 -16
  264. agents/code_inspection/patterns/inspection/recurring_builtin.json +0 -16
  265. agents/compliance_anticipation_agent.py +0 -1422
  266. agents/compliance_db.py +0 -339
  267. agents/epic_integration_wizard.py +0 -530
  268. agents/notifications.py +0 -291
  269. agents/trust_building_behaviors.py +0 -872
  270. empathy_framework-3.7.0.dist-info/RECORD +0 -105
  271. {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/WHEEL +0 -0
  272. {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/entry_points.txt +0 -0
  273. {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/licenses/LICENSE +0 -0
  274. /empathy_os/{monitoring.py → agent_monitoring.py} +0 -0
@@ -0,0 +1,39 @@
1
+ """Keyboard Shortcuts Workflow Package
2
+
3
+ Generates optimized keyboard shortcuts for any project following
4
+ the "Keyboard Conductor" musical scale pattern.
5
+
6
+ Features:
7
+ - Multi-source feature discovery (VSCode, Python, YAML, LLM)
8
+ - Multi-layout generation (QWERTY, Dvorak, Colemak)
9
+ - Ergonomic optimization with mnemonic phrases
10
+ - Multiple output formats (keybindings, aliases, documentation)
11
+ """
12
+
13
+ from .generators import CLIAliasGenerator, MarkdownDocGenerator, VSCodeKeybindingsGenerator
14
+ from .parsers import (
15
+ FeatureParser,
16
+ LLMFeatureAnalyzer,
17
+ PyProjectParser,
18
+ VSCodeCommandParser,
19
+ YAMLManifestParser,
20
+ )
21
+ from .schema import Category, Feature, FeatureManifest, LayoutConfig, ShortcutAssignment
22
+ from .workflow import KeyboardShortcutWorkflow
23
+
24
+ __all__ = [
25
+ "CLIAliasGenerator",
26
+ "Category",
27
+ "Feature",
28
+ "FeatureManifest",
29
+ "FeatureParser",
30
+ "KeyboardShortcutWorkflow",
31
+ "LLMFeatureAnalyzer",
32
+ "LayoutConfig",
33
+ "MarkdownDocGenerator",
34
+ "PyProjectParser",
35
+ "ShortcutAssignment",
36
+ "VSCodeCommandParser",
37
+ "VSCodeKeybindingsGenerator",
38
+ "YAMLManifestParser",
39
+ ]
@@ -0,0 +1,386 @@
1
+ """Output generators for keyboard shortcut files.
2
+
3
+ Generates:
4
+ - VSCode keybindings.json (per layout)
5
+ - Bash/Zsh alias scripts
6
+ - Markdown documentation with ASCII keyboard diagrams
7
+ """
8
+
9
+ import json
10
+ from pathlib import Path
11
+
12
+ from .schema import (
13
+ FeatureManifest,
14
+ GeneratedShortcuts,
15
+ KeyboardLayout,
16
+ LayoutShortcuts,
17
+ ShortcutAssignment,
18
+ )
19
+
20
+
21
+ class VSCodeKeybindingsGenerator:
22
+ """Generate VSCode keybindings.json files for each layout."""
23
+
24
+ def generate(
25
+ self,
26
+ shortcuts: GeneratedShortcuts,
27
+ output_dir: Path,
28
+ ) -> dict[str, Path]:
29
+ """Generate keybindings files for all layouts.
30
+
31
+ Returns dict of layout -> output file path.
32
+ """
33
+ output_dir.mkdir(parents=True, exist_ok=True)
34
+ generated_files = {}
35
+
36
+ for layout, layout_shortcuts in shortcuts.layouts.items():
37
+ output_file = output_dir / f"{layout.value}.json"
38
+ bindings = self._generate_bindings(shortcuts.manifest, layout_shortcuts)
39
+ output_file.write_text(json.dumps(bindings, indent=2))
40
+ generated_files[layout.value] = output_file
41
+
42
+ return generated_files
43
+
44
+ def _generate_bindings(
45
+ self,
46
+ manifest: FeatureManifest,
47
+ layout_shortcuts: LayoutShortcuts,
48
+ ) -> list[dict]:
49
+ """Generate VSCode keybinding entries."""
50
+ bindings = []
51
+ prefix = manifest.prefix
52
+
53
+ for shortcut in layout_shortcuts.shortcuts:
54
+ # Find the feature to get the command
55
+ command = self._find_command(manifest, shortcut.feature_id)
56
+ if not command:
57
+ continue
58
+
59
+ bindings.append(
60
+ {
61
+ "key": f"{prefix} {shortcut.key}",
62
+ "mac": f"{prefix.replace('ctrl', 'cmd')} {shortcut.key}",
63
+ "command": command,
64
+ "// mnemonic": shortcut.mnemonic,
65
+ },
66
+ )
67
+
68
+ return bindings
69
+
70
+ def _find_command(self, manifest: FeatureManifest, feature_id: str) -> str | None:
71
+ """Find command for a feature ID."""
72
+ for feature in manifest.all_features():
73
+ if feature.id == feature_id:
74
+ return feature.command
75
+ return None
76
+
77
+
78
+ class CLIAliasGenerator:
79
+ """Generate shell alias scripts for CLI commands."""
80
+
81
+ BASH_HEADER = """#!/bin/bash
82
+ # Keyboard Conductor CLI Aliases for {project_name}
83
+ # Generated by Empathy Framework
84
+ #
85
+ # Add to your .bashrc or .zshrc:
86
+ # source {output_file}
87
+ #
88
+ # Mnemonic: {mnemonic}
89
+
90
+ """
91
+
92
+ def generate(
93
+ self,
94
+ shortcuts: GeneratedShortcuts,
95
+ output_file: Path,
96
+ ) -> Path:
97
+ """Generate a shell alias script."""
98
+ output_file.parent.mkdir(parents=True, exist_ok=True)
99
+
100
+ # Use QWERTY layout for CLI (most common)
101
+ layout_shortcuts = shortcuts.layouts.get(KeyboardLayout.QWERTY)
102
+ if not layout_shortcuts:
103
+ layout_shortcuts = next(iter(shortcuts.layouts.values()), None)
104
+
105
+ if not layout_shortcuts:
106
+ output_file.write_text("# No shortcuts generated\n")
107
+ return output_file
108
+
109
+ lines = [
110
+ self.BASH_HEADER.format(
111
+ project_name=shortcuts.manifest.project_name,
112
+ output_file=output_file.name,
113
+ mnemonic=layout_shortcuts.phrase_mnemonic,
114
+ ),
115
+ ]
116
+
117
+ for shortcut in layout_shortcuts.shortcuts:
118
+ # Find the CLI alias for this feature
119
+ cli_alias = self._find_cli_alias(shortcuts.manifest, shortcut.feature_id)
120
+ if not cli_alias:
121
+ continue
122
+
123
+ # Create a short alias (e.g., "em" for empathy morning)
124
+ short_alias = f"e{shortcut.key}"
125
+ lines.append(f'alias {short_alias}="{cli_alias}" # {shortcut.mnemonic}')
126
+
127
+ output_file.write_text("\n".join(lines))
128
+ return output_file
129
+
130
+ def _find_cli_alias(self, manifest: FeatureManifest, feature_id: str) -> str | None:
131
+ """Find CLI alias for a feature ID."""
132
+ for feature in manifest.all_features():
133
+ if feature.id == feature_id and feature.cli_alias:
134
+ return feature.cli_alias
135
+ return None
136
+
137
+
138
+ class MarkdownDocGenerator:
139
+ """Generate Markdown documentation with keyboard cheatsheets."""
140
+
141
+ TEMPLATE = """# {project_name} Keyboard Shortcuts
142
+
143
+ > {phrase_mnemonic}
144
+
145
+ ## Quick Reference
146
+
147
+ Hold **{prefix}** (Mac: **{mac_prefix}**) then press one key:
148
+
149
+ {cheatsheet}
150
+
151
+ ## Keyboard Layout
152
+
153
+ ```
154
+ {keyboard_diagram}
155
+ ```
156
+
157
+ ## Scales (Learning Progression)
158
+
159
+ {scales_section}
160
+
161
+ ## All Shortcuts
162
+
163
+ {full_table}
164
+
165
+ ---
166
+
167
+ *Generated by [Empathy Framework](https://github.com/Smart-AI-Memory/empathy-framework) Keyboard Conductor*
168
+ """
169
+
170
+ KEYBOARD_DIAGRAM = """
171
+ ┌─────────────────────────────────────┐
172
+ │ [Q][W][E][R][T][Y][U][I][O][P] │
173
+ │ [{a}][{s}][{d}][{f}][G][H][J][K][L] │
174
+ │ [{z}][X][{c}][{v}][{b}][N][M] │
175
+ └─────────────────────────────────────┘
176
+ """
177
+
178
+ def generate(
179
+ self,
180
+ shortcuts: GeneratedShortcuts,
181
+ output_file: Path,
182
+ ) -> Path:
183
+ """Generate Markdown documentation."""
184
+ output_file.parent.mkdir(parents=True, exist_ok=True)
185
+
186
+ # Use QWERTY layout as default for docs
187
+ layout_shortcuts = shortcuts.layouts.get(KeyboardLayout.QWERTY)
188
+ if not layout_shortcuts:
189
+ layout_shortcuts = next(iter(shortcuts.layouts.values()), None)
190
+
191
+ if not layout_shortcuts:
192
+ output_file.write_text("# No shortcuts generated\n")
193
+ return output_file
194
+
195
+ manifest = shortcuts.manifest
196
+ prefix = manifest.prefix
197
+ mac_prefix = prefix.replace("ctrl", "cmd")
198
+
199
+ content = self.TEMPLATE.format(
200
+ project_name=manifest.project_name,
201
+ phrase_mnemonic=layout_shortcuts.phrase_mnemonic,
202
+ prefix=prefix,
203
+ mac_prefix=mac_prefix,
204
+ cheatsheet=self._generate_cheatsheet(manifest, layout_shortcuts),
205
+ keyboard_diagram=self._generate_keyboard_diagram(layout_shortcuts),
206
+ scales_section=self._generate_scales_section(manifest, layout_shortcuts),
207
+ full_table=self._generate_full_table(manifest, layout_shortcuts),
208
+ )
209
+
210
+ output_file.write_text(content)
211
+ return output_file
212
+
213
+ def _generate_cheatsheet(
214
+ self,
215
+ manifest: FeatureManifest,
216
+ layout_shortcuts: LayoutShortcuts,
217
+ ) -> str:
218
+ """Generate quick reference cheatsheet."""
219
+ lines = []
220
+
221
+ # Group by scale
222
+ scales = layout_shortcuts.scale_assignments
223
+ scale_features = {
224
+ "Daily (Start Here)": scales.daily,
225
+ "Frequent": scales.frequent,
226
+ "Advanced": scales.advanced,
227
+ }
228
+
229
+ for scale_name, keys in scale_features.items():
230
+ if not keys:
231
+ continue
232
+
233
+ lines.append(f"### {scale_name}")
234
+ for key in keys:
235
+ shortcut = self._find_shortcut_by_key(layout_shortcuts, key)
236
+ if shortcut:
237
+ feature = self._find_feature(manifest, shortcut.feature_id)
238
+ name = feature.name if feature else shortcut.feature_id
239
+ lines.append(f"- **{key.upper()}** = {name}")
240
+ lines.append("")
241
+
242
+ return "\n".join(lines)
243
+
244
+ def _generate_keyboard_diagram(self, layout_shortcuts: LayoutShortcuts) -> str:
245
+ """Generate ASCII keyboard diagram highlighting active keys."""
246
+ # Map of positions to highlight
247
+ key_positions = {}
248
+ for shortcut in layout_shortcuts.shortcuts:
249
+ key_positions[shortcut.key.lower()] = shortcut.key.upper()
250
+
251
+ # Create the diagram with highlights
252
+ diagram = self.KEYBOARD_DIAGRAM
253
+
254
+ # Replace placeholders with actual keys or defaults
255
+ replacements = {
256
+ "a": key_positions.get("a", "A"),
257
+ "s": key_positions.get("s", "S"),
258
+ "d": key_positions.get("d", "D"),
259
+ "f": key_positions.get("f", "F"),
260
+ "z": key_positions.get("z", "Z"),
261
+ "c": key_positions.get("c", "C"),
262
+ "v": key_positions.get("v", "V"),
263
+ "b": key_positions.get("b", "B"),
264
+ }
265
+
266
+ for placeholder, value in replacements.items():
267
+ diagram = diagram.replace(f"{{{placeholder}}}", value)
268
+
269
+ return diagram
270
+
271
+ def _generate_scales_section(
272
+ self,
273
+ manifest: FeatureManifest,
274
+ layout_shortcuts: LayoutShortcuts,
275
+ ) -> str:
276
+ """Generate learning progression section."""
277
+ lines = []
278
+ scales = layout_shortcuts.scale_assignments
279
+
280
+ lines.append("### Scale 1: The Basics (4 notes)")
281
+ lines.append("```")
282
+ for key in scales.daily:
283
+ shortcut = self._find_shortcut_by_key(layout_shortcuts, key)
284
+ if shortcut:
285
+ feature = self._find_feature(manifest, shortcut.feature_id)
286
+ name = feature.name if feature else shortcut.feature_id
287
+ lines.append(f"{key.upper()} = {name}")
288
+ lines.append("```")
289
+ lines.append("")
290
+
291
+ lines.append("### Scale 2: The Workflows (add 4 more)")
292
+ lines.append("```")
293
+ for key in scales.frequent:
294
+ shortcut = self._find_shortcut_by_key(layout_shortcuts, key)
295
+ if shortcut:
296
+ feature = self._find_feature(manifest, shortcut.feature_id)
297
+ name = feature.name if feature else shortcut.feature_id
298
+ lines.append(f"{key.upper()} = {name}")
299
+ lines.append("```")
300
+ lines.append("")
301
+
302
+ lines.append("### Scale 3: Full Orchestra (power users)")
303
+ lines.append("```")
304
+ for key in scales.advanced:
305
+ shortcut = self._find_shortcut_by_key(layout_shortcuts, key)
306
+ if shortcut:
307
+ feature = self._find_feature(manifest, shortcut.feature_id)
308
+ name = feature.name if feature else shortcut.feature_id
309
+ lines.append(f"{key.upper()} = {name}")
310
+ lines.append("```")
311
+
312
+ return "\n".join(lines)
313
+
314
+ def _generate_full_table(
315
+ self,
316
+ manifest: FeatureManifest,
317
+ layout_shortcuts: LayoutShortcuts,
318
+ ) -> str:
319
+ """Generate full table of all shortcuts."""
320
+ lines = [
321
+ "| Key | Command | Mnemonic |",
322
+ "|-----|---------|----------|",
323
+ ]
324
+
325
+ for shortcut in layout_shortcuts.shortcuts:
326
+ feature = self._find_feature(manifest, shortcut.feature_id)
327
+ name = feature.name if feature else shortcut.feature_id
328
+ lines.append(f"| {shortcut.key.upper()} | {name} | {shortcut.mnemonic} |")
329
+
330
+ return "\n".join(lines)
331
+
332
+ def _find_shortcut_by_key(
333
+ self,
334
+ layout_shortcuts: LayoutShortcuts,
335
+ key: str,
336
+ ) -> ShortcutAssignment | None:
337
+ """Find shortcut by key."""
338
+ for shortcut in layout_shortcuts.shortcuts:
339
+ if shortcut.key.lower() == key.lower():
340
+ return shortcut
341
+ return None
342
+
343
+ def _find_feature(self, manifest: FeatureManifest, feature_id: str):
344
+ """Find feature by ID."""
345
+ for feature in manifest.all_features():
346
+ if feature.id == feature_id:
347
+ return feature
348
+ return None
349
+
350
+
351
+ class ComprehensiveGenerator:
352
+ """Generate all output formats at once."""
353
+
354
+ def __init__(self):
355
+ self.vscode_gen = VSCodeKeybindingsGenerator()
356
+ self.cli_gen = CLIAliasGenerator()
357
+ self.markdown_gen = MarkdownDocGenerator()
358
+
359
+ def generate_all(
360
+ self,
361
+ shortcuts: GeneratedShortcuts,
362
+ output_dir: Path,
363
+ ) -> dict[str, Path]:
364
+ """Generate all output formats.
365
+
366
+ Returns dict of format -> output path(s).
367
+ """
368
+ output_dir.mkdir(parents=True, exist_ok=True)
369
+ generated = {}
370
+
371
+ # VSCode keybindings (one per layout)
372
+ keybindings_dir = output_dir / "keybindings"
373
+ vscode_files = self.vscode_gen.generate(shortcuts, keybindings_dir)
374
+ generated["vscode"] = vscode_files
375
+
376
+ # CLI aliases
377
+ aliases_file = output_dir / "aliases.sh"
378
+ self.cli_gen.generate(shortcuts, aliases_file)
379
+ generated["cli"] = aliases_file
380
+
381
+ # Markdown documentation
382
+ docs_file = output_dir / "KEYBOARD_SHORTCUTS.md"
383
+ self.markdown_gen.generate(shortcuts, docs_file)
384
+ generated["docs"] = docs_file
385
+
386
+ return generated