empathy-framework 3.7.0__py3-none-any.whl → 3.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.
- coach_wizards/code_reviewer_README.md +60 -0
- coach_wizards/code_reviewer_wizard.py +180 -0
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.7.1.dist-info}/METADATA +20 -2
- empathy_framework-3.7.1.dist-info/RECORD +327 -0
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.7.1.dist-info}/top_level.txt +5 -1
- empathy_healthcare_plugin/monitors/__init__.py +9 -0
- empathy_healthcare_plugin/monitors/clinical_protocol_monitor.py +315 -0
- empathy_healthcare_plugin/monitors/monitoring/__init__.py +44 -0
- empathy_healthcare_plugin/monitors/monitoring/protocol_checker.py +300 -0
- empathy_healthcare_plugin/monitors/monitoring/protocol_loader.py +214 -0
- empathy_healthcare_plugin/monitors/monitoring/sensor_parsers.py +306 -0
- empathy_healthcare_plugin/monitors/monitoring/trajectory_analyzer.py +389 -0
- empathy_llm_toolkit/agent_factory/__init__.py +53 -0
- empathy_llm_toolkit/agent_factory/adapters/__init__.py +85 -0
- empathy_llm_toolkit/agent_factory/adapters/autogen_adapter.py +312 -0
- empathy_llm_toolkit/agent_factory/adapters/crewai_adapter.py +454 -0
- empathy_llm_toolkit/agent_factory/adapters/haystack_adapter.py +298 -0
- empathy_llm_toolkit/agent_factory/adapters/langchain_adapter.py +362 -0
- empathy_llm_toolkit/agent_factory/adapters/langgraph_adapter.py +333 -0
- empathy_llm_toolkit/agent_factory/adapters/native.py +228 -0
- empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +426 -0
- empathy_llm_toolkit/agent_factory/base.py +305 -0
- empathy_llm_toolkit/agent_factory/crews/__init__.py +67 -0
- empathy_llm_toolkit/agent_factory/crews/code_review.py +1113 -0
- empathy_llm_toolkit/agent_factory/crews/health_check.py +1246 -0
- empathy_llm_toolkit/agent_factory/crews/refactoring.py +1128 -0
- empathy_llm_toolkit/agent_factory/crews/security_audit.py +1018 -0
- empathy_llm_toolkit/agent_factory/decorators.py +286 -0
- empathy_llm_toolkit/agent_factory/factory.py +558 -0
- empathy_llm_toolkit/agent_factory/framework.py +192 -0
- empathy_llm_toolkit/agent_factory/memory_integration.py +324 -0
- empathy_llm_toolkit/agent_factory/resilient.py +320 -0
- empathy_llm_toolkit/cli/__init__.py +8 -0
- empathy_llm_toolkit/cli/sync_claude.py +487 -0
- empathy_llm_toolkit/code_health.py +150 -3
- empathy_llm_toolkit/config/__init__.py +29 -0
- empathy_llm_toolkit/config/unified.py +295 -0
- empathy_llm_toolkit/routing/__init__.py +32 -0
- empathy_llm_toolkit/routing/model_router.py +362 -0
- empathy_llm_toolkit/security/IMPLEMENTATION_SUMMARY.md +413 -0
- empathy_llm_toolkit/security/PHASE2_COMPLETE.md +384 -0
- empathy_llm_toolkit/security/PHASE2_SECRETS_DETECTOR_COMPLETE.md +271 -0
- empathy_llm_toolkit/security/QUICK_REFERENCE.md +316 -0
- empathy_llm_toolkit/security/README.md +262 -0
- empathy_llm_toolkit/security/__init__.py +62 -0
- empathy_llm_toolkit/security/audit_logger.py +929 -0
- empathy_llm_toolkit/security/audit_logger_example.py +152 -0
- empathy_llm_toolkit/security/pii_scrubber.py +640 -0
- empathy_llm_toolkit/security/secrets_detector.py +678 -0
- empathy_llm_toolkit/security/secrets_detector_example.py +304 -0
- empathy_llm_toolkit/security/secure_memdocs.py +1192 -0
- empathy_llm_toolkit/security/secure_memdocs_example.py +278 -0
- empathy_llm_toolkit/wizards/__init__.py +38 -0
- empathy_llm_toolkit/wizards/base_wizard.py +364 -0
- empathy_llm_toolkit/wizards/customer_support_wizard.py +190 -0
- empathy_llm_toolkit/wizards/healthcare_wizard.py +362 -0
- empathy_llm_toolkit/wizards/patient_assessment_README.md +64 -0
- empathy_llm_toolkit/wizards/patient_assessment_wizard.py +193 -0
- empathy_llm_toolkit/wizards/technology_wizard.py +194 -0
- empathy_os/__init__.py +52 -52
- empathy_os/adaptive/__init__.py +13 -0
- empathy_os/adaptive/task_complexity.py +127 -0
- empathy_os/cli.py +118 -8
- empathy_os/cli_unified.py +121 -1
- empathy_os/config/__init__.py +63 -0
- empathy_os/config/xml_config.py +239 -0
- empathy_os/dashboard/__init__.py +15 -0
- empathy_os/dashboard/server.py +743 -0
- empathy_os/memory/__init__.py +195 -0
- empathy_os/memory/claude_memory.py +466 -0
- empathy_os/memory/config.py +224 -0
- empathy_os/memory/control_panel.py +1298 -0
- empathy_os/memory/edges.py +179 -0
- empathy_os/memory/graph.py +567 -0
- empathy_os/memory/long_term.py +1193 -0
- empathy_os/memory/nodes.py +179 -0
- empathy_os/memory/redis_bootstrap.py +540 -0
- empathy_os/memory/security/__init__.py +31 -0
- empathy_os/memory/security/audit_logger.py +930 -0
- empathy_os/memory/security/pii_scrubber.py +640 -0
- empathy_os/memory/security/secrets_detector.py +678 -0
- empathy_os/memory/short_term.py +2119 -0
- empathy_os/memory/storage/__init__.py +15 -0
- empathy_os/memory/summary_index.py +583 -0
- empathy_os/memory/unified.py +619 -0
- empathy_os/metrics/__init__.py +12 -0
- empathy_os/metrics/prompt_metrics.py +190 -0
- empathy_os/models/__init__.py +136 -0
- empathy_os/models/__main__.py +13 -0
- empathy_os/models/cli.py +655 -0
- empathy_os/models/empathy_executor.py +354 -0
- empathy_os/models/executor.py +252 -0
- empathy_os/models/fallback.py +671 -0
- empathy_os/models/provider_config.py +563 -0
- empathy_os/models/registry.py +382 -0
- empathy_os/models/tasks.py +302 -0
- empathy_os/models/telemetry.py +548 -0
- empathy_os/models/token_estimator.py +378 -0
- empathy_os/models/validation.py +274 -0
- empathy_os/monitoring/__init__.py +52 -0
- empathy_os/monitoring/alerts.py +23 -0
- empathy_os/monitoring/alerts_cli.py +268 -0
- empathy_os/monitoring/multi_backend.py +271 -0
- empathy_os/monitoring/otel_backend.py +363 -0
- empathy_os/optimization/__init__.py +19 -0
- empathy_os/optimization/context_optimizer.py +272 -0
- empathy_os/plugins/__init__.py +28 -0
- empathy_os/plugins/base.py +361 -0
- empathy_os/plugins/registry.py +268 -0
- empathy_os/project_index/__init__.py +30 -0
- empathy_os/project_index/cli.py +335 -0
- empathy_os/project_index/crew_integration.py +430 -0
- empathy_os/project_index/index.py +425 -0
- empathy_os/project_index/models.py +501 -0
- empathy_os/project_index/reports.py +473 -0
- empathy_os/project_index/scanner.py +538 -0
- empathy_os/prompts/__init__.py +61 -0
- empathy_os/prompts/config.py +77 -0
- empathy_os/prompts/context.py +177 -0
- empathy_os/prompts/parser.py +285 -0
- empathy_os/prompts/registry.py +313 -0
- empathy_os/prompts/templates.py +208 -0
- empathy_os/resilience/__init__.py +56 -0
- empathy_os/resilience/circuit_breaker.py +256 -0
- empathy_os/resilience/fallback.py +179 -0
- empathy_os/resilience/health.py +300 -0
- empathy_os/resilience/retry.py +209 -0
- empathy_os/resilience/timeout.py +135 -0
- empathy_os/routing/__init__.py +43 -0
- empathy_os/routing/chain_executor.py +433 -0
- empathy_os/routing/classifier.py +217 -0
- empathy_os/routing/smart_router.py +234 -0
- empathy_os/routing/wizard_registry.py +307 -0
- empathy_os/trust/__init__.py +28 -0
- empathy_os/trust/circuit_breaker.py +579 -0
- empathy_os/validation/__init__.py +19 -0
- empathy_os/validation/xml_validator.py +281 -0
- empathy_os/wizard_factory_cli.py +170 -0
- empathy_os/workflows/__init__.py +360 -0
- empathy_os/workflows/base.py +1530 -0
- empathy_os/workflows/bug_predict.py +962 -0
- empathy_os/workflows/code_review.py +960 -0
- empathy_os/workflows/code_review_adapters.py +310 -0
- empathy_os/workflows/code_review_pipeline.py +720 -0
- empathy_os/workflows/config.py +600 -0
- empathy_os/workflows/dependency_check.py +648 -0
- empathy_os/workflows/document_gen.py +1069 -0
- empathy_os/workflows/documentation_orchestrator.py +1205 -0
- empathy_os/workflows/health_check.py +679 -0
- empathy_os/workflows/keyboard_shortcuts/__init__.py +39 -0
- empathy_os/workflows/keyboard_shortcuts/generators.py +386 -0
- empathy_os/workflows/keyboard_shortcuts/parsers.py +414 -0
- empathy_os/workflows/keyboard_shortcuts/prompts.py +295 -0
- empathy_os/workflows/keyboard_shortcuts/schema.py +193 -0
- empathy_os/workflows/keyboard_shortcuts/workflow.py +505 -0
- empathy_os/workflows/manage_documentation.py +804 -0
- empathy_os/workflows/new_sample_workflow1.py +146 -0
- empathy_os/workflows/new_sample_workflow1_README.md +150 -0
- empathy_os/workflows/perf_audit.py +687 -0
- empathy_os/workflows/pr_review.py +748 -0
- empathy_os/workflows/progress.py +445 -0
- empathy_os/workflows/progress_server.py +322 -0
- empathy_os/workflows/refactor_plan.py +691 -0
- empathy_os/workflows/release_prep.py +808 -0
- empathy_os/workflows/research_synthesis.py +404 -0
- empathy_os/workflows/secure_release.py +585 -0
- empathy_os/workflows/security_adapters.py +297 -0
- empathy_os/workflows/security_audit.py +1050 -0
- empathy_os/workflows/step_config.py +234 -0
- empathy_os/workflows/test5.py +125 -0
- empathy_os/workflows/test5_README.md +158 -0
- empathy_os/workflows/test_gen.py +1855 -0
- empathy_os/workflows/test_lifecycle.py +526 -0
- empathy_os/workflows/test_maintenance.py +626 -0
- empathy_os/workflows/test_maintenance_cli.py +590 -0
- empathy_os/workflows/test_maintenance_crew.py +821 -0
- empathy_os/workflows/xml_enhanced_crew.py +285 -0
- empathy_software_plugin/cli/__init__.py +120 -0
- empathy_software_plugin/cli/inspect.py +362 -0
- empathy_software_plugin/cli.py +3 -1
- empathy_software_plugin/wizards/__init__.py +42 -0
- empathy_software_plugin/wizards/advanced_debugging_wizard.py +392 -0
- empathy_software_plugin/wizards/agent_orchestration_wizard.py +511 -0
- empathy_software_plugin/wizards/ai_collaboration_wizard.py +503 -0
- empathy_software_plugin/wizards/ai_context_wizard.py +441 -0
- empathy_software_plugin/wizards/ai_documentation_wizard.py +503 -0
- empathy_software_plugin/wizards/base_wizard.py +288 -0
- empathy_software_plugin/wizards/book_chapter_wizard.py +519 -0
- empathy_software_plugin/wizards/code_review_wizard.py +606 -0
- empathy_software_plugin/wizards/debugging/__init__.py +50 -0
- empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +414 -0
- empathy_software_plugin/wizards/debugging/config_loaders.py +442 -0
- empathy_software_plugin/wizards/debugging/fix_applier.py +469 -0
- empathy_software_plugin/wizards/debugging/language_patterns.py +383 -0
- empathy_software_plugin/wizards/debugging/linter_parsers.py +470 -0
- empathy_software_plugin/wizards/debugging/verification.py +369 -0
- empathy_software_plugin/wizards/enhanced_testing_wizard.py +537 -0
- empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +816 -0
- empathy_software_plugin/wizards/multi_model_wizard.py +501 -0
- empathy_software_plugin/wizards/pattern_extraction_wizard.py +422 -0
- empathy_software_plugin/wizards/pattern_retriever_wizard.py +400 -0
- empathy_software_plugin/wizards/performance/__init__.py +9 -0
- empathy_software_plugin/wizards/performance/bottleneck_detector.py +221 -0
- empathy_software_plugin/wizards/performance/profiler_parsers.py +278 -0
- empathy_software_plugin/wizards/performance/trajectory_analyzer.py +429 -0
- empathy_software_plugin/wizards/performance_profiling_wizard.py +305 -0
- empathy_software_plugin/wizards/prompt_engineering_wizard.py +425 -0
- empathy_software_plugin/wizards/rag_pattern_wizard.py +461 -0
- empathy_software_plugin/wizards/security/__init__.py +32 -0
- empathy_software_plugin/wizards/security/exploit_analyzer.py +290 -0
- empathy_software_plugin/wizards/security/owasp_patterns.py +241 -0
- empathy_software_plugin/wizards/security/vulnerability_scanner.py +604 -0
- empathy_software_plugin/wizards/security_analysis_wizard.py +322 -0
- empathy_software_plugin/wizards/security_learning_wizard.py +740 -0
- empathy_software_plugin/wizards/tech_debt_wizard.py +726 -0
- empathy_software_plugin/wizards/testing/__init__.py +27 -0
- empathy_software_plugin/wizards/testing/coverage_analyzer.py +459 -0
- empathy_software_plugin/wizards/testing/quality_analyzer.py +531 -0
- empathy_software_plugin/wizards/testing/test_suggester.py +533 -0
- empathy_software_plugin/wizards/testing_wizard.py +274 -0
- hot_reload/README.md +473 -0
- hot_reload/__init__.py +62 -0
- hot_reload/config.py +84 -0
- hot_reload/integration.py +228 -0
- hot_reload/reloader.py +298 -0
- hot_reload/watcher.py +179 -0
- hot_reload/websocket.py +176 -0
- scaffolding/README.md +589 -0
- scaffolding/__init__.py +35 -0
- scaffolding/__main__.py +14 -0
- scaffolding/cli.py +240 -0
- test_generator/__init__.py +38 -0
- test_generator/__main__.py +14 -0
- test_generator/cli.py +226 -0
- test_generator/generator.py +325 -0
- test_generator/risk_analyzer.py +216 -0
- workflow_patterns/__init__.py +33 -0
- workflow_patterns/behavior.py +249 -0
- workflow_patterns/core.py +76 -0
- workflow_patterns/output.py +99 -0
- workflow_patterns/registry.py +255 -0
- workflow_patterns/structural.py +288 -0
- workflow_scaffolding/__init__.py +11 -0
- workflow_scaffolding/__main__.py +12 -0
- workflow_scaffolding/cli.py +206 -0
- workflow_scaffolding/generator.py +265 -0
- agents/code_inspection/patterns/inspection/recurring_B112.json +0 -18
- agents/code_inspection/patterns/inspection/recurring_F541.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_FORMAT.json +0 -25
- agents/code_inspection/patterns/inspection/recurring_bug_20250822_def456.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20250915_abc123.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_3c5b9951.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_97c0f72f.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_a0871d53.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_a9b6ec41.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_null_001.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_builtin.json +0 -16
- agents/compliance_anticipation_agent.py +0 -1422
- agents/compliance_db.py +0 -339
- agents/epic_integration_wizard.py +0 -530
- agents/notifications.py +0 -291
- agents/trust_building_behaviors.py +0 -872
- empathy_framework-3.7.0.dist-info/RECORD +0 -105
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.7.1.dist-info}/WHEEL +0 -0
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.7.1.dist-info}/entry_points.txt +0 -0
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.7.1.dist-info}/licenses/LICENSE +0 -0
- /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
|