empathy-framework 4.6.2__py3-none-any.whl → 4.6.5__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 (43) hide show
  1. {empathy_framework-4.6.2.dist-info → empathy_framework-4.6.5.dist-info}/METADATA +53 -11
  2. {empathy_framework-4.6.2.dist-info → empathy_framework-4.6.5.dist-info}/RECORD +43 -35
  3. {empathy_framework-4.6.2.dist-info → empathy_framework-4.6.5.dist-info}/WHEEL +1 -1
  4. empathy_llm_toolkit/agent_factory/crews/health_check.py +7 -4
  5. empathy_llm_toolkit/agent_factory/decorators.py +3 -2
  6. empathy_llm_toolkit/agent_factory/memory_integration.py +6 -2
  7. empathy_llm_toolkit/contextual_patterns.py +5 -2
  8. empathy_llm_toolkit/git_pattern_extractor.py +8 -4
  9. empathy_llm_toolkit/providers.py +4 -3
  10. empathy_os/__init__.py +1 -1
  11. empathy_os/cli/__init__.py +306 -0
  12. empathy_os/cli/__main__.py +26 -0
  13. empathy_os/cli/commands/__init__.py +8 -0
  14. empathy_os/cli/commands/inspection.py +48 -0
  15. empathy_os/cli/commands/memory.py +56 -0
  16. empathy_os/cli/commands/provider.py +86 -0
  17. empathy_os/cli/commands/utilities.py +94 -0
  18. empathy_os/cli/core.py +32 -0
  19. empathy_os/cli.py +379 -38
  20. empathy_os/cli_unified.py +19 -3
  21. empathy_os/config/xml_config.py +8 -3
  22. empathy_os/core.py +37 -4
  23. empathy_os/leverage_points.py +2 -1
  24. empathy_os/memory/short_term.py +57 -3
  25. empathy_os/models/token_estimator.py +16 -9
  26. empathy_os/models/validation.py +7 -1
  27. empathy_os/orchestration/real_tools.py +4 -2
  28. empathy_os/project_index/scanner.py +151 -49
  29. empathy_os/socratic/storage.py +2 -1
  30. empathy_os/socratic/visual_editor.py +9 -4
  31. empathy_os/tier_recommender.py +5 -2
  32. empathy_os/workflow_commands.py +11 -6
  33. empathy_os/workflows/base.py +1 -1
  34. empathy_os/workflows/bug_predict.py +70 -1
  35. empathy_os/workflows/pr_review.py +6 -0
  36. empathy_os/workflows/security_audit.py +13 -0
  37. empathy_os/workflows/test_maintenance.py +3 -2
  38. empathy_os/workflows/tier_tracking.py +50 -2
  39. wizards/discharge_summary_wizard.py +4 -2
  40. wizards/incident_report_wizard.py +4 -2
  41. {empathy_framework-4.6.2.dist-info → empathy_framework-4.6.5.dist-info}/entry_points.txt +0 -0
  42. {empathy_framework-4.6.2.dist-info → empathy_framework-4.6.5.dist-info}/licenses/LICENSE +0 -0
  43. {empathy_framework-4.6.2.dist-info → empathy_framework-4.6.5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,306 @@
1
+ """Unified CLI for Empathy Framework.
2
+
3
+ A single entry point for all Empathy Framework commands using Typer.
4
+
5
+ Usage:
6
+ empathy --help # Show all commands
7
+ empathy memory status # Memory control panel
8
+ empathy provider # Show provider config
9
+ empathy scan . # Scan codebase
10
+ empathy morning # Start-of-day briefing
11
+
12
+ Copyright 2025 Smart-AI-Memory
13
+ Licensed under Fair Source License 0.9
14
+ """
15
+
16
+ import subprocess
17
+ import sys
18
+ from pathlib import Path
19
+
20
+ import typer
21
+
22
+ # Re-export legacy CLI functions for backward compatibility
23
+ # These functions are defined in the sibling cli.py module (now cli_legacy)
24
+ # Tests and other code may import them from empathy_os.cli
25
+ try:
26
+ # Import from the legacy module using relative import workaround
27
+ # Since this package shadows cli.py, we need to import it explicitly
28
+ import importlib.util
29
+ import os
30
+
31
+ _legacy_cli_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "cli.py")
32
+ if os.path.exists(_legacy_cli_path):
33
+ _spec = importlib.util.spec_from_file_location("cli_legacy", _legacy_cli_path)
34
+ _cli_legacy = importlib.util.module_from_spec(_spec)
35
+ _spec.loader.exec_module(_cli_legacy)
36
+
37
+ # Re-export legacy functions
38
+ cmd_info = _cli_legacy.cmd_info
39
+ cmd_init = _cli_legacy.cmd_init
40
+ cmd_version = _cli_legacy.cmd_version
41
+ cmd_validate = _cli_legacy.cmd_validate
42
+ cmd_patterns_list = _cli_legacy.cmd_patterns_list
43
+ cmd_patterns_export = _cli_legacy.cmd_patterns_export
44
+ cmd_metrics_show = _cli_legacy.cmd_metrics_show
45
+ cmd_state_list = _cli_legacy.cmd_state_list
46
+ cmd_run = _cli_legacy.cmd_run
47
+ cmd_inspect = _cli_legacy.cmd_inspect
48
+ cmd_export = _cli_legacy.cmd_export
49
+ cmd_import = _cli_legacy.cmd_import
50
+ cmd_wizard = _cli_legacy.cmd_wizard
51
+ cmd_cheatsheet = _cli_legacy.cmd_cheatsheet
52
+ cmd_frameworks = _cli_legacy.cmd_frameworks
53
+ main_legacy = _cli_legacy.main
54
+
55
+ # Export for backward compatibility
56
+ __all__ = [
57
+ "app",
58
+ "main",
59
+ "cmd_info",
60
+ "cmd_init",
61
+ "cmd_version",
62
+ "cmd_validate",
63
+ "cmd_patterns_list",
64
+ "cmd_patterns_export",
65
+ "cmd_metrics_show",
66
+ "cmd_state_list",
67
+ "cmd_run",
68
+ "cmd_inspect",
69
+ "cmd_export",
70
+ "cmd_import",
71
+ "cmd_wizard",
72
+ "cmd_cheatsheet",
73
+ "cmd_frameworks",
74
+ ]
75
+ except Exception:
76
+ # If legacy import fails, functions won't be available
77
+ # Tests will fail but the new CLI will still work
78
+ pass
79
+
80
+ from empathy_os.cli.commands import inspection, utilities
81
+ from empathy_os.cli.commands.memory import memory_app
82
+ from empathy_os.cli.commands.provider import provider_app
83
+ from empathy_os.cli.core import console, get_empathy_version, version_callback
84
+
85
+ # Create the main Typer app
86
+ app = typer.Typer(
87
+ name="empathy",
88
+ help="Empathy Framework - Predictive AI-Developer Collaboration",
89
+ no_args_is_help=True,
90
+ rich_markup_mode="rich",
91
+ )
92
+
93
+ # Register command group apps
94
+ app.add_typer(memory_app, name="memory")
95
+ app.add_typer(provider_app, name="provider")
96
+
97
+
98
+ @app.callback()
99
+ def callback(
100
+ version: bool = typer.Option(
101
+ None,
102
+ "--version",
103
+ "-v",
104
+ callback=version_callback,
105
+ is_eager=True,
106
+ help="Show version and exit",
107
+ ),
108
+ ) -> None:
109
+ """Empathy Framework - Predictive AI-Developer Collaboration
110
+
111
+ The AI collaboration framework that predicts problems before they happen.
112
+
113
+ [bold]Quick Start:[/bold]
114
+ empathy morning Start-of-day briefing
115
+ empathy health Quick health check
116
+ empathy ship Pre-commit validation
117
+
118
+ [bold]Memory:[/bold]
119
+ empathy memory status Check memory system status
120
+ empathy memory start Start Redis server
121
+
122
+ [bold]Provider:[/bold]
123
+ empathy provider Show current provider config
124
+ empathy provider --set hybrid Configure provider
125
+
126
+ [bold]Inspection:[/bold]
127
+ empathy scan . Scan codebase for issues
128
+ empathy inspect . Deep inspection with SARIF output
129
+ """
130
+
131
+
132
+ # =============================================================================
133
+ # SCAN/INSPECT COMMANDS (top-level)
134
+ # =============================================================================
135
+
136
+
137
+ @app.command("scan")
138
+ def scan(
139
+ path: Path = Path("."),
140
+ format_out: str = "text",
141
+ fix: bool = False,
142
+ staged: bool = False,
143
+ ) -> None:
144
+ """Scan codebase for issues."""
145
+ inspection.scan(path, format_out, fix, staged)
146
+
147
+
148
+ @app.command("inspect")
149
+ def inspect_cmd(
150
+ path: Path = Path("."),
151
+ format_out: str = "text",
152
+ ) -> None:
153
+ """Deep inspection with code analysis."""
154
+ inspection.inspect_cmd(path, format_out)
155
+
156
+
157
+ # =============================================================================
158
+ # UTILITY COMMANDS (top-level)
159
+ # =============================================================================
160
+
161
+
162
+ @app.command("sync-claude")
163
+ def sync_claude(source: str = "patterns") -> None:
164
+ """Sync patterns to Claude Code memory."""
165
+ utilities.sync_claude(source)
166
+
167
+
168
+ @app.command("cheatsheet")
169
+ def cheatsheet() -> None:
170
+ """Show quick reference for all commands."""
171
+ utilities.cheatsheet()
172
+
173
+
174
+ @app.command("dashboard")
175
+ def dashboard() -> None:
176
+ """Launch visual dashboard."""
177
+ utilities.dashboard()
178
+
179
+
180
+ @app.command("costs")
181
+ def costs() -> None:
182
+ """View API cost tracking."""
183
+ utilities.costs()
184
+
185
+
186
+ @app.command("init")
187
+ def init() -> None:
188
+ """Create a new configuration file."""
189
+ utilities.init()
190
+
191
+
192
+ @app.command("status")
193
+ def status() -> None:
194
+ """What needs attention now."""
195
+ utilities.status()
196
+
197
+
198
+ # =============================================================================
199
+ # WORKFLOW COMMANDS (delegate to legacy CLI for now)
200
+ # These will be extracted in Phase 2b
201
+ # =============================================================================
202
+
203
+
204
+ @app.command("morning")
205
+ def morning() -> None:
206
+ """Start-of-day briefing with patterns, git context, and priorities."""
207
+ subprocess.run([sys.executable, "-m", "empathy_os.cli", "morning"], check=False)
208
+
209
+
210
+ @app.command("ship")
211
+ def ship(
212
+ tests_only: bool = False,
213
+ security_only: bool = False,
214
+ skip_sync: bool = False,
215
+ ) -> None:
216
+ """Pre-commit validation (lint, format, tests, security)."""
217
+ args = [sys.executable, "-m", "empathy_os.cli", "ship"]
218
+ if tests_only:
219
+ args.append("--tests-only")
220
+ if security_only:
221
+ args.append("--security-only")
222
+ if skip_sync:
223
+ args.append("--skip-sync")
224
+ subprocess.run(args, check=False)
225
+
226
+
227
+ @app.command("health")
228
+ def health(
229
+ deep: bool = False,
230
+ fix: bool = False,
231
+ ) -> None:
232
+ """Quick health check (lint, types, tests)."""
233
+ args = [sys.executable, "-m", "empathy_os.cli", "health"]
234
+ if deep:
235
+ args.append("--deep")
236
+ if fix:
237
+ args.append("--fix")
238
+ subprocess.run(args, check=False)
239
+
240
+
241
+ @app.command("fix-all")
242
+ def fix_all() -> None:
243
+ """Fix all lint and format issues."""
244
+ subprocess.run([sys.executable, "-m", "empathy_os.cli", "fix-all"], check=False)
245
+
246
+
247
+ @app.command("learn")
248
+ def learn(analyze: int = 20) -> None:
249
+ """Learn patterns from commit history."""
250
+ subprocess.run(
251
+ [sys.executable, "-m", "empathy_os.cli", "learn", "--analyze", str(analyze)],
252
+ check=False,
253
+ )
254
+
255
+
256
+ @app.command("run")
257
+ def run_repl() -> None:
258
+ """Start interactive REPL mode."""
259
+ subprocess.run([sys.executable, "-m", "empathy_os.cli", "run"], check=False)
260
+
261
+
262
+ # =============================================================================
263
+ # REMAINING COMMAND GROUPS
264
+ # Import directly from cli_unified.py for now - will be extracted later
265
+ # =============================================================================
266
+
267
+ # Import and register remaining command groups from cli_unified.py
268
+ # These are imported here to keep the transition incremental
269
+ try:
270
+ from empathy_os.cli_unified import (
271
+ orchestrate_app,
272
+ progressive_app,
273
+ service_app,
274
+ telemetry_app,
275
+ tier_app,
276
+ wizard_app,
277
+ workflow_app,
278
+ )
279
+
280
+ app.add_typer(wizard_app, name="wizard")
281
+ app.add_typer(workflow_app, name="workflow")
282
+ app.add_typer(orchestrate_app, name="orchestrate")
283
+ app.add_typer(telemetry_app, name="telemetry")
284
+ app.add_typer(service_app, name="service")
285
+ app.add_typer(progressive_app, name="progressive")
286
+ app.add_typer(tier_app, name="tier")
287
+ except ImportError:
288
+ # cli_unified.py may not have these exports yet
289
+ pass
290
+
291
+ # Register meta-workflow if available
292
+ try:
293
+ from empathy_os.meta_workflows.cli_meta_workflows import meta_workflow_app
294
+
295
+ app.add_typer(meta_workflow_app, name="meta-workflow")
296
+ except ImportError:
297
+ pass
298
+
299
+
300
+ def main() -> None:
301
+ """Entry point for the unified CLI."""
302
+ app()
303
+
304
+
305
+ if __name__ == "__main__":
306
+ main()
@@ -0,0 +1,26 @@
1
+ """Entry point for python -m empathy_os.cli.
2
+
3
+ This redirects to the legacy cli.py module for backward compatibility.
4
+ The cli/ package coexists with cli.py, but Python finds packages first.
5
+ """
6
+
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ # Add the parent directory to find the cli.py module
11
+ parent = Path(__file__).parent.parent
12
+ if str(parent) not in sys.path:
13
+ sys.path.insert(0, str(parent))
14
+
15
+ # Import and run the legacy CLI
16
+ # We can't import cli directly because of the package name conflict
17
+ # So we use importlib to load cli.py as a module
18
+ import importlib.util
19
+
20
+ cli_py_path = parent / "cli.py"
21
+ spec = importlib.util.spec_from_file_location("cli_legacy", cli_py_path)
22
+ cli_module = importlib.util.module_from_spec(spec)
23
+ spec.loader.exec_module(cli_module)
24
+
25
+ if __name__ == "__main__":
26
+ cli_module.main()
@@ -0,0 +1,8 @@
1
+ """CLI command modules for Empathy Framework.
2
+
3
+ Each module contains a Typer app that can be registered with the main app.
4
+ """
5
+
6
+ from empathy_os.cli.commands import inspection, memory, provider, utilities
7
+
8
+ __all__ = ["memory", "provider", "inspection", "utilities"]
@@ -0,0 +1,48 @@
1
+ """Code inspection commands.
2
+
3
+ Commands for scanning and inspecting codebases for issues.
4
+
5
+ Copyright 2025 Smart-AI-Memory
6
+ Licensed under Fair Source License 0.9
7
+ """
8
+
9
+ import subprocess
10
+ from pathlib import Path
11
+
12
+ from empathy_os.cli.core import console
13
+
14
+
15
+ def scan(
16
+ path: Path = Path("."),
17
+ format_out: str = "text",
18
+ fix: bool = False,
19
+ staged: bool = False,
20
+ ) -> None:
21
+ """Scan codebase for issues."""
22
+ args = ["empathy-scan", str(path)]
23
+ if format_out != "text":
24
+ args.extend(["--format", format_out])
25
+ if fix:
26
+ args.append("--fix")
27
+ if staged:
28
+ args.append("--staged")
29
+
30
+ result = subprocess.run(args, check=False, capture_output=False)
31
+ if result.returncode != 0:
32
+ console.print("[yellow]Note: empathy-scan may not be installed[/yellow]")
33
+ console.print("Install with: pip install empathy-framework[software]")
34
+
35
+
36
+ def inspect_cmd(
37
+ path: Path = Path("."),
38
+ format_out: str = "text",
39
+ ) -> None:
40
+ """Deep inspection with code analysis."""
41
+ args = ["empathy-inspect", str(path)]
42
+ if format_out != "text":
43
+ args.extend(["--format", format_out])
44
+
45
+ result = subprocess.run(args, check=False, capture_output=False)
46
+ if result.returncode != 0:
47
+ console.print("[yellow]Note: empathy-inspect may not be installed[/yellow]")
48
+ console.print("Install with: pip install empathy-framework[software]")
@@ -0,0 +1,56 @@
1
+ """Memory system control panel commands.
2
+
3
+ Commands for managing Redis-backed short-term memory system.
4
+
5
+ Copyright 2025 Smart-AI-Memory
6
+ Licensed under Fair Source License 0.9
7
+ """
8
+
9
+ import subprocess
10
+ import sys
11
+
12
+ import typer
13
+
14
+ # Create the memory Typer app
15
+ memory_app = typer.Typer(help="Memory system control panel")
16
+
17
+
18
+ @memory_app.command("status")
19
+ def memory_status() -> None:
20
+ """Check memory system status (Redis, patterns, stats)."""
21
+ subprocess.run(
22
+ [sys.executable, "-m", "empathy_os.memory.control_panel", "status"], check=False
23
+ )
24
+
25
+
26
+ @memory_app.command("start")
27
+ def memory_start() -> None:
28
+ """Start Redis server for short-term memory."""
29
+ subprocess.run(
30
+ [sys.executable, "-m", "empathy_os.memory.control_panel", "start"], check=False
31
+ )
32
+
33
+
34
+ @memory_app.command("stop")
35
+ def memory_stop() -> None:
36
+ """Stop Redis server."""
37
+ subprocess.run(
38
+ [sys.executable, "-m", "empathy_os.memory.control_panel", "stop"], check=False
39
+ )
40
+
41
+
42
+ @memory_app.command("stats")
43
+ def memory_stats() -> None:
44
+ """Show memory statistics."""
45
+ subprocess.run(
46
+ [sys.executable, "-m", "empathy_os.memory.control_panel", "stats"], check=False
47
+ )
48
+
49
+
50
+ @memory_app.command("patterns")
51
+ def memory_patterns() -> None:
52
+ """List stored patterns."""
53
+ subprocess.run(
54
+ [sys.executable, "-m", "empathy_os.memory.control_panel", "patterns", "--list"],
55
+ check=False,
56
+ )
@@ -0,0 +1,86 @@
1
+ """Multi-model provider configuration commands.
2
+
3
+ Commands for managing provider settings, registry, costs, and telemetry.
4
+
5
+ Copyright 2025 Smart-AI-Memory
6
+ Licensed under Fair Source License 0.9
7
+ """
8
+
9
+ import subprocess
10
+ import sys
11
+
12
+ import typer
13
+
14
+ # Create the provider Typer app
15
+ provider_app = typer.Typer(help="Multi-model provider configuration")
16
+
17
+
18
+ @provider_app.callback(invoke_without_command=True)
19
+ def provider_show(
20
+ ctx: typer.Context,
21
+ set_provider: str | None = None,
22
+ interactive: bool = False,
23
+ format_out: str = "table",
24
+ ) -> None:
25
+ """Show or configure provider settings."""
26
+ if ctx.invoked_subcommand is not None:
27
+ return
28
+
29
+ args = [sys.executable, "-m", "empathy_os.models.cli", "provider"]
30
+ if set_provider:
31
+ args.extend(["--set", set_provider])
32
+ if interactive:
33
+ args.append("--interactive")
34
+ if format_out != "table":
35
+ args.extend(["-f", format_out])
36
+
37
+ subprocess.run(args, check=False)
38
+
39
+
40
+ @provider_app.command("registry")
41
+ def provider_registry(
42
+ provider_filter: str | None = None,
43
+ ) -> None:
44
+ """Show all available models in the registry."""
45
+ args = [sys.executable, "-m", "empathy_os.models.cli", "registry"]
46
+ if provider_filter:
47
+ args.extend(["--provider", provider_filter])
48
+ subprocess.run(args, check=False)
49
+
50
+
51
+ @provider_app.command("costs")
52
+ def provider_costs(
53
+ input_tokens: int = 10000,
54
+ output_tokens: int = 2000,
55
+ ) -> None:
56
+ """Estimate costs for token usage."""
57
+ subprocess.run(
58
+ [
59
+ sys.executable,
60
+ "-m",
61
+ "empathy_os.models.cli",
62
+ "costs",
63
+ "--input-tokens",
64
+ str(input_tokens),
65
+ "--output-tokens",
66
+ str(output_tokens),
67
+ ],
68
+ check=False,
69
+ )
70
+
71
+
72
+ @provider_app.command("telemetry")
73
+ def provider_telemetry(
74
+ summary: bool = False,
75
+ costs: bool = False,
76
+ providers: bool = False,
77
+ ) -> None:
78
+ """View telemetry and analytics."""
79
+ args = [sys.executable, "-m", "empathy_os.models.cli", "telemetry"]
80
+ if summary:
81
+ args.append("--summary")
82
+ if costs:
83
+ args.append("--costs")
84
+ if providers:
85
+ args.append("--providers")
86
+ subprocess.run(args, check=False)
@@ -0,0 +1,94 @@
1
+ """Utility commands for Empathy Framework CLI.
2
+
3
+ General-purpose utility commands (sync, cheatsheet, dashboard, etc.).
4
+
5
+ Copyright 2025 Smart-AI-Memory
6
+ Licensed under Fair Source License 0.9
7
+ """
8
+
9
+ import subprocess
10
+ import sys
11
+
12
+ from rich.panel import Panel
13
+
14
+ from empathy_os.cli.core import console
15
+
16
+
17
+ def sync_claude(source: str = "patterns") -> None:
18
+ """Sync patterns to Claude Code memory."""
19
+ subprocess.run(["empathy-sync-claude", "--source", source], check=False)
20
+
21
+
22
+ def cheatsheet() -> None:
23
+ """Show quick reference for all commands."""
24
+ console.print(
25
+ Panel.fit(
26
+ """[bold]Getting Started[/bold]
27
+ empathy morning Start-of-day briefing
28
+ empathy health Quick health check
29
+ empathy ship Pre-commit validation
30
+ empathy run Interactive REPL
31
+
32
+ [bold]Memory System[/bold]
33
+ empathy memory status Check Redis & patterns
34
+ empathy memory start Start Redis server
35
+ empathy memory patterns List stored patterns
36
+
37
+ [bold]Cross-Session Service[/bold]
38
+ empathy service start Start coordination service
39
+ empathy service status Show service & sessions
40
+ empathy service sessions List active agents
41
+
42
+ [bold]Provider Config[/bold]
43
+ empathy provider Show current config
44
+ empathy provider --set hybrid Use best-of-breed
45
+ empathy provider registry List all models
46
+
47
+ [bold]Code Inspection[/bold]
48
+ empathy scan . Scan for issues
49
+ empathy inspect . Deep analysis (SARIF)
50
+ empathy fix-all Auto-fix everything
51
+
52
+ [bold]Pattern Learning[/bold]
53
+ empathy learn --analyze 20 Learn from commits
54
+ empathy sync-claude Sync to Claude Code
55
+
56
+ [bold]Workflows[/bold]
57
+ empathy workflow list Show available workflows
58
+ empathy workflow run <name> Execute a workflow
59
+ empathy workflow create <name> -p <patterns> Create workflow (12x faster)
60
+ empathy workflow list-patterns List available patterns
61
+
62
+ [bold]Wizards[/bold]
63
+ empathy wizard list Show available wizards
64
+ empathy wizard run <name> Execute a wizard
65
+ empathy wizard create <name> -d <domain> Create wizard (12x faster)
66
+ empathy wizard list-patterns List available patterns
67
+
68
+ [bold]Usage Telemetry[/bold]
69
+ empathy telemetry show View recent LLM calls & costs
70
+ empathy telemetry savings Calculate cost savings (tier routing)
71
+ empathy telemetry export Export usage data (JSON/CSV)""",
72
+ title="[bold blue]Empathy Framework Cheatsheet[/bold blue]",
73
+ )
74
+ )
75
+
76
+
77
+ def dashboard() -> None:
78
+ """Launch visual dashboard."""
79
+ subprocess.run([sys.executable, "-m", "empathy_os.cli", "dashboard"], check=False)
80
+
81
+
82
+ def costs() -> None:
83
+ """View API cost tracking."""
84
+ subprocess.run([sys.executable, "-m", "empathy_os.cli", "costs"], check=False)
85
+
86
+
87
+ def init() -> None:
88
+ """Create a new configuration file."""
89
+ subprocess.run([sys.executable, "-m", "empathy_os.cli", "init"], check=False)
90
+
91
+
92
+ def status() -> None:
93
+ """What needs attention now."""
94
+ subprocess.run([sys.executable, "-m", "empathy_os.cli", "status"], check=False)
empathy_os/cli/core.py ADDED
@@ -0,0 +1,32 @@
1
+ """Core utilities for Empathy Framework CLI.
2
+
3
+ Shared utilities, console configuration, and helper functions used across
4
+ all CLI command modules.
5
+
6
+ Copyright 2025 Smart-AI-Memory
7
+ Licensed under Fair Source License 0.9
8
+ """
9
+
10
+ from importlib.metadata import version as get_version
11
+
12
+ import typer
13
+ from rich.console import Console
14
+
15
+ # Shared Rich console instance for all CLI commands
16
+ console = Console()
17
+
18
+
19
+ def get_empathy_version() -> str:
20
+ """Get the installed version of empathy-framework."""
21
+ try:
22
+ return get_version("empathy-framework")
23
+ except Exception: # noqa: BLE001
24
+ # INTENTIONAL: Version detection fallback for dev installs
25
+ return "dev"
26
+
27
+
28
+ def version_callback(value: bool) -> None:
29
+ """Show version and exit."""
30
+ if value:
31
+ console.print(f"[bold blue]Empathy Framework[/bold blue] v{get_empathy_version()}")
32
+ raise typer.Exit()