empathy-framework 3.5.6__py3-none-any.whl → 3.7.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.
- agents/compliance_anticipation_agent.py +113 -118
- agents/compliance_db.py +339 -0
- agents/epic_integration_wizard.py +37 -48
- agents/notifications.py +291 -0
- agents/trust_building_behaviors.py +66 -85
- coach_wizards/__init__.py +11 -12
- coach_wizards/accessibility_wizard.py +12 -12
- coach_wizards/api_wizard.py +12 -12
- coach_wizards/base_wizard.py +26 -20
- coach_wizards/cicd_wizard.py +15 -13
- coach_wizards/compliance_wizard.py +12 -12
- coach_wizards/database_wizard.py +12 -12
- coach_wizards/debugging_wizard.py +12 -12
- coach_wizards/documentation_wizard.py +12 -12
- coach_wizards/generate_wizards.py +1 -2
- coach_wizards/localization_wizard.py +21 -14
- coach_wizards/migration_wizard.py +12 -12
- coach_wizards/monitoring_wizard.py +12 -12
- coach_wizards/observability_wizard.py +12 -12
- coach_wizards/performance_wizard.py +12 -12
- coach_wizards/prompt_engineering_wizard.py +22 -25
- coach_wizards/refactoring_wizard.py +12 -12
- coach_wizards/scaling_wizard.py +12 -12
- coach_wizards/security_wizard.py +12 -12
- coach_wizards/testing_wizard.py +12 -12
- {empathy_framework-3.5.6.dist-info → empathy_framework-3.7.0.dist-info}/METADATA +234 -30
- empathy_framework-3.7.0.dist-info/RECORD +105 -0
- empathy_healthcare_plugin/__init__.py +1 -2
- empathy_llm_toolkit/__init__.py +5 -6
- empathy_llm_toolkit/claude_memory.py +14 -15
- empathy_llm_toolkit/code_health.py +27 -19
- empathy_llm_toolkit/contextual_patterns.py +11 -12
- empathy_llm_toolkit/core.py +43 -49
- empathy_llm_toolkit/git_pattern_extractor.py +16 -12
- empathy_llm_toolkit/levels.py +6 -13
- empathy_llm_toolkit/pattern_confidence.py +14 -18
- empathy_llm_toolkit/pattern_resolver.py +10 -12
- empathy_llm_toolkit/pattern_summary.py +13 -11
- empathy_llm_toolkit/providers.py +27 -38
- empathy_llm_toolkit/session_status.py +18 -20
- empathy_llm_toolkit/state.py +20 -21
- empathy_os/__init__.py +72 -73
- empathy_os/cli.py +193 -98
- empathy_os/cli_unified.py +68 -41
- empathy_os/config.py +31 -31
- empathy_os/coordination.py +48 -54
- empathy_os/core.py +90 -99
- empathy_os/cost_tracker.py +20 -23
- empathy_os/discovery.py +9 -11
- empathy_os/emergence.py +20 -21
- empathy_os/exceptions.py +18 -30
- empathy_os/feedback_loops.py +27 -30
- empathy_os/levels.py +31 -34
- empathy_os/leverage_points.py +27 -28
- empathy_os/logging_config.py +11 -12
- empathy_os/monitoring.py +27 -27
- empathy_os/pattern_library.py +29 -28
- empathy_os/persistence.py +30 -34
- empathy_os/platform_utils.py +46 -47
- empathy_os/redis_config.py +14 -15
- empathy_os/redis_memory.py +53 -56
- empathy_os/templates.py +12 -11
- empathy_os/trust_building.py +44 -36
- empathy_os/workflow_commands.py +123 -31
- empathy_software_plugin/__init__.py +1 -2
- empathy_software_plugin/cli.py +32 -25
- empathy_software_plugin/plugin.py +4 -8
- empathy_framework-3.5.6.dist-info/RECORD +0 -103
- {empathy_framework-3.5.6.dist-info → empathy_framework-3.7.0.dist-info}/WHEEL +0 -0
- {empathy_framework-3.5.6.dist-info → empathy_framework-3.7.0.dist-info}/entry_points.txt +0 -0
- {empathy_framework-3.5.6.dist-info → empathy_framework-3.7.0.dist-info}/licenses/LICENSE +0 -0
- {empathy_framework-3.5.6.dist-info → empathy_framework-3.7.0.dist-info}/top_level.txt +0 -0
empathy_os/workflow_commands.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
One-Command Workflows for Empathy Framework
|
|
1
|
+
"""One-Command Workflows for Empathy Framework
|
|
3
2
|
|
|
4
3
|
Power-user commands that automate common developer workflows:
|
|
5
4
|
- morning: Start-of-day briefing with patterns, debt, and focus areas
|
|
@@ -30,7 +29,7 @@ def _load_patterns(patterns_dir: str = "./patterns") -> dict[str, list]:
|
|
|
30
29
|
if not patterns_path.exists():
|
|
31
30
|
return patterns
|
|
32
31
|
|
|
33
|
-
for pattern_type in patterns
|
|
32
|
+
for pattern_type in patterns:
|
|
34
33
|
file_path = patterns_path / f"{pattern_type}.json"
|
|
35
34
|
if file_path.exists():
|
|
36
35
|
try:
|
|
@@ -68,7 +67,7 @@ def _save_stats(stats: dict, empathy_dir: str = ".empathy") -> None:
|
|
|
68
67
|
def _run_command(cmd: list, capture: bool = True) -> tuple:
|
|
69
68
|
"""Run a shell command and return (success, output)."""
|
|
70
69
|
try:
|
|
71
|
-
result = subprocess.run(cmd, capture_output=capture, text=True, timeout=300)
|
|
70
|
+
result = subprocess.run(cmd, check=False, capture_output=capture, text=True, timeout=300)
|
|
72
71
|
return result.returncode == 0, result.stdout + result.stderr
|
|
73
72
|
except subprocess.TimeoutExpired:
|
|
74
73
|
return False, "Command timed out"
|
|
@@ -97,19 +96,19 @@ def _get_tech_debt_trend(patterns_dir: str = "./patterns") -> str:
|
|
|
97
96
|
|
|
98
97
|
if recent > previous:
|
|
99
98
|
return "increasing"
|
|
100
|
-
|
|
99
|
+
if recent < previous:
|
|
101
100
|
return "decreasing"
|
|
102
|
-
|
|
103
|
-
return "stable"
|
|
101
|
+
return "stable"
|
|
104
102
|
except (OSError, json.JSONDecodeError, KeyError):
|
|
105
103
|
return "unknown"
|
|
106
104
|
|
|
107
105
|
|
|
108
106
|
def morning_workflow(
|
|
109
|
-
patterns_dir: str = "./patterns",
|
|
107
|
+
patterns_dir: str = "./patterns",
|
|
108
|
+
project_root: str = ".",
|
|
109
|
+
verbose: bool = False,
|
|
110
110
|
) -> int:
|
|
111
|
-
"""
|
|
112
|
-
Start-of-day developer briefing.
|
|
111
|
+
"""Start-of-day developer briefing.
|
|
113
112
|
|
|
114
113
|
Shows:
|
|
115
114
|
- Health check summary
|
|
@@ -231,7 +230,7 @@ def morning_workflow(
|
|
|
231
230
|
]
|
|
232
231
|
if investigating_bugs:
|
|
233
232
|
suggestions.append(
|
|
234
|
-
f"Resolve {len(investigating_bugs)} investigating bug(s) via 'empathy patterns resolve'"
|
|
233
|
+
f"Resolve {len(investigating_bugs)} investigating bug(s) via 'empathy patterns resolve'",
|
|
235
234
|
)
|
|
236
235
|
|
|
237
236
|
if trend == "increasing":
|
|
@@ -258,14 +257,93 @@ def morning_workflow(
|
|
|
258
257
|
return 0
|
|
259
258
|
|
|
260
259
|
|
|
260
|
+
def _run_tests_only(project_root: str = ".", verbose: bool = False) -> int:
|
|
261
|
+
"""Run tests only (used by ship --tests-only)."""
|
|
262
|
+
print("\n" + "=" * 60)
|
|
263
|
+
print(" TEST RESULTS")
|
|
264
|
+
print("=" * 60 + "\n")
|
|
265
|
+
|
|
266
|
+
# Try pytest first
|
|
267
|
+
success, output = _run_command(["python", "-m", "pytest", project_root, "-v", "--tb=short"])
|
|
268
|
+
|
|
269
|
+
if success:
|
|
270
|
+
print("All tests passed!")
|
|
271
|
+
print("\n" + "=" * 60 + "\n")
|
|
272
|
+
return 0
|
|
273
|
+
print("Test Results:")
|
|
274
|
+
print("-" * 40)
|
|
275
|
+
print(output)
|
|
276
|
+
print("\n" + "=" * 60 + "\n")
|
|
277
|
+
return 1
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def _run_security_only(project_root: str = ".", verbose: bool = False) -> int:
|
|
281
|
+
"""Run security checks only (used by ship --security-only)."""
|
|
282
|
+
print("\n" + "=" * 60)
|
|
283
|
+
print(" SECURITY SCAN")
|
|
284
|
+
print("=" * 60 + "\n")
|
|
285
|
+
|
|
286
|
+
issues = []
|
|
287
|
+
|
|
288
|
+
# Try bandit (Python security scanner)
|
|
289
|
+
print("1. Running Bandit security scan...")
|
|
290
|
+
success, output = _run_command(["bandit", "-r", project_root, "-ll", "-q"])
|
|
291
|
+
if success:
|
|
292
|
+
print(" PASS - No high/medium security issues")
|
|
293
|
+
elif "bandit" in output.lower() and "not found" in output.lower():
|
|
294
|
+
print(" SKIP - Bandit not installed (pip install bandit)")
|
|
295
|
+
else:
|
|
296
|
+
issue_count = output.count(">> Issue:")
|
|
297
|
+
issues.append(f"Bandit: {issue_count} security issues")
|
|
298
|
+
print(f" WARN - {issue_count} issues found")
|
|
299
|
+
if verbose:
|
|
300
|
+
print(output)
|
|
301
|
+
|
|
302
|
+
# Check for secrets in code
|
|
303
|
+
print("2. Checking for hardcoded secrets...")
|
|
304
|
+
success, output = _run_command(
|
|
305
|
+
["grep", "-rn", "--include=*.py", "password.*=.*['\"]", project_root],
|
|
306
|
+
)
|
|
307
|
+
if not success or not output.strip():
|
|
308
|
+
print(" PASS - No obvious hardcoded secrets")
|
|
309
|
+
else:
|
|
310
|
+
lines = len([line for line in output.split("\n") if line.strip()])
|
|
311
|
+
issues.append(f"Secrets: {lines} potential hardcoded secrets")
|
|
312
|
+
print(f" WARN - {lines} potential hardcoded values found")
|
|
313
|
+
|
|
314
|
+
# Check for .env files that might be committed
|
|
315
|
+
print("3. Checking for sensitive files...")
|
|
316
|
+
success, output = _run_command(["git", "ls-files", ".env", "*.pem", "*.key"])
|
|
317
|
+
if not output.strip():
|
|
318
|
+
print(" PASS - No sensitive files tracked")
|
|
319
|
+
else:
|
|
320
|
+
files = len([line for line in output.split("\n") if line.strip()])
|
|
321
|
+
issues.append(f"Files: {files} sensitive files in git")
|
|
322
|
+
print(f" WARN - {files} sensitive files tracked in git")
|
|
323
|
+
|
|
324
|
+
# Summary
|
|
325
|
+
print("\n" + "-" * 60)
|
|
326
|
+
if issues:
|
|
327
|
+
print("\nSECURITY ISSUES FOUND:")
|
|
328
|
+
for issue in issues:
|
|
329
|
+
print(f" - {issue}")
|
|
330
|
+
print("\n" + "=" * 60 + "\n")
|
|
331
|
+
return 1
|
|
332
|
+
|
|
333
|
+
print("\nNo security issues found!")
|
|
334
|
+
print("\n" + "=" * 60 + "\n")
|
|
335
|
+
return 0
|
|
336
|
+
|
|
337
|
+
|
|
261
338
|
def ship_workflow(
|
|
262
339
|
patterns_dir: str = "./patterns",
|
|
263
340
|
project_root: str = ".",
|
|
264
341
|
skip_sync: bool = False,
|
|
342
|
+
tests_only: bool = False,
|
|
343
|
+
security_only: bool = False,
|
|
265
344
|
verbose: bool = False,
|
|
266
345
|
) -> int:
|
|
267
|
-
"""
|
|
268
|
-
Pre-commit validation pipeline.
|
|
346
|
+
"""Pre-commit validation pipeline.
|
|
269
347
|
|
|
270
348
|
Runs:
|
|
271
349
|
1. empathy inspect (code analysis)
|
|
@@ -273,8 +351,23 @@ def ship_workflow(
|
|
|
273
351
|
3. empathy sync-claude (pattern sync)
|
|
274
352
|
4. Summary
|
|
275
353
|
|
|
354
|
+
Args:
|
|
355
|
+
patterns_dir: Path to patterns directory
|
|
356
|
+
project_root: Project root directory
|
|
357
|
+
skip_sync: Skip syncing patterns to Claude
|
|
358
|
+
tests_only: Run tests only (skip lint/format checks)
|
|
359
|
+
security_only: Run security checks only
|
|
360
|
+
verbose: Show detailed output
|
|
361
|
+
|
|
276
362
|
Returns exit code (0 = ready to ship, non-zero = issues found).
|
|
363
|
+
|
|
277
364
|
"""
|
|
365
|
+
if tests_only:
|
|
366
|
+
return _run_tests_only(project_root, verbose)
|
|
367
|
+
|
|
368
|
+
if security_only:
|
|
369
|
+
return _run_security_only(project_root, verbose)
|
|
370
|
+
|
|
278
371
|
print("\n" + "=" * 60)
|
|
279
372
|
print(" PRE-SHIP CHECKLIST")
|
|
280
373
|
print("=" * 60 + "\n")
|
|
@@ -289,7 +382,7 @@ def ship_workflow(
|
|
|
289
382
|
print(" PASS - No lint issues")
|
|
290
383
|
else:
|
|
291
384
|
issue_count = len(
|
|
292
|
-
[line for line in output.split("\n") if line.strip() and not line.startswith("Found")]
|
|
385
|
+
[line for line in output.split("\n") if line.strip() and not line.startswith("Found")],
|
|
293
386
|
)
|
|
294
387
|
issues.append(f"Lint: {issue_count} issues")
|
|
295
388
|
print(f" FAIL - {issue_count} issues found")
|
|
@@ -307,7 +400,7 @@ def ship_workflow(
|
|
|
307
400
|
line
|
|
308
401
|
for line in output.split("\n")
|
|
309
402
|
if "would be reformatted" in line.lower() or line.strip().endswith(".py")
|
|
310
|
-
]
|
|
403
|
+
],
|
|
311
404
|
)
|
|
312
405
|
warnings.append(f"Format: {files} files need formatting")
|
|
313
406
|
print(f" WARN - {files} files need formatting (run 'empathy fix-all')")
|
|
@@ -330,7 +423,7 @@ def ship_workflow(
|
|
|
330
423
|
success, output = _run_command(["git", "status", "--porcelain"])
|
|
331
424
|
if success:
|
|
332
425
|
staged = len(
|
|
333
|
-
[line for line in output.split("\n") if line.startswith(("A ", "M ", "D ", "R "))]
|
|
426
|
+
[line for line in output.split("\n") if line.startswith(("A ", "M ", "D ", "R "))],
|
|
334
427
|
)
|
|
335
428
|
unstaged = len([line for line in output.split("\n") if line.startswith((" M", " D", "??"))])
|
|
336
429
|
if staged > 0:
|
|
@@ -346,15 +439,14 @@ def ship_workflow(
|
|
|
346
439
|
print("5. Syncing patterns to Claude Code...")
|
|
347
440
|
# Import here to avoid circular imports
|
|
348
441
|
try:
|
|
349
|
-
from
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
result =
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
print(f" PASS - {result.get('patterns_synced', 0)} patterns synced")
|
|
442
|
+
from pathlib import Path
|
|
443
|
+
|
|
444
|
+
from empathy_llm_toolkit.cli.sync_claude import sync_patterns
|
|
445
|
+
|
|
446
|
+
result = sync_patterns(project_root=Path(), verbose=False)
|
|
447
|
+
synced_count = len(result.get("synced", []))
|
|
448
|
+
if synced_count > 0:
|
|
449
|
+
print(f" PASS - {synced_count} patterns synced")
|
|
358
450
|
else:
|
|
359
451
|
print(" SKIP - No patterns to sync")
|
|
360
452
|
except ImportError:
|
|
@@ -395,8 +487,7 @@ def ship_workflow(
|
|
|
395
487
|
|
|
396
488
|
|
|
397
489
|
def fix_all_workflow(project_root: str = ".", dry_run: bool = False, verbose: bool = False) -> int:
|
|
398
|
-
"""
|
|
399
|
-
Auto-fix all fixable issues.
|
|
490
|
+
"""Auto-fix all fixable issues.
|
|
400
491
|
|
|
401
492
|
Runs:
|
|
402
493
|
1. ruff --fix (lint fixes)
|
|
@@ -444,7 +535,7 @@ def fix_all_workflow(project_root: str = ".", dry_run: bool = False, verbose: bo
|
|
|
444
535
|
line
|
|
445
536
|
for line in output.split("\n")
|
|
446
537
|
if line.strip().endswith(".py") and "reformatted" in output.lower()
|
|
447
|
-
]
|
|
538
|
+
],
|
|
448
539
|
)
|
|
449
540
|
|
|
450
541
|
print(f" Formatted {formatted} files")
|
|
@@ -488,8 +579,7 @@ def learn_workflow(
|
|
|
488
579
|
watch: bool = False,
|
|
489
580
|
verbose: bool = False,
|
|
490
581
|
) -> int:
|
|
491
|
-
"""
|
|
492
|
-
Watch for bug fixes and extract patterns.
|
|
582
|
+
"""Watch for bug fixes and extract patterns.
|
|
493
583
|
|
|
494
584
|
Modes:
|
|
495
585
|
- analyze: Analyze recent commits for bug fix patterns
|
|
@@ -516,7 +606,7 @@ def learn_workflow(
|
|
|
516
606
|
|
|
517
607
|
# Get recent commits
|
|
518
608
|
success, output = _run_command(
|
|
519
|
-
["git", "log", f"-{commit_count}", "--oneline", "--format=%H|%s|%an|%ai"]
|
|
609
|
+
["git", "log", f"-{commit_count}", "--oneline", "--format=%H|%s|%an|%ai"],
|
|
520
610
|
)
|
|
521
611
|
|
|
522
612
|
if not success:
|
|
@@ -660,6 +750,8 @@ def cmd_ship(args):
|
|
|
660
750
|
patterns_dir=getattr(args, "patterns_dir", "./patterns"),
|
|
661
751
|
project_root=getattr(args, "project_root", "."),
|
|
662
752
|
skip_sync=getattr(args, "skip_sync", False),
|
|
753
|
+
tests_only=getattr(args, "tests_only", False),
|
|
754
|
+
security_only=getattr(args, "security_only", False),
|
|
663
755
|
verbose=getattr(args, "verbose", False),
|
|
664
756
|
)
|
|
665
757
|
|
empathy_software_plugin/cli.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Empathy Framework - Software Development CLI
|
|
1
|
+
"""Empathy Framework - Software Development CLI
|
|
3
2
|
|
|
4
3
|
Command-line interface for running AI development wizards on your codebase.
|
|
5
4
|
|
|
@@ -98,14 +97,14 @@ async def analyze_project(
|
|
|
98
97
|
output_format: str = "text",
|
|
99
98
|
verbose: bool = False,
|
|
100
99
|
):
|
|
101
|
-
"""
|
|
102
|
-
Analyze a project with AI development wizards.
|
|
100
|
+
"""Analyze a project with AI development wizards.
|
|
103
101
|
|
|
104
102
|
Args:
|
|
105
103
|
project_path: Path to project root
|
|
106
104
|
wizard_names: List of wizard names to run (or None for all)
|
|
107
105
|
output_format: 'text' or 'json'
|
|
108
106
|
verbose: Show detailed output
|
|
107
|
+
|
|
109
108
|
"""
|
|
110
109
|
logger.info(f"Starting project analysis for: {project_path} (format: {output_format})")
|
|
111
110
|
print_header("Empathy Framework - AI Development Analysis")
|
|
@@ -192,8 +191,7 @@ async def analyze_project(
|
|
|
192
191
|
|
|
193
192
|
|
|
194
193
|
async def gather_project_context(project_path: str) -> dict[str, Any]:
|
|
195
|
-
"""
|
|
196
|
-
Gather context about the project.
|
|
194
|
+
"""Gather context about the project.
|
|
197
195
|
|
|
198
196
|
Returns dictionary with all context needed by wizards.
|
|
199
197
|
"""
|
|
@@ -234,8 +232,10 @@ async def gather_project_context(project_path: str) -> dict[str, Any]:
|
|
|
234
232
|
|
|
235
233
|
# Parse AI calls
|
|
236
234
|
context["ai_calls"].extend(parse_ai_calls(str(file_path), content))
|
|
237
|
-
except Exception:
|
|
238
|
-
|
|
235
|
+
except Exception as e:
|
|
236
|
+
# Best effort: Skip files that can't be parsed (corrupted, binary, etc.)
|
|
237
|
+
logger.debug(f"Could not parse {file_path}: {e}")
|
|
238
|
+
pass
|
|
239
239
|
|
|
240
240
|
# All Python/JS/TS files are code files
|
|
241
241
|
context["code_files"].append(str(file_path))
|
|
@@ -264,6 +264,7 @@ async def gather_project_context(project_path: str) -> dict[str, Any]:
|
|
|
264
264
|
|
|
265
265
|
result = subprocess.run(
|
|
266
266
|
["git", "log", "--oneline", "--name-only", "-50"],
|
|
267
|
+
check=False,
|
|
267
268
|
cwd=project_path,
|
|
268
269
|
capture_output=True,
|
|
269
270
|
text=True,
|
|
@@ -271,8 +272,10 @@ async def gather_project_context(project_path: str) -> dict[str, Any]:
|
|
|
271
272
|
)
|
|
272
273
|
if result.returncode == 0:
|
|
273
274
|
context["version_history"] = parse_git_history(result.stdout)
|
|
274
|
-
except Exception:
|
|
275
|
-
|
|
275
|
+
except Exception as e:
|
|
276
|
+
# Optional: Git history unavailable (not a git repo or git not installed)
|
|
277
|
+
logger.debug(f"Could not fetch git history: {e}")
|
|
278
|
+
pass
|
|
276
279
|
|
|
277
280
|
return context
|
|
278
281
|
|
|
@@ -291,7 +294,7 @@ def parse_ai_calls(file_path: str, content: str) -> list[dict[str, Any]]:
|
|
|
291
294
|
"code_snippet": content[:500], # First 500 chars as sample
|
|
292
295
|
"prompt_size": len(content),
|
|
293
296
|
"conversation_id": None, # Could detect from context
|
|
294
|
-
}
|
|
297
|
+
},
|
|
295
298
|
)
|
|
296
299
|
|
|
297
300
|
return calls
|
|
@@ -320,7 +323,6 @@ def parse_git_history(git_output: str) -> list[dict[str, Any]]:
|
|
|
320
323
|
|
|
321
324
|
def prepare_wizard_context(wizard_name: str, full_context: dict[str, Any]) -> dict[str, Any]:
|
|
322
325
|
"""Prepare context specific to a wizard's requirements"""
|
|
323
|
-
|
|
324
326
|
base_context = {
|
|
325
327
|
"project_path": full_context["project_path"],
|
|
326
328
|
"version_history": full_context.get("version_history", []),
|
|
@@ -332,7 +334,7 @@ def prepare_wizard_context(wizard_name: str, full_context: dict[str, Any]) -> di
|
|
|
332
334
|
"prompt_files": full_context.get("prompt_files", []),
|
|
333
335
|
}
|
|
334
336
|
|
|
335
|
-
|
|
337
|
+
if wizard_name == "context_window":
|
|
336
338
|
return {
|
|
337
339
|
**base_context,
|
|
338
340
|
"ai_calls": full_context.get("ai_calls", []),
|
|
@@ -341,14 +343,14 @@ def prepare_wizard_context(wizard_name: str, full_context: dict[str, Any]) -> di
|
|
|
341
343
|
"model_name": "claude-3-sonnet",
|
|
342
344
|
}
|
|
343
345
|
|
|
344
|
-
|
|
346
|
+
if wizard_name == "collaboration_pattern":
|
|
345
347
|
return {
|
|
346
348
|
**base_context,
|
|
347
349
|
"ai_integration_files": full_context.get("ai_integration_files", []),
|
|
348
350
|
"ai_usage_patterns": full_context.get("ai_usage_patterns", []),
|
|
349
351
|
}
|
|
350
352
|
|
|
351
|
-
|
|
353
|
+
if wizard_name == "ai_documentation":
|
|
352
354
|
return {
|
|
353
355
|
**base_context,
|
|
354
356
|
"documentation_files": full_context.get("documentation_files", []),
|
|
@@ -360,7 +362,6 @@ def prepare_wizard_context(wizard_name: str, full_context: dict[str, Any]) -> di
|
|
|
360
362
|
|
|
361
363
|
def display_wizard_results(wizard, result: dict[str, Any], verbose: bool):
|
|
362
364
|
"""Display wizard results in human-readable format"""
|
|
363
|
-
|
|
364
365
|
# Issues
|
|
365
366
|
issues = result.get("issues", [])
|
|
366
367
|
if issues:
|
|
@@ -461,7 +462,7 @@ def list_wizards():
|
|
|
461
462
|
print(f"\n{Colors.BOLD}{wizard_id}{Colors.END}")
|
|
462
463
|
print(f" Name: {info['name']}")
|
|
463
464
|
print(
|
|
464
|
-
f" Level: {info['empathy_level']} ({'Anticipatory' if info['empathy_level'] == 4 else 'Other'})"
|
|
465
|
+
f" Level: {info['empathy_level']} ({'Anticipatory' if info['empathy_level'] == 4 else 'Other'})",
|
|
465
466
|
)
|
|
466
467
|
print(f" Category: {info.get('category', 'N/A')}")
|
|
467
468
|
|
|
@@ -520,10 +521,15 @@ Examples:
|
|
|
520
521
|
analyze_parser = subparsers.add_parser("analyze", help="Analyze a project")
|
|
521
522
|
analyze_parser.add_argument("path", help="Path to project")
|
|
522
523
|
analyze_parser.add_argument(
|
|
523
|
-
"--wizards",
|
|
524
|
+
"--wizards",
|
|
525
|
+
help="Comma-separated list of wizards to run",
|
|
526
|
+
default=None,
|
|
524
527
|
)
|
|
525
528
|
analyze_parser.add_argument(
|
|
526
|
-
"--output",
|
|
529
|
+
"--output",
|
|
530
|
+
choices=["text", "json"],
|
|
531
|
+
default="text",
|
|
532
|
+
help="Output format",
|
|
527
533
|
)
|
|
528
534
|
analyze_parser.add_argument("--verbose", action="store_true", help="Show detailed output")
|
|
529
535
|
|
|
@@ -552,21 +558,20 @@ Examples:
|
|
|
552
558
|
wizard_names=wizard_names,
|
|
553
559
|
output_format=args.output,
|
|
554
560
|
verbose=args.verbose,
|
|
555
|
-
)
|
|
561
|
+
),
|
|
556
562
|
)
|
|
557
563
|
|
|
558
|
-
|
|
564
|
+
if args.command == "list-wizards":
|
|
559
565
|
return list_wizards()
|
|
560
566
|
|
|
561
|
-
|
|
567
|
+
if args.command == "wizard-info":
|
|
562
568
|
return wizard_info(args.wizard_id)
|
|
563
569
|
|
|
564
570
|
return 0
|
|
565
571
|
|
|
566
572
|
|
|
567
573
|
def scan_command():
|
|
568
|
-
"""
|
|
569
|
-
Entry point for empathy-scan command (converted from bin/empathy-scan).
|
|
574
|
+
"""Entry point for empathy-scan command (converted from bin/empathy-scan).
|
|
570
575
|
One-click security & performance scanner.
|
|
571
576
|
"""
|
|
572
577
|
logger.info("Empathy Framework security and performance scanner started")
|
|
@@ -646,7 +651,9 @@ def scan_command():
|
|
|
646
651
|
|
|
647
652
|
for wizard_name, wizard in wizards:
|
|
648
653
|
result = wizard.run_full_analysis(
|
|
649
|
-
code=code,
|
|
654
|
+
code=code,
|
|
655
|
+
file_path=str(file_path),
|
|
656
|
+
language="python",
|
|
650
657
|
)
|
|
651
658
|
|
|
652
659
|
if result.issues:
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Software Development Plugin for Empathy Framework
|
|
1
|
+
"""Software Development Plugin for Empathy Framework
|
|
3
2
|
|
|
4
3
|
This plugin provides 16+ Coach wizards for code analysis,
|
|
5
4
|
demonstrating Level 4 Anticipatory Empathy in software development.
|
|
@@ -25,8 +24,7 @@ logger = logging.getLogger(__name__)
|
|
|
25
24
|
|
|
26
25
|
|
|
27
26
|
class SoftwarePlugin(BasePlugin):
|
|
28
|
-
"""
|
|
29
|
-
Software Development Domain Plugin
|
|
27
|
+
"""Software Development Domain Plugin
|
|
30
28
|
|
|
31
29
|
Provides wizards for:
|
|
32
30
|
- Security analysis
|
|
@@ -59,8 +57,7 @@ class SoftwarePlugin(BasePlugin):
|
|
|
59
57
|
)
|
|
60
58
|
|
|
61
59
|
def register_wizards(self) -> dict[str, type[BaseWizard]]:
|
|
62
|
-
"""
|
|
63
|
-
Register all software development wizards.
|
|
60
|
+
"""Register all software development wizards.
|
|
64
61
|
|
|
65
62
|
In our experience building these wizards, we found that the framework
|
|
66
63
|
enables a fundamental shift: instead of reactive debugging, the system
|
|
@@ -157,8 +154,7 @@ class SoftwarePlugin(BasePlugin):
|
|
|
157
154
|
return wizards
|
|
158
155
|
|
|
159
156
|
def register_patterns(self) -> dict:
|
|
160
|
-
"""
|
|
161
|
-
Register software development patterns.
|
|
157
|
+
"""Register software development patterns.
|
|
162
158
|
|
|
163
159
|
These patterns were learned from real-world usage and enable
|
|
164
160
|
cross-domain learning (Level 5 Systems Empathy).
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
agents/compliance_anticipation_agent.py,sha256=p8ZjJqTwnbv9e6PddNV20Ee-d80gqdJ7FGDho_K2viY,48738
|
|
2
|
-
agents/epic_integration_wizard.py,sha256=axhSisp72Yl8gcgNQBrk-c4heVtTzGQzzD_a5lqALAM,17329
|
|
3
|
-
agents/trust_building_behaviors.py,sha256=UqTlMLwEJ7xJ5IMgdAoNAvOnA_Do4GRQuRaUwLwWLdY,33109
|
|
4
|
-
agents/code_inspection/patterns/inspection/recurring_B112.json,sha256=i0Oy4i8FoNb7wghhLJBscuac6dRrWCgjmxOQJejiJqk,745
|
|
5
|
-
agents/code_inspection/patterns/inspection/recurring_F541.json,sha256=zKKZs_6BkDRslzEuor78BS1nr49oUR426r2MQMOVUXs,492
|
|
6
|
-
agents/code_inspection/patterns/inspection/recurring_FORMAT.json,sha256=o-Xe8X5gbHvZyPXcZPpYam7icVYx0fwQIMX9YHVtg70,1490
|
|
7
|
-
agents/code_inspection/patterns/inspection/recurring_bug_20250822_def456.json,sha256=-ZMxXDBqXFLX1DXe4p1yI5U6lMwn-zH2zmLZB8Ylwgc,464
|
|
8
|
-
agents/code_inspection/patterns/inspection/recurring_bug_20250915_abc123.json,sha256=ek_2bKCUSwdHoyHM3xEWEC_4IaJO9HAS_51oUI7lRfU,464
|
|
9
|
-
agents/code_inspection/patterns/inspection/recurring_bug_20251212_3c5b9951.json,sha256=fAVGiraItm_ltT_ULR4ueSQJ2k4BYc8rcU69hhddSGE,469
|
|
10
|
-
agents/code_inspection/patterns/inspection/recurring_bug_20251212_97c0f72f.json,sha256=YkH2fZXGVGv-xv0pw0W8qmRxvrdRdSIgnukfzIXsCTU,469
|
|
11
|
-
agents/code_inspection/patterns/inspection/recurring_bug_20251212_a0871d53.json,sha256=JoBXmzdcFAX6DBGlM3Nb2430D8FWFLR3Mx66yYFwb6I,469
|
|
12
|
-
agents/code_inspection/patterns/inspection/recurring_bug_20251212_a9b6ec41.json,sha256=RnqaCoqGdNUVN36hx2tlyRMulzCuzXvpqNMYOPZLTwk,469
|
|
13
|
-
agents/code_inspection/patterns/inspection/recurring_bug_null_001.json,sha256=yztgivhfu8JRevB8AleGmNWSJpLUtWVRnZN3bMIJoLU,442
|
|
14
|
-
agents/code_inspection/patterns/inspection/recurring_builtin.json,sha256=ax-DHlUPqP3_gZK7mpEmn0VMqieQ4IikrY4bWaY-Xws,405
|
|
15
|
-
coach_wizards/__init__.py,sha256=T228pZI58QXwvXBDoq0sijNM1bLPElOWuhjcQ_kyIC0,1446
|
|
16
|
-
coach_wizards/accessibility_wizard.py,sha256=PCMO-FjsppfVatpyEqdqpki6pcJcm-VksOHCmYhvRvo,2622
|
|
17
|
-
coach_wizards/api_wizard.py,sha256=1j5yVZIar4n8Lp9l1TOr2qYeAb_mBjkpiVYimo6sBx0,2556
|
|
18
|
-
coach_wizards/base_wizard.py,sha256=OSZOX1ZVWH1hhAUrHOBDvx3WBtA7GjtA-Mm0u-1Umqo,5821
|
|
19
|
-
coach_wizards/cicd_wizard.py,sha256=vAgkWEBpqCbDOxPjBg215OwpFy2mZ0t-EkDX3wmykN0,2483
|
|
20
|
-
coach_wizards/compliance_wizard.py,sha256=amZih3Mya8fGJIXwydJTDMysM8An6fKWg4H4ERDIsmw,2576
|
|
21
|
-
coach_wizards/database_wizard.py,sha256=kIPVDnShzAjjC17kNSDnWyWBQGIKQahnZ77VuaYKacY,2586
|
|
22
|
-
coach_wizards/debugging_wizard.py,sha256=Jrm4nl_w3EQUs28R6cmW0enUY3wfpBWO_o3KrxEFC4w,2605
|
|
23
|
-
coach_wizards/documentation_wizard.py,sha256=MSQzdup-o2cjbyTlaM__eb7EJKJfspPrND4hhq5eCDo,2629
|
|
24
|
-
coach_wizards/generate_wizards.py,sha256=-AS30t6IPFH3G1MHxUsVGJ-uJLoYLFIZSfvrb0bQljk,12375
|
|
25
|
-
coach_wizards/localization_wizard.py,sha256=qNxCea02NfvNrjqa4B7rejwgcEhP_m0kWK5SmHFhf7s,6035
|
|
26
|
-
coach_wizards/migration_wizard.py,sha256=V3jYOXAH_6dzGdlzqtpKuiAyNCvcHc5Ky53WOL_MVk0,2585
|
|
27
|
-
coach_wizards/monitoring_wizard.py,sha256=bxCrSs4aNEytC0YyFK_nrf6RVTAS5vKCkD3eItP7GVo,2557
|
|
28
|
-
coach_wizards/observability_wizard.py,sha256=cN7EyemptnzDO9Y-R1-Lzmc1uXZGVw2UlQ_xQaDuzM0,2622
|
|
29
|
-
coach_wizards/performance_wizard.py,sha256=8CerXAg7nO3ze6NwqaVXHTFPKufubSniF0m5Mmd1-5A,2648
|
|
30
|
-
coach_wizards/prompt_engineering_wizard.py,sha256=wxqZ848_EdbJJVyqmhPZ0OV1h5qoZANmJyoI6ORqmTM,21358
|
|
31
|
-
coach_wizards/refactoring_wizard.py,sha256=1AuRyX45KI63n_-fvvbRXamqvPbrB-O1B7TPPc2CcDQ,2627
|
|
32
|
-
coach_wizards/scaling_wizard.py,sha256=yLULCkflLoBKS4hOSBPQuKKGBGHgKExnuEp5WLTIY-8,2596
|
|
33
|
-
coach_wizards/security_wizard.py,sha256=tr1iq0egAMLCM-wOFhTDN5dHQRFuhSshXSkv17Jm7eM,2603
|
|
34
|
-
coach_wizards/testing_wizard.py,sha256=M2RtaTa1WHsk42svJAEZpLySU3PXJJZn2jigouMJrG0,2561
|
|
35
|
-
empathy_framework-3.5.6.dist-info/licenses/LICENSE,sha256=IJ9eeI5KSrD5P7alsn7sI_6_1bDihxBA5S4Sen4jf2k,4937
|
|
36
|
-
empathy_healthcare_plugin/__init__.py,sha256=FvVcD7WQTlmCCLgSPfM-FPT2l-ma1oAACBZWhtYFAUA,296
|
|
37
|
-
empathy_healthcare_plugin/protocols/cardiac.json,sha256=uShOvI2RQJYLZacLT2R_aHfsjvJdyCu_gYfpMfK3N74,2088
|
|
38
|
-
empathy_healthcare_plugin/protocols/post_operative.json,sha256=nqh3ydPY8FNSLv-Q3QmH8Dsyc1c4LvQxUSP84B8W6xk,2021
|
|
39
|
-
empathy_healthcare_plugin/protocols/respiratory.json,sha256=wNDprggFDGRxxHNwchC19N8aoyaN74RnhYN7lNookDI,2136
|
|
40
|
-
empathy_healthcare_plugin/protocols/sepsis.json,sha256=yXKt8QmDaAeTgHitqJJ-N9J9pkHRqGxZM_jJl_wDG6A,3631
|
|
41
|
-
empathy_llm_toolkit/README.md,sha256=wKfp80nOvQkyU2qkBMAdF9cPPR3iaHuia_2AfiXVaFM,12273
|
|
42
|
-
empathy_llm_toolkit/__init__.py,sha256=hpDQmnshhXdcTyvdGRDNv6hqLSzj0RBPGixFHvmAjcQ,705
|
|
43
|
-
empathy_llm_toolkit/claude_memory.py,sha256=L4XaIDR_5yugYz4ITJw3ofWBxYQWeI3W3Cfs09TB2_Y,14872
|
|
44
|
-
empathy_llm_toolkit/code_health.py,sha256=hc0dRN00xb4An3KPXAbNp3Tp076a2GnJ1MlPGH7HHM0,42438
|
|
45
|
-
empathy_llm_toolkit/contextual_patterns.py,sha256=pC2LU4z8dNRcCj0TWZB_LSyXeAdt7me5WKmdt2dfXFk,12056
|
|
46
|
-
empathy_llm_toolkit/core.py,sha256=Ts8OUASBLjNxiRvDbkvCiXo5aN-lmYRXUVQO_OW4b7w,34499
|
|
47
|
-
empathy_llm_toolkit/git_pattern_extractor.py,sha256=L_BFi5ZLOhKbXZqLon4bJpHRrZk4dt-ICQ_R3YQftZg,14756
|
|
48
|
-
empathy_llm_toolkit/levels.py,sha256=8iH_mPRh72yFZ0wJgSB6K20XZTdfnw4gBanX6_4P6n8,7178
|
|
49
|
-
empathy_llm_toolkit/pattern_confidence.py,sha256=M9w37N621c7gA21U0cI0ApaV9TFKoQtP4dhUfjmzf7I,14207
|
|
50
|
-
empathy_llm_toolkit/pattern_resolver.py,sha256=uvrRZfROMQkaghTLHr7b6OtB6MlW-mgAV3_Il0LWBMk,9330
|
|
51
|
-
empathy_llm_toolkit/pattern_summary.py,sha256=q3gPMZtk5TIG9hs61mEZzaBtpry0qVfbu2lXryunhQs,12265
|
|
52
|
-
empathy_llm_toolkit/providers.py,sha256=vfN5u_9e4BVUj8hR4HSZTGOLPfiH4k7ffk_Q7Zqf57o,19811
|
|
53
|
-
empathy_llm_toolkit/session_status.py,sha256=pJwqHwbVwR2Q6coRkB_34CWRCMoF-r4-YBtQWEO1Mj8,25724
|
|
54
|
-
empathy_llm_toolkit/state.py,sha256=oi8bPqUHkmfgkfT4_4eD1ndIGH_THyLQDYlIWZLUx5s,8051
|
|
55
|
-
empathy_os/__init__.py,sha256=pvaca4oCfdL4MG5WO-RKJeXBOk0oj02Mhh_E0h7zSyY,5896
|
|
56
|
-
empathy_os/cli.py,sha256=BKZHQeOLcocO6FIHn5wgnEK84KY4APlGulWwL2tpKOE,93218
|
|
57
|
-
empathy_os/cli_unified.py,sha256=YLNjgZRaeaJn72_4vUpkDK9g70as0upfyDQTmcC7aeY,14029
|
|
58
|
-
empathy_os/config.py,sha256=itgEYHR3QOxtjObHqnYGoQ48863Mf16UoGPyc_l8gNE,14803
|
|
59
|
-
empathy_os/coordination.py,sha256=0jKt2DzzJmFjpXJs4pMXBcUktCFHsa9i3rkXzXxykGk,28656
|
|
60
|
-
empathy_os/core.py,sha256=kL_37DajqIV1_b0ldee8rGG0xUTrSzAqYuQ4dowSxuw,53229
|
|
61
|
-
empathy_os/cost_tracker.py,sha256=VwjkyKEm-gbmyO7wQ88t82RNZfc-LCp0vpK699Giqp0,12575
|
|
62
|
-
empathy_os/discovery.py,sha256=7cIZAOpbgtirjMvVKASZv4ZN87_BaLQwoX77Z80VWIQ,9848
|
|
63
|
-
empathy_os/emergence.py,sha256=lLaPZlKAouYL3SgnjckloCqTRLYvnZjYMkWIoljxLEY,11394
|
|
64
|
-
empathy_os/exceptions.py,sha256=SvfXisnEZdXv3YHNmCJRoDbyWFryoPst4Qnjy3lhau8,3360
|
|
65
|
-
empathy_os/feedback_loops.py,sha256=g_fv7r5Z6RCPkzHkZc_lBDNbPW7x2lPNpLimCpadcLE,13356
|
|
66
|
-
empathy_os/levels.py,sha256=9LYlDEdyIUlGol0riBMyTKBbTAzqzPaVVql3JK773Lk,19188
|
|
67
|
-
empathy_os/leverage_points.py,sha256=dhZThMKtYIQTxhsC8hnim36cpS98GgrSd2xowPOJGyg,16736
|
|
68
|
-
empathy_os/logging_config.py,sha256=U_MylJblr2jMfYmsK6z4WKd9Z6ZZ1G0kxzq9cNPGLEk,8135
|
|
69
|
-
empathy_os/monitoring.py,sha256=76Fiwqd8prqi6H_mMX79_yEPbfbPdx58E9ZfLld6fvw,13434
|
|
70
|
-
empathy_os/pattern_library.py,sha256=jUeWRnRHbhB05Rm9kL-OFdMajRCOqOzOb9ow_23JdY0,14040
|
|
71
|
-
empathy_os/persistence.py,sha256=2jNqPmW6TrCH2quYph2SVMQnAnhBDDVk9DqNuEhLhGE,17637
|
|
72
|
-
empathy_os/platform_utils.py,sha256=8R35nql5f1cuMwWz9JKM_Nx_Gf9rGhCiAleEmIk8WVY,7343
|
|
73
|
-
empathy_os/redis_config.py,sha256=sX7EAXxRd8pL3r1E-Oa5yke_j-wYIQ1PI9jzaNZjlrs,9778
|
|
74
|
-
empathy_os/redis_memory.py,sha256=lWS_F4FeDkmEI-jIgkPTzs3D8TTDB0627WsOxYMT-XM,23276
|
|
75
|
-
empathy_os/templates.py,sha256=ap4u9i5O9KA83wWLfoUCS7phDHKb6wj8M1Zcm218lN0,17069
|
|
76
|
-
empathy_os/trust_building.py,sha256=8ZvNwJmeDyKeUIkk_331M9jwKcqrsn6K43gnGtnIXbM,18790
|
|
77
|
-
empathy_os/workflow_commands.py,sha256=Kqyr8ICTsx4S-_ThXB52SYzH1mYFsHGVDYiG2KgkQGo,21904
|
|
78
|
-
empathy_software_plugin/SOFTWARE_PLUGIN_README.md,sha256=RXIOB9Mt-8JrfGAA3ZUuRPT34sThubrwUgg5iNcSKIc,22591
|
|
79
|
-
empathy_software_plugin/__init__.py,sha256=Ylyj95pSsoN9Zasam96DH61uBHoMJh3kbhO7k_VaCWo,310
|
|
80
|
-
empathy_software_plugin/cli.py,sha256=GrZWpnFJ9allM9sYrh8rSxSlVDU6RZVnEy4FYg-dSG8,22366
|
|
81
|
-
empathy_software_plugin/plugin.py,sha256=NNZTILE5Npo4SahA4F_3awIizLHI32_wWTFAutvmsqQ,6700
|
|
82
|
-
wizards/__init__.py,sha256=5JJ6rtS5mwJtuZIgO2sYHZlCy0XJP2eyyCK5zMD6ZAc,2452
|
|
83
|
-
wizards/admission_assessment_wizard.py,sha256=-Th9bwu6Sd6V2jA4fciK35QpoFc40U1quZHDMdOH93U,23609
|
|
84
|
-
wizards/care_plan.py,sha256=YVjjmbdUptOSkgkbhCIioHbcgISgzvIhlRiHZ3xvUJQ,10728
|
|
85
|
-
wizards/clinical_assessment.py,sha256=LrH_ATyYw8e1IWPwR9GNtc4acnqLC3PaqTH-RMGtRQE,29581
|
|
86
|
-
wizards/discharge_planning.py,sha256=17oN6EvSaRS8kSGV4xkXmu_wx4qOAOzMOUnWAzHa3_Y,2364
|
|
87
|
-
wizards/discharge_summary_wizard.py,sha256=47hFpLNUXmRYPaaWK7ptVCtwHD8AuY8v-bbPzDeTO-c,17916
|
|
88
|
-
wizards/dosage_calculation.py,sha256=UST0Y2hwRPcEomqXm6u_TxcDO6tvBvKdYb3lVuzGZUQ,20167
|
|
89
|
-
wizards/incident_report_wizard.py,sha256=IbKcvtDynNTDSFSN4SWG4FpXpyQrjaRE4dADMvHDjQk,17131
|
|
90
|
-
wizards/medication_reconciliation.py,sha256=QYF-_k85oHNU9VHvHJ8XxLxBops9j0b2EI9_G5TvWxI,2708
|
|
91
|
-
wizards/nursing_assessment.py,sha256=WHh-co87ZaFgZRl7Ss1ldJ4lBanDm_3ePVpqWkdT0m4,5967
|
|
92
|
-
wizards/patient_education.py,sha256=1Tkh_z_R4OxgsUaHU8qmlsqS1EYR-WN_dLl3Hvrpkkk,23493
|
|
93
|
-
wizards/quality_improvement.py,sha256=eY4KEbHQOfvNI8ybgFwDR5BmRDAw7fQ-x6dtFmIUyik,27690
|
|
94
|
-
wizards/sbar_report.py,sha256=sVkiF6Vq3FFYqXIdI-ueN2HCMiGOTC519jcf1ccqEUQ,11519
|
|
95
|
-
wizards/sbar_wizard.py,sha256=CJ63JAXwcfBf6C3aYyxY2LODbARP9GPl0ZGJWLbx88E,21790
|
|
96
|
-
wizards/shift_handoff_wizard.py,sha256=SkoNB0nLQGg92yz4j1j3NBR2mGVe_rw1pTjOFDy-JH0,19092
|
|
97
|
-
wizards/soap_note_wizard.py,sha256=DBzuuuOvIONhwdfn8jaE4PCuGeKsFwM65XTb6gKFIy4,23572
|
|
98
|
-
wizards/treatment_plan.py,sha256=t2Qk5eCa1gobEUaBztnwem_p9OuJK5BKqJ-Po8vXuns,512
|
|
99
|
-
empathy_framework-3.5.6.dist-info/METADATA,sha256=Ay9yi3cPZaMwrSBVgh8V8syC3YzRy8mF76AEQcEBrVw,30238
|
|
100
|
-
empathy_framework-3.5.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
101
|
-
empathy_framework-3.5.6.dist-info/entry_points.txt,sha256=zMu7sKCiLndbEEXjTecltS-1P_JZoEUKrifuRBBbroc,1268
|
|
102
|
-
empathy_framework-3.5.6.dist-info/top_level.txt,sha256=8zHB-_f0MI2K55LIEjCeaFNcog3_KgLBa_dDfzE8ESI,110
|
|
103
|
-
empathy_framework-3.5.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|