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.
Files changed (267) 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.7.1.dist-info}/METADATA +20 -2
  4. empathy_framework-3.7.1.dist-info/RECORD +327 -0
  5. {empathy_framework-3.7.0.dist-info → empathy_framework-3.7.1.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/cli.py +118 -8
  64. empathy_os/cli_unified.py +121 -1
  65. empathy_os/config/__init__.py +63 -0
  66. empathy_os/config/xml_config.py +239 -0
  67. empathy_os/dashboard/__init__.py +15 -0
  68. empathy_os/dashboard/server.py +743 -0
  69. empathy_os/memory/__init__.py +195 -0
  70. empathy_os/memory/claude_memory.py +466 -0
  71. empathy_os/memory/config.py +224 -0
  72. empathy_os/memory/control_panel.py +1298 -0
  73. empathy_os/memory/edges.py +179 -0
  74. empathy_os/memory/graph.py +567 -0
  75. empathy_os/memory/long_term.py +1193 -0
  76. empathy_os/memory/nodes.py +179 -0
  77. empathy_os/memory/redis_bootstrap.py +540 -0
  78. empathy_os/memory/security/__init__.py +31 -0
  79. empathy_os/memory/security/audit_logger.py +930 -0
  80. empathy_os/memory/security/pii_scrubber.py +640 -0
  81. empathy_os/memory/security/secrets_detector.py +678 -0
  82. empathy_os/memory/short_term.py +2119 -0
  83. empathy_os/memory/storage/__init__.py +15 -0
  84. empathy_os/memory/summary_index.py +583 -0
  85. empathy_os/memory/unified.py +619 -0
  86. empathy_os/metrics/__init__.py +12 -0
  87. empathy_os/metrics/prompt_metrics.py +190 -0
  88. empathy_os/models/__init__.py +136 -0
  89. empathy_os/models/__main__.py +13 -0
  90. empathy_os/models/cli.py +655 -0
  91. empathy_os/models/empathy_executor.py +354 -0
  92. empathy_os/models/executor.py +252 -0
  93. empathy_os/models/fallback.py +671 -0
  94. empathy_os/models/provider_config.py +563 -0
  95. empathy_os/models/registry.py +382 -0
  96. empathy_os/models/tasks.py +302 -0
  97. empathy_os/models/telemetry.py +548 -0
  98. empathy_os/models/token_estimator.py +378 -0
  99. empathy_os/models/validation.py +274 -0
  100. empathy_os/monitoring/__init__.py +52 -0
  101. empathy_os/monitoring/alerts.py +23 -0
  102. empathy_os/monitoring/alerts_cli.py +268 -0
  103. empathy_os/monitoring/multi_backend.py +271 -0
  104. empathy_os/monitoring/otel_backend.py +363 -0
  105. empathy_os/optimization/__init__.py +19 -0
  106. empathy_os/optimization/context_optimizer.py +272 -0
  107. empathy_os/plugins/__init__.py +28 -0
  108. empathy_os/plugins/base.py +361 -0
  109. empathy_os/plugins/registry.py +268 -0
  110. empathy_os/project_index/__init__.py +30 -0
  111. empathy_os/project_index/cli.py +335 -0
  112. empathy_os/project_index/crew_integration.py +430 -0
  113. empathy_os/project_index/index.py +425 -0
  114. empathy_os/project_index/models.py +501 -0
  115. empathy_os/project_index/reports.py +473 -0
  116. empathy_os/project_index/scanner.py +538 -0
  117. empathy_os/prompts/__init__.py +61 -0
  118. empathy_os/prompts/config.py +77 -0
  119. empathy_os/prompts/context.py +177 -0
  120. empathy_os/prompts/parser.py +285 -0
  121. empathy_os/prompts/registry.py +313 -0
  122. empathy_os/prompts/templates.py +208 -0
  123. empathy_os/resilience/__init__.py +56 -0
  124. empathy_os/resilience/circuit_breaker.py +256 -0
  125. empathy_os/resilience/fallback.py +179 -0
  126. empathy_os/resilience/health.py +300 -0
  127. empathy_os/resilience/retry.py +209 -0
  128. empathy_os/resilience/timeout.py +135 -0
  129. empathy_os/routing/__init__.py +43 -0
  130. empathy_os/routing/chain_executor.py +433 -0
  131. empathy_os/routing/classifier.py +217 -0
  132. empathy_os/routing/smart_router.py +234 -0
  133. empathy_os/routing/wizard_registry.py +307 -0
  134. empathy_os/trust/__init__.py +28 -0
  135. empathy_os/trust/circuit_breaker.py +579 -0
  136. empathy_os/validation/__init__.py +19 -0
  137. empathy_os/validation/xml_validator.py +281 -0
  138. empathy_os/wizard_factory_cli.py +170 -0
  139. empathy_os/workflows/__init__.py +360 -0
  140. empathy_os/workflows/base.py +1530 -0
  141. empathy_os/workflows/bug_predict.py +962 -0
  142. empathy_os/workflows/code_review.py +960 -0
  143. empathy_os/workflows/code_review_adapters.py +310 -0
  144. empathy_os/workflows/code_review_pipeline.py +720 -0
  145. empathy_os/workflows/config.py +600 -0
  146. empathy_os/workflows/dependency_check.py +648 -0
  147. empathy_os/workflows/document_gen.py +1069 -0
  148. empathy_os/workflows/documentation_orchestrator.py +1205 -0
  149. empathy_os/workflows/health_check.py +679 -0
  150. empathy_os/workflows/keyboard_shortcuts/__init__.py +39 -0
  151. empathy_os/workflows/keyboard_shortcuts/generators.py +386 -0
  152. empathy_os/workflows/keyboard_shortcuts/parsers.py +414 -0
  153. empathy_os/workflows/keyboard_shortcuts/prompts.py +295 -0
  154. empathy_os/workflows/keyboard_shortcuts/schema.py +193 -0
  155. empathy_os/workflows/keyboard_shortcuts/workflow.py +505 -0
  156. empathy_os/workflows/manage_documentation.py +804 -0
  157. empathy_os/workflows/new_sample_workflow1.py +146 -0
  158. empathy_os/workflows/new_sample_workflow1_README.md +150 -0
  159. empathy_os/workflows/perf_audit.py +687 -0
  160. empathy_os/workflows/pr_review.py +748 -0
  161. empathy_os/workflows/progress.py +445 -0
  162. empathy_os/workflows/progress_server.py +322 -0
  163. empathy_os/workflows/refactor_plan.py +691 -0
  164. empathy_os/workflows/release_prep.py +808 -0
  165. empathy_os/workflows/research_synthesis.py +404 -0
  166. empathy_os/workflows/secure_release.py +585 -0
  167. empathy_os/workflows/security_adapters.py +297 -0
  168. empathy_os/workflows/security_audit.py +1050 -0
  169. empathy_os/workflows/step_config.py +234 -0
  170. empathy_os/workflows/test5.py +125 -0
  171. empathy_os/workflows/test5_README.md +158 -0
  172. empathy_os/workflows/test_gen.py +1855 -0
  173. empathy_os/workflows/test_lifecycle.py +526 -0
  174. empathy_os/workflows/test_maintenance.py +626 -0
  175. empathy_os/workflows/test_maintenance_cli.py +590 -0
  176. empathy_os/workflows/test_maintenance_crew.py +821 -0
  177. empathy_os/workflows/xml_enhanced_crew.py +285 -0
  178. empathy_software_plugin/cli/__init__.py +120 -0
  179. empathy_software_plugin/cli/inspect.py +362 -0
  180. empathy_software_plugin/cli.py +3 -1
  181. empathy_software_plugin/wizards/__init__.py +42 -0
  182. empathy_software_plugin/wizards/advanced_debugging_wizard.py +392 -0
  183. empathy_software_plugin/wizards/agent_orchestration_wizard.py +511 -0
  184. empathy_software_plugin/wizards/ai_collaboration_wizard.py +503 -0
  185. empathy_software_plugin/wizards/ai_context_wizard.py +441 -0
  186. empathy_software_plugin/wizards/ai_documentation_wizard.py +503 -0
  187. empathy_software_plugin/wizards/base_wizard.py +288 -0
  188. empathy_software_plugin/wizards/book_chapter_wizard.py +519 -0
  189. empathy_software_plugin/wizards/code_review_wizard.py +606 -0
  190. empathy_software_plugin/wizards/debugging/__init__.py +50 -0
  191. empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +414 -0
  192. empathy_software_plugin/wizards/debugging/config_loaders.py +442 -0
  193. empathy_software_plugin/wizards/debugging/fix_applier.py +469 -0
  194. empathy_software_plugin/wizards/debugging/language_patterns.py +383 -0
  195. empathy_software_plugin/wizards/debugging/linter_parsers.py +470 -0
  196. empathy_software_plugin/wizards/debugging/verification.py +369 -0
  197. empathy_software_plugin/wizards/enhanced_testing_wizard.py +537 -0
  198. empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +816 -0
  199. empathy_software_plugin/wizards/multi_model_wizard.py +501 -0
  200. empathy_software_plugin/wizards/pattern_extraction_wizard.py +422 -0
  201. empathy_software_plugin/wizards/pattern_retriever_wizard.py +400 -0
  202. empathy_software_plugin/wizards/performance/__init__.py +9 -0
  203. empathy_software_plugin/wizards/performance/bottleneck_detector.py +221 -0
  204. empathy_software_plugin/wizards/performance/profiler_parsers.py +278 -0
  205. empathy_software_plugin/wizards/performance/trajectory_analyzer.py +429 -0
  206. empathy_software_plugin/wizards/performance_profiling_wizard.py +305 -0
  207. empathy_software_plugin/wizards/prompt_engineering_wizard.py +425 -0
  208. empathy_software_plugin/wizards/rag_pattern_wizard.py +461 -0
  209. empathy_software_plugin/wizards/security/__init__.py +32 -0
  210. empathy_software_plugin/wizards/security/exploit_analyzer.py +290 -0
  211. empathy_software_plugin/wizards/security/owasp_patterns.py +241 -0
  212. empathy_software_plugin/wizards/security/vulnerability_scanner.py +604 -0
  213. empathy_software_plugin/wizards/security_analysis_wizard.py +322 -0
  214. empathy_software_plugin/wizards/security_learning_wizard.py +740 -0
  215. empathy_software_plugin/wizards/tech_debt_wizard.py +726 -0
  216. empathy_software_plugin/wizards/testing/__init__.py +27 -0
  217. empathy_software_plugin/wizards/testing/coverage_analyzer.py +459 -0
  218. empathy_software_plugin/wizards/testing/quality_analyzer.py +531 -0
  219. empathy_software_plugin/wizards/testing/test_suggester.py +533 -0
  220. empathy_software_plugin/wizards/testing_wizard.py +274 -0
  221. hot_reload/README.md +473 -0
  222. hot_reload/__init__.py +62 -0
  223. hot_reload/config.py +84 -0
  224. hot_reload/integration.py +228 -0
  225. hot_reload/reloader.py +298 -0
  226. hot_reload/watcher.py +179 -0
  227. hot_reload/websocket.py +176 -0
  228. scaffolding/README.md +589 -0
  229. scaffolding/__init__.py +35 -0
  230. scaffolding/__main__.py +14 -0
  231. scaffolding/cli.py +240 -0
  232. test_generator/__init__.py +38 -0
  233. test_generator/__main__.py +14 -0
  234. test_generator/cli.py +226 -0
  235. test_generator/generator.py +325 -0
  236. test_generator/risk_analyzer.py +216 -0
  237. workflow_patterns/__init__.py +33 -0
  238. workflow_patterns/behavior.py +249 -0
  239. workflow_patterns/core.py +76 -0
  240. workflow_patterns/output.py +99 -0
  241. workflow_patterns/registry.py +255 -0
  242. workflow_patterns/structural.py +288 -0
  243. workflow_scaffolding/__init__.py +11 -0
  244. workflow_scaffolding/__main__.py +12 -0
  245. workflow_scaffolding/cli.py +206 -0
  246. workflow_scaffolding/generator.py +265 -0
  247. agents/code_inspection/patterns/inspection/recurring_B112.json +0 -18
  248. agents/code_inspection/patterns/inspection/recurring_F541.json +0 -16
  249. agents/code_inspection/patterns/inspection/recurring_FORMAT.json +0 -25
  250. agents/code_inspection/patterns/inspection/recurring_bug_20250822_def456.json +0 -16
  251. agents/code_inspection/patterns/inspection/recurring_bug_20250915_abc123.json +0 -16
  252. agents/code_inspection/patterns/inspection/recurring_bug_20251212_3c5b9951.json +0 -16
  253. agents/code_inspection/patterns/inspection/recurring_bug_20251212_97c0f72f.json +0 -16
  254. agents/code_inspection/patterns/inspection/recurring_bug_20251212_a0871d53.json +0 -16
  255. agents/code_inspection/patterns/inspection/recurring_bug_20251212_a9b6ec41.json +0 -16
  256. agents/code_inspection/patterns/inspection/recurring_bug_null_001.json +0 -16
  257. agents/code_inspection/patterns/inspection/recurring_builtin.json +0 -16
  258. agents/compliance_anticipation_agent.py +0 -1422
  259. agents/compliance_db.py +0 -339
  260. agents/epic_integration_wizard.py +0 -530
  261. agents/notifications.py +0 -291
  262. agents/trust_building_behaviors.py +0 -872
  263. empathy_framework-3.7.0.dist-info/RECORD +0 -105
  264. {empathy_framework-3.7.0.dist-info → empathy_framework-3.7.1.dist-info}/WHEEL +0 -0
  265. {empathy_framework-3.7.0.dist-info → empathy_framework-3.7.1.dist-info}/entry_points.txt +0 -0
  266. {empathy_framework-3.7.0.dist-info → empathy_framework-3.7.1.dist-info}/licenses/LICENSE +0 -0
  267. /empathy_os/{monitoring.py → agent_monitoring.py} +0 -0
@@ -0,0 +1,501 @@
1
+ """Project Index Data Models
2
+
3
+ Defines the structure of file metadata and project summaries.
4
+
5
+ Copyright 2025 Smart AI Memory, LLC
6
+ Licensed under Fair Source 0.9
7
+ """
8
+
9
+ from dataclasses import dataclass, field
10
+ from datetime import datetime
11
+ from enum import Enum
12
+ from typing import Any
13
+
14
+
15
+ class FileCategory(str, Enum):
16
+ """Categories of files in a project."""
17
+
18
+ SOURCE = "source" # Production code
19
+ TEST = "test" # Test files
20
+ CONFIG = "config" # Configuration files
21
+ DOCS = "docs" # Documentation
22
+ ASSET = "asset" # Static assets
23
+ GENERATED = "generated" # Auto-generated files
24
+ BUILD = "build" # Build artifacts
25
+ UNKNOWN = "unknown"
26
+
27
+
28
+ class TestRequirement(str, Enum):
29
+ """Whether a file requires tests."""
30
+
31
+ REQUIRED = "required" # Should have tests
32
+ OPTIONAL = "optional" # Tests nice to have
33
+ NOT_APPLICABLE = "not_applicable" # Doesn't need tests
34
+ EXCLUDED = "excluded" # Explicitly excluded
35
+
36
+
37
+ @dataclass
38
+ class FileRecord:
39
+ """Metadata record for a single file in the project.
40
+
41
+ This is the core data structure that workflows and agents
42
+ can read and write to track file state.
43
+ """
44
+
45
+ # Identity
46
+ path: str # Relative path from project root
47
+ name: str # File name
48
+ category: FileCategory = FileCategory.UNKNOWN
49
+ language: str = "" # python, typescript, etc.
50
+
51
+ # Testing metadata
52
+ test_requirement: TestRequirement = TestRequirement.REQUIRED
53
+ test_file_path: str | None = None
54
+ tests_exist: bool = False
55
+ test_count: int = 0
56
+ coverage_percent: float = 0.0
57
+
58
+ # Timestamps
59
+ last_modified: datetime | None = None
60
+ tests_last_modified: datetime | None = None
61
+ last_indexed: datetime | None = None
62
+
63
+ # Staleness (days since source changed but tests didn't)
64
+ staleness_days: int = 0
65
+ is_stale: bool = False
66
+
67
+ # Code metrics
68
+ lines_of_code: int = 0
69
+ lines_of_test: int = 0
70
+ complexity_score: float = 0.0
71
+
72
+ # Quality indicators
73
+ has_docstrings: bool = False
74
+ has_type_hints: bool = False
75
+ lint_issues: int = 0
76
+
77
+ # Dependencies
78
+ imports: list[str] = field(default_factory=list)
79
+ imported_by: list[str] = field(default_factory=list)
80
+ import_count: int = 0
81
+ imported_by_count: int = 0
82
+
83
+ # Impact scoring (higher = more critical)
84
+ impact_score: float = 0.0
85
+
86
+ # Custom metadata (for workflow-specific data)
87
+ metadata: dict[str, Any] = field(default_factory=dict)
88
+
89
+ # Tracking
90
+ needs_attention: bool = False
91
+ attention_reasons: list[str] = field(default_factory=list)
92
+
93
+ def to_dict(self) -> dict[str, Any]:
94
+ """Convert to dictionary for JSON serialization."""
95
+ return {
96
+ "path": self.path,
97
+ "name": self.name,
98
+ "category": self.category.value,
99
+ "language": self.language,
100
+ "test_requirement": self.test_requirement.value,
101
+ "test_file_path": self.test_file_path,
102
+ "tests_exist": self.tests_exist,
103
+ "test_count": self.test_count,
104
+ "coverage_percent": self.coverage_percent,
105
+ "last_modified": self.last_modified.isoformat() if self.last_modified else None,
106
+ "tests_last_modified": (
107
+ self.tests_last_modified.isoformat() if self.tests_last_modified else None
108
+ ),
109
+ "last_indexed": self.last_indexed.isoformat() if self.last_indexed else None,
110
+ "staleness_days": self.staleness_days,
111
+ "is_stale": self.is_stale,
112
+ "lines_of_code": self.lines_of_code,
113
+ "lines_of_test": self.lines_of_test,
114
+ "complexity_score": self.complexity_score,
115
+ "has_docstrings": self.has_docstrings,
116
+ "has_type_hints": self.has_type_hints,
117
+ "lint_issues": self.lint_issues,
118
+ "imports": self.imports,
119
+ "imported_by": self.imported_by,
120
+ "import_count": self.import_count,
121
+ "imported_by_count": self.imported_by_count,
122
+ "impact_score": self.impact_score,
123
+ "metadata": self.metadata,
124
+ "needs_attention": self.needs_attention,
125
+ "attention_reasons": self.attention_reasons,
126
+ }
127
+
128
+ @classmethod
129
+ def from_dict(cls, data: dict[str, Any]) -> "FileRecord":
130
+ """Create from dictionary."""
131
+ return cls(
132
+ path=data.get("path", ""),
133
+ name=data.get("name", ""),
134
+ category=FileCategory(data.get("category", "unknown")),
135
+ language=data.get("language", ""),
136
+ test_requirement=TestRequirement(data.get("test_requirement", "required")),
137
+ test_file_path=data.get("test_file_path"),
138
+ tests_exist=data.get("tests_exist", False),
139
+ test_count=data.get("test_count", 0),
140
+ coverage_percent=data.get("coverage_percent", 0.0),
141
+ last_modified=(
142
+ datetime.fromisoformat(data["last_modified"]) if data.get("last_modified") else None
143
+ ),
144
+ tests_last_modified=(
145
+ datetime.fromisoformat(data["tests_last_modified"])
146
+ if data.get("tests_last_modified")
147
+ else None
148
+ ),
149
+ last_indexed=(
150
+ datetime.fromisoformat(data["last_indexed"]) if data.get("last_indexed") else None
151
+ ),
152
+ staleness_days=data.get("staleness_days", 0),
153
+ is_stale=data.get("is_stale", False),
154
+ lines_of_code=data.get("lines_of_code", 0),
155
+ lines_of_test=data.get("lines_of_test", 0),
156
+ complexity_score=data.get("complexity_score", 0.0),
157
+ has_docstrings=data.get("has_docstrings", False),
158
+ has_type_hints=data.get("has_type_hints", False),
159
+ lint_issues=data.get("lint_issues", 0),
160
+ imports=data.get("imports", []),
161
+ imported_by=data.get("imported_by", []),
162
+ import_count=data.get("import_count", 0),
163
+ imported_by_count=data.get("imported_by_count", 0),
164
+ impact_score=data.get("impact_score", 0.0),
165
+ metadata=data.get("metadata", {}),
166
+ needs_attention=data.get("needs_attention", False),
167
+ attention_reasons=data.get("attention_reasons", []),
168
+ )
169
+
170
+
171
+ @dataclass
172
+ class ProjectSummary:
173
+ """High-level summary of project health.
174
+
175
+ Updated each time the index is regenerated.
176
+ """
177
+
178
+ # Counts
179
+ total_files: int = 0
180
+ source_files: int = 0
181
+ test_files: int = 0
182
+ config_files: int = 0
183
+ doc_files: int = 0
184
+
185
+ # Testing health
186
+ files_requiring_tests: int = 0
187
+ files_with_tests: int = 0
188
+ files_without_tests: int = 0
189
+ test_coverage_avg: float = 0.0
190
+ total_test_count: int = 0
191
+
192
+ # Staleness
193
+ stale_file_count: int = 0
194
+ avg_staleness_days: float = 0.0
195
+ most_stale_files: list[str] = field(default_factory=list)
196
+
197
+ # Code metrics
198
+ total_lines_of_code: int = 0
199
+ total_lines_of_test: int = 0
200
+ test_to_code_ratio: float = 0.0
201
+ avg_complexity: float = 0.0
202
+
203
+ # Quality
204
+ files_with_docstrings_pct: float = 0.0
205
+ files_with_type_hints_pct: float = 0.0
206
+ total_lint_issues: int = 0
207
+
208
+ # Impact analysis
209
+ high_impact_files: list[str] = field(default_factory=list)
210
+ critical_untested_files: list[str] = field(default_factory=list)
211
+
212
+ # Attention needed
213
+ files_needing_attention: int = 0
214
+ top_attention_files: list[str] = field(default_factory=list)
215
+
216
+ def to_dict(self) -> dict[str, Any]:
217
+ """Convert to dictionary."""
218
+ return {
219
+ "total_files": self.total_files,
220
+ "source_files": self.source_files,
221
+ "test_files": self.test_files,
222
+ "config_files": self.config_files,
223
+ "doc_files": self.doc_files,
224
+ "files_requiring_tests": self.files_requiring_tests,
225
+ "files_with_tests": self.files_with_tests,
226
+ "files_without_tests": self.files_without_tests,
227
+ "test_coverage_avg": self.test_coverage_avg,
228
+ "total_test_count": self.total_test_count,
229
+ "stale_file_count": self.stale_file_count,
230
+ "avg_staleness_days": self.avg_staleness_days,
231
+ "most_stale_files": self.most_stale_files,
232
+ "total_lines_of_code": self.total_lines_of_code,
233
+ "total_lines_of_test": self.total_lines_of_test,
234
+ "test_to_code_ratio": self.test_to_code_ratio,
235
+ "avg_complexity": self.avg_complexity,
236
+ "files_with_docstrings_pct": self.files_with_docstrings_pct,
237
+ "files_with_type_hints_pct": self.files_with_type_hints_pct,
238
+ "total_lint_issues": self.total_lint_issues,
239
+ "high_impact_files": self.high_impact_files,
240
+ "critical_untested_files": self.critical_untested_files,
241
+ "files_needing_attention": self.files_needing_attention,
242
+ "top_attention_files": self.top_attention_files,
243
+ }
244
+
245
+ @classmethod
246
+ def from_dict(cls, data: dict[str, Any]) -> "ProjectSummary":
247
+ """Create from dictionary."""
248
+ return cls(
249
+ total_files=data.get("total_files", 0),
250
+ source_files=data.get("source_files", 0),
251
+ test_files=data.get("test_files", 0),
252
+ config_files=data.get("config_files", 0),
253
+ doc_files=data.get("doc_files", 0),
254
+ files_requiring_tests=data.get("files_requiring_tests", 0),
255
+ files_with_tests=data.get("files_with_tests", 0),
256
+ files_without_tests=data.get("files_without_tests", 0),
257
+ test_coverage_avg=data.get("test_coverage_avg", 0.0),
258
+ total_test_count=data.get("total_test_count", 0),
259
+ stale_file_count=data.get("stale_file_count", 0),
260
+ avg_staleness_days=data.get("avg_staleness_days", 0.0),
261
+ most_stale_files=data.get("most_stale_files", []),
262
+ total_lines_of_code=data.get("total_lines_of_code", 0),
263
+ total_lines_of_test=data.get("total_lines_of_test", 0),
264
+ test_to_code_ratio=data.get("test_to_code_ratio", 0.0),
265
+ avg_complexity=data.get("avg_complexity", 0.0),
266
+ files_with_docstrings_pct=data.get("files_with_docstrings_pct", 0.0),
267
+ files_with_type_hints_pct=data.get("files_with_type_hints_pct", 0.0),
268
+ total_lint_issues=data.get("total_lint_issues", 0),
269
+ high_impact_files=data.get("high_impact_files", []),
270
+ critical_untested_files=data.get("critical_untested_files", []),
271
+ files_needing_attention=data.get("files_needing_attention", 0),
272
+ top_attention_files=data.get("top_attention_files", []),
273
+ )
274
+
275
+
276
+ @dataclass
277
+ class IndexConfig:
278
+ """Configuration for the project index.
279
+
280
+ Defines exclusion patterns, staleness thresholds, etc.
281
+ """
282
+
283
+ # File patterns to exclude from indexing
284
+ exclude_patterns: list[str] = field(
285
+ default_factory=lambda: [
286
+ # Python cache and bytecode
287
+ "**/__pycache__/**",
288
+ "**/*.pyc",
289
+ "**/*.pyo",
290
+ # Version control
291
+ "**/.git/**",
292
+ # Virtual environments
293
+ "**/.venv/**",
294
+ "**/venv/**",
295
+ "**/env/**",
296
+ # Package managers
297
+ "**/node_modules/**",
298
+ # Build outputs
299
+ "**/dist/**",
300
+ "**/build/**",
301
+ "**/.next/**",
302
+ "**/site/**",
303
+ "**/*.egg-info/**",
304
+ "**/out/**",
305
+ # Test cache and coverage
306
+ "**/htmlcov/**",
307
+ "**/.pytest_cache/**",
308
+ "**/.mypy_cache/**",
309
+ "**/.ruff_cache/**",
310
+ "**/.coverage*",
311
+ "**/coverage.xml",
312
+ "**/coverage.json",
313
+ "**/.tox/**",
314
+ "**/.nox/**",
315
+ # Generated/binary files
316
+ "**/*.pack",
317
+ "**/dump.rdb",
318
+ # Logs
319
+ "**/logs/**",
320
+ "**/*.log",
321
+ "**/*.jsonl",
322
+ # OS files
323
+ "**/.DS_Store",
324
+ "**/Thumbs.db",
325
+ # IDE/Editor files
326
+ "**/.idea/**",
327
+ "**/.vscode/**",
328
+ "**/*.swp",
329
+ "**/*.swo",
330
+ # External/archived directories (project-specific)
331
+ "**/website/**",
332
+ "**/ebook-site/**",
333
+ "**/anthropic-cookbook/**",
334
+ "**/salvaged/**",
335
+ "**/10_9_2025_ai_nurse_florence/**",
336
+ "**/book-indesign/**",
337
+ "**/examples/**",
338
+ # Binary/asset files
339
+ "**/*.pdf",
340
+ "**/*.jpeg",
341
+ "**/*.jpg",
342
+ "**/*.png",
343
+ "**/*.gif",
344
+ "**/*.ico",
345
+ "**/*.svg",
346
+ "**/*.woff",
347
+ "**/*.woff2",
348
+ "**/*.ttf",
349
+ "**/*.eot",
350
+ "**/*.mp3",
351
+ "**/*.mp4",
352
+ "**/*.wav",
353
+ "**/*.zip",
354
+ "**/*.tar",
355
+ "**/*.gz",
356
+ # Adobe/Design files
357
+ "**/*.indd",
358
+ "**/*.psd",
359
+ "**/*.ai",
360
+ "**/*.sketch",
361
+ "**/*.figma",
362
+ # Lock files
363
+ "**/package-lock.json",
364
+ "**/yarn.lock",
365
+ "**/poetry.lock",
366
+ "**/Pipfile.lock",
367
+ # Archive directories
368
+ "**/archived_wizards/**",
369
+ ],
370
+ )
371
+
372
+ # Patterns for files that don't require tests
373
+ no_test_patterns: list[str] = field(
374
+ default_factory=lambda: [
375
+ # Python special files
376
+ "**/__init__.py",
377
+ "**/__main__.py",
378
+ "**/conftest.py",
379
+ "**/setup.py",
380
+ "**/setup.cfg",
381
+ # Configuration files
382
+ "**/*.yml",
383
+ "**/*.yaml",
384
+ "**/*.json",
385
+ "**/*.toml",
386
+ "**/*.ini",
387
+ "**/*.cfg",
388
+ "**/*.conf",
389
+ # Documentation
390
+ "**/*.md",
391
+ "**/*.txt",
392
+ "**/*.rst",
393
+ # Frontend assets
394
+ "**/*.css",
395
+ "**/*.scss",
396
+ "**/*.less",
397
+ "**/*.html",
398
+ "**/*.jinja",
399
+ "**/*.jinja2",
400
+ # Database and migrations
401
+ "**/migrations/**",
402
+ "**/alembic/**",
403
+ # Static and templates
404
+ "**/static/**",
405
+ "**/templates/**",
406
+ "**/fixtures/**",
407
+ # Scripts and utilities (typically standalone)
408
+ "**/scripts/**",
409
+ "**/bin/**",
410
+ "**/tools/**",
411
+ "**/*_script.py",
412
+ "**/*_example.py",
413
+ "**/profile_*.py",
414
+ "**/benchmark_*.py",
415
+ # CLI entry points
416
+ "**/*_cli.py",
417
+ "**/cli.py",
418
+ # Type stubs
419
+ "**/*.pyi",
420
+ # Jupyter notebooks
421
+ "**/*.ipynb",
422
+ # Test files themselves don't need tests
423
+ "**/test_*.py",
424
+ "**/tests/**",
425
+ "**/*_test.py",
426
+ # Example and demo files
427
+ "**/*_example.py",
428
+ "**/*_demo.py",
429
+ "**/example_*.py",
430
+ "**/demo_*.py",
431
+ # Prompt templates
432
+ "**/prompts/**",
433
+ # Vscode extension (separate project)
434
+ "**/vscode-extension/**",
435
+ ],
436
+ )
437
+
438
+ # Staleness threshold in days
439
+ staleness_threshold_days: int = 7
440
+
441
+ # Coverage threshold for "needs attention"
442
+ low_coverage_threshold: float = 50.0
443
+
444
+ # Impact score threshold for "high impact"
445
+ high_impact_threshold: float = 5.0
446
+
447
+ # Source directories to scan
448
+ source_dirs: list[str] = field(
449
+ default_factory=lambda: [
450
+ "src",
451
+ "empathy_llm_toolkit",
452
+ "coach_wizards",
453
+ "empathy_software_plugin",
454
+ "empathy_healthcare_plugin",
455
+ ],
456
+ )
457
+
458
+ # Test directory
459
+ test_dir: str = "tests"
460
+
461
+ # Redis settings
462
+ use_redis: bool = False
463
+ redis_key_prefix: str = "empathy:project_index"
464
+
465
+ def to_dict(self) -> dict[str, Any]:
466
+ """Convert to dictionary."""
467
+ return {
468
+ "exclude_patterns": self.exclude_patterns,
469
+ "no_test_patterns": self.no_test_patterns,
470
+ "staleness_threshold_days": self.staleness_threshold_days,
471
+ "low_coverage_threshold": self.low_coverage_threshold,
472
+ "high_impact_threshold": self.high_impact_threshold,
473
+ "source_dirs": self.source_dirs,
474
+ "test_dir": self.test_dir,
475
+ "use_redis": self.use_redis,
476
+ "redis_key_prefix": self.redis_key_prefix,
477
+ }
478
+
479
+ @classmethod
480
+ def from_dict(cls, data: dict[str, Any]) -> "IndexConfig":
481
+ """Create from dictionary."""
482
+ config = cls()
483
+ if "exclude_patterns" in data:
484
+ config.exclude_patterns = data["exclude_patterns"]
485
+ if "no_test_patterns" in data:
486
+ config.no_test_patterns = data["no_test_patterns"]
487
+ if "staleness_threshold_days" in data:
488
+ config.staleness_threshold_days = data["staleness_threshold_days"]
489
+ if "low_coverage_threshold" in data:
490
+ config.low_coverage_threshold = data["low_coverage_threshold"]
491
+ if "high_impact_threshold" in data:
492
+ config.high_impact_threshold = data["high_impact_threshold"]
493
+ if "source_dirs" in data:
494
+ config.source_dirs = data["source_dirs"]
495
+ if "test_dir" in data:
496
+ config.test_dir = data["test_dir"]
497
+ if "use_redis" in data:
498
+ config.use_redis = data["use_redis"]
499
+ if "redis_key_prefix" in data:
500
+ config.redis_key_prefix = data["redis_key_prefix"]
501
+ return config