tapps-agents 3.6.0__py3-none-any.whl → 3.6.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.
- tapps_agents/__init__.py +2 -2
- tapps_agents/agents/__init__.py +22 -22
- tapps_agents/agents/analyst/__init__.py +5 -5
- tapps_agents/agents/architect/__init__.py +5 -5
- tapps_agents/agents/architect/agent.py +1033 -1033
- tapps_agents/agents/architect/pattern_detector.py +75 -75
- tapps_agents/agents/cleanup/__init__.py +7 -7
- tapps_agents/agents/cleanup/agent.py +445 -445
- tapps_agents/agents/debugger/__init__.py +7 -7
- tapps_agents/agents/debugger/agent.py +310 -310
- tapps_agents/agents/debugger/error_analyzer.py +437 -437
- tapps_agents/agents/designer/__init__.py +5 -5
- tapps_agents/agents/designer/agent.py +786 -786
- tapps_agents/agents/designer/visual_designer.py +638 -638
- tapps_agents/agents/documenter/__init__.py +7 -7
- tapps_agents/agents/documenter/agent.py +531 -531
- tapps_agents/agents/documenter/doc_generator.py +472 -472
- tapps_agents/agents/documenter/doc_validator.py +393 -393
- tapps_agents/agents/documenter/framework_doc_updater.py +493 -493
- tapps_agents/agents/enhancer/__init__.py +7 -7
- tapps_agents/agents/evaluator/__init__.py +7 -7
- tapps_agents/agents/evaluator/agent.py +443 -443
- tapps_agents/agents/evaluator/priority_evaluator.py +641 -641
- tapps_agents/agents/evaluator/quality_analyzer.py +147 -147
- tapps_agents/agents/evaluator/report_generator.py +344 -344
- tapps_agents/agents/evaluator/usage_analyzer.py +192 -192
- tapps_agents/agents/evaluator/workflow_analyzer.py +189 -189
- tapps_agents/agents/implementer/__init__.py +7 -7
- tapps_agents/agents/implementer/agent.py +798 -798
- tapps_agents/agents/implementer/auto_fix.py +1119 -1119
- tapps_agents/agents/implementer/code_generator.py +73 -73
- tapps_agents/agents/improver/__init__.py +1 -1
- tapps_agents/agents/improver/agent.py +753 -753
- tapps_agents/agents/ops/__init__.py +1 -1
- tapps_agents/agents/ops/agent.py +619 -619
- tapps_agents/agents/ops/dependency_analyzer.py +600 -600
- tapps_agents/agents/orchestrator/__init__.py +5 -5
- tapps_agents/agents/orchestrator/agent.py +522 -522
- tapps_agents/agents/planner/__init__.py +7 -7
- tapps_agents/agents/planner/agent.py +1127 -1127
- tapps_agents/agents/reviewer/__init__.py +24 -24
- tapps_agents/agents/reviewer/agent.py +3513 -3513
- tapps_agents/agents/reviewer/aggregator.py +213 -213
- tapps_agents/agents/reviewer/batch_review.py +448 -448
- tapps_agents/agents/reviewer/cache.py +443 -443
- tapps_agents/agents/reviewer/context7_enhancer.py +630 -630
- tapps_agents/agents/reviewer/context_detector.py +203 -203
- tapps_agents/agents/reviewer/docker_compose_validator.py +158 -158
- tapps_agents/agents/reviewer/dockerfile_validator.py +176 -176
- tapps_agents/agents/reviewer/error_handling.py +126 -126
- tapps_agents/agents/reviewer/feedback_generator.py +490 -490
- tapps_agents/agents/reviewer/influxdb_validator.py +316 -316
- tapps_agents/agents/reviewer/issue_tracking.py +169 -169
- tapps_agents/agents/reviewer/library_detector.py +295 -295
- tapps_agents/agents/reviewer/library_patterns.py +268 -268
- tapps_agents/agents/reviewer/maintainability_scorer.py +593 -593
- tapps_agents/agents/reviewer/metric_strategies.py +276 -276
- tapps_agents/agents/reviewer/mqtt_validator.py +160 -160
- tapps_agents/agents/reviewer/output_enhancer.py +105 -105
- tapps_agents/agents/reviewer/pattern_detector.py +241 -241
- tapps_agents/agents/reviewer/performance_scorer.py +357 -357
- tapps_agents/agents/reviewer/phased_review.py +516 -516
- tapps_agents/agents/reviewer/progressive_review.py +435 -435
- tapps_agents/agents/reviewer/react_scorer.py +331 -331
- tapps_agents/agents/reviewer/score_constants.py +228 -228
- tapps_agents/agents/reviewer/score_validator.py +507 -507
- tapps_agents/agents/reviewer/scorer_registry.py +373 -373
- tapps_agents/agents/reviewer/service_discovery.py +534 -534
- tapps_agents/agents/reviewer/tools/parallel_executor.py +581 -581
- tapps_agents/agents/reviewer/tools/ruff_grouping.py +250 -250
- tapps_agents/agents/reviewer/tools/scoped_mypy.py +284 -284
- tapps_agents/agents/reviewer/typescript_scorer.py +1142 -1142
- tapps_agents/agents/reviewer/validation.py +208 -208
- tapps_agents/agents/reviewer/websocket_validator.py +132 -132
- tapps_agents/agents/tester/__init__.py +7 -7
- tapps_agents/agents/tester/accessibility_auditor.py +309 -309
- tapps_agents/agents/tester/agent.py +1080 -1080
- tapps_agents/agents/tester/batch_generator.py +54 -54
- tapps_agents/agents/tester/context_learner.py +51 -51
- tapps_agents/agents/tester/coverage_analyzer.py +386 -386
- tapps_agents/agents/tester/coverage_test_generator.py +290 -290
- tapps_agents/agents/tester/debug_enhancer.py +238 -238
- tapps_agents/agents/tester/device_emulator.py +241 -241
- tapps_agents/agents/tester/integration_generator.py +62 -62
- tapps_agents/agents/tester/network_recorder.py +300 -300
- tapps_agents/agents/tester/performance_monitor.py +320 -320
- tapps_agents/agents/tester/test_fixer.py +316 -316
- tapps_agents/agents/tester/test_generator.py +632 -632
- tapps_agents/agents/tester/trace_manager.py +234 -234
- tapps_agents/agents/tester/visual_regression.py +291 -291
- tapps_agents/analysis/pattern_detector.py +36 -36
- tapps_agents/beads/hydration.py +213 -213
- tapps_agents/beads/parse.py +32 -32
- tapps_agents/beads/specs.py +206 -206
- tapps_agents/cli/__init__.py +9 -9
- tapps_agents/cli/__main__.py +8 -8
- tapps_agents/cli/base.py +478 -478
- tapps_agents/cli/command_classifier.py +72 -72
- tapps_agents/cli/commands/__init__.py +2 -2
- tapps_agents/cli/commands/analyst.py +173 -173
- tapps_agents/cli/commands/architect.py +109 -109
- tapps_agents/cli/commands/cleanup_agent.py +92 -92
- tapps_agents/cli/commands/common.py +126 -126
- tapps_agents/cli/commands/debugger.py +90 -90
- tapps_agents/cli/commands/designer.py +112 -112
- tapps_agents/cli/commands/documenter.py +136 -136
- tapps_agents/cli/commands/enhancer.py +110 -110
- tapps_agents/cli/commands/evaluator.py +255 -255
- tapps_agents/cli/commands/implementer.py +301 -301
- tapps_agents/cli/commands/improver.py +91 -91
- tapps_agents/cli/commands/knowledge.py +111 -111
- tapps_agents/cli/commands/learning.py +172 -172
- tapps_agents/cli/commands/observability.py +283 -283
- tapps_agents/cli/commands/ops.py +135 -135
- tapps_agents/cli/commands/orchestrator.py +116 -116
- tapps_agents/cli/commands/planner.py +237 -237
- tapps_agents/cli/commands/reviewer.py +1872 -1872
- tapps_agents/cli/commands/status.py +285 -285
- tapps_agents/cli/commands/task.py +227 -227
- tapps_agents/cli/commands/tester.py +191 -191
- tapps_agents/cli/feedback.py +936 -936
- tapps_agents/cli/formatters.py +608 -608
- tapps_agents/cli/help/__init__.py +7 -7
- tapps_agents/cli/help/static_help.py +425 -425
- tapps_agents/cli/network_detection.py +110 -110
- tapps_agents/cli/output_compactor.py +274 -274
- tapps_agents/cli/parsers/__init__.py +2 -2
- tapps_agents/cli/parsers/analyst.py +186 -186
- tapps_agents/cli/parsers/architect.py +167 -167
- tapps_agents/cli/parsers/cleanup_agent.py +228 -228
- tapps_agents/cli/parsers/debugger.py +116 -116
- tapps_agents/cli/parsers/designer.py +182 -182
- tapps_agents/cli/parsers/documenter.py +134 -134
- tapps_agents/cli/parsers/enhancer.py +113 -113
- tapps_agents/cli/parsers/evaluator.py +213 -213
- tapps_agents/cli/parsers/implementer.py +168 -168
- tapps_agents/cli/parsers/improver.py +132 -132
- tapps_agents/cli/parsers/ops.py +159 -159
- tapps_agents/cli/parsers/orchestrator.py +98 -98
- tapps_agents/cli/parsers/planner.py +145 -145
- tapps_agents/cli/parsers/reviewer.py +462 -462
- tapps_agents/cli/parsers/tester.py +124 -124
- tapps_agents/cli/progress_heartbeat.py +254 -254
- tapps_agents/cli/streaming_progress.py +336 -336
- tapps_agents/cli/utils/__init__.py +6 -6
- tapps_agents/cli/utils/agent_lifecycle.py +48 -48
- tapps_agents/cli/utils/error_formatter.py +82 -82
- tapps_agents/cli/utils/error_recovery.py +188 -188
- tapps_agents/cli/utils/output_handler.py +59 -59
- tapps_agents/cli/utils/prompt_enhancer.py +319 -319
- tapps_agents/cli/validators/__init__.py +9 -9
- tapps_agents/cli/validators/command_validator.py +81 -81
- tapps_agents/context7/__init__.py +112 -112
- tapps_agents/context7/agent_integration.py +869 -869
- tapps_agents/context7/analytics.py +382 -382
- tapps_agents/context7/analytics_dashboard.py +299 -299
- tapps_agents/context7/async_cache.py +681 -681
- tapps_agents/context7/backup_client.py +958 -958
- tapps_agents/context7/cache_locking.py +194 -194
- tapps_agents/context7/cache_metadata.py +214 -214
- tapps_agents/context7/cache_prewarm.py +488 -488
- tapps_agents/context7/cache_structure.py +168 -168
- tapps_agents/context7/cache_warming.py +604 -604
- tapps_agents/context7/circuit_breaker.py +376 -376
- tapps_agents/context7/cleanup.py +461 -461
- tapps_agents/context7/commands.py +858 -858
- tapps_agents/context7/credential_validation.py +276 -276
- tapps_agents/context7/cross_reference_resolver.py +168 -168
- tapps_agents/context7/cross_references.py +424 -424
- tapps_agents/context7/doc_manager.py +225 -225
- tapps_agents/context7/fuzzy_matcher.py +369 -369
- tapps_agents/context7/kb_cache.py +404 -404
- tapps_agents/context7/language_detector.py +219 -219
- tapps_agents/context7/library_detector.py +725 -725
- tapps_agents/context7/lookup.py +738 -738
- tapps_agents/context7/metadata.py +258 -258
- tapps_agents/context7/refresh_queue.py +300 -300
- tapps_agents/context7/security.py +373 -373
- tapps_agents/context7/staleness_policies.py +278 -278
- tapps_agents/context7/tiles_integration.py +47 -47
- tapps_agents/continuous_bug_fix/__init__.py +20 -20
- tapps_agents/continuous_bug_fix/bug_finder.py +306 -306
- tapps_agents/continuous_bug_fix/bug_fix_coordinator.py +177 -177
- tapps_agents/continuous_bug_fix/commit_manager.py +178 -178
- tapps_agents/continuous_bug_fix/continuous_bug_fixer.py +322 -322
- tapps_agents/continuous_bug_fix/proactive_bug_finder.py +285 -285
- tapps_agents/core/__init__.py +298 -298
- tapps_agents/core/adaptive_cache_config.py +432 -432
- tapps_agents/core/agent_base.py +647 -647
- tapps_agents/core/agent_cache.py +466 -466
- tapps_agents/core/agent_learning.py +1865 -1865
- tapps_agents/core/analytics_dashboard.py +563 -563
- tapps_agents/core/analytics_enhancements.py +597 -597
- tapps_agents/core/anonymization.py +274 -274
- tapps_agents/core/ast_parser.py +228 -228
- tapps_agents/core/async_file_ops.py +402 -402
- tapps_agents/core/best_practice_consultant.py +299 -299
- tapps_agents/core/brownfield_analyzer.py +299 -299
- tapps_agents/core/brownfield_review.py +541 -541
- tapps_agents/core/browser_controller.py +513 -513
- tapps_agents/core/capability_registry.py +418 -418
- tapps_agents/core/change_impact_analyzer.py +190 -190
- tapps_agents/core/checkpoint_manager.py +377 -377
- tapps_agents/core/code_generator.py +329 -329
- tapps_agents/core/code_validator.py +276 -276
- tapps_agents/core/command_registry.py +327 -327
- tapps_agents/core/context_gathering/__init__.py +2 -2
- tapps_agents/core/context_gathering/repository_explorer.py +28 -28
- tapps_agents/core/context_intelligence/__init__.py +2 -2
- tapps_agents/core/context_intelligence/relevance_scorer.py +24 -24
- tapps_agents/core/context_intelligence/token_budget_manager.py +27 -27
- tapps_agents/core/context_manager.py +240 -240
- tapps_agents/core/cursor_feedback_monitor.py +146 -146
- tapps_agents/core/cursor_verification.py +290 -290
- tapps_agents/core/customization_loader.py +280 -280
- tapps_agents/core/customization_schema.py +260 -260
- tapps_agents/core/customization_template.py +238 -238
- tapps_agents/core/debug_logger.py +124 -124
- tapps_agents/core/design_validator.py +298 -298
- tapps_agents/core/diagram_generator.py +226 -226
- tapps_agents/core/docker_utils.py +232 -232
- tapps_agents/core/document_generator.py +617 -617
- tapps_agents/core/domain_detector.py +30 -30
- tapps_agents/core/error_envelope.py +454 -454
- tapps_agents/core/error_handler.py +270 -270
- tapps_agents/core/estimation_tracker.py +189 -189
- tapps_agents/core/eval_prompt_engine.py +116 -116
- tapps_agents/core/evaluation_base.py +119 -119
- tapps_agents/core/evaluation_models.py +320 -320
- tapps_agents/core/evaluation_orchestrator.py +225 -225
- tapps_agents/core/evaluators/__init__.py +7 -7
- tapps_agents/core/evaluators/architectural_evaluator.py +205 -205
- tapps_agents/core/evaluators/behavioral_evaluator.py +160 -160
- tapps_agents/core/evaluators/performance_profile_evaluator.py +160 -160
- tapps_agents/core/evaluators/security_posture_evaluator.py +148 -148
- tapps_agents/core/evaluators/spec_compliance_evaluator.py +181 -181
- tapps_agents/core/exceptions.py +107 -107
- tapps_agents/core/expert_config_generator.py +293 -293
- tapps_agents/core/export_schema.py +202 -202
- tapps_agents/core/external_feedback_models.py +102 -102
- tapps_agents/core/external_feedback_storage.py +213 -213
- tapps_agents/core/fallback_strategy.py +314 -314
- tapps_agents/core/feedback_analyzer.py +162 -162
- tapps_agents/core/feedback_collector.py +178 -178
- tapps_agents/core/git_operations.py +445 -445
- tapps_agents/core/hardware_profiler.py +151 -151
- tapps_agents/core/instructions.py +324 -324
- tapps_agents/core/io_guardrails.py +69 -69
- tapps_agents/core/issue_manifest.py +249 -249
- tapps_agents/core/issue_schema.py +139 -139
- tapps_agents/core/json_utils.py +128 -128
- tapps_agents/core/knowledge_graph.py +446 -446
- tapps_agents/core/language_detector.py +296 -296
- tapps_agents/core/learning_confidence.py +242 -242
- tapps_agents/core/learning_dashboard.py +246 -246
- tapps_agents/core/learning_decision.py +384 -384
- tapps_agents/core/learning_explainability.py +578 -578
- tapps_agents/core/learning_export.py +287 -287
- tapps_agents/core/learning_integration.py +228 -228
- tapps_agents/core/llm_behavior.py +232 -232
- tapps_agents/core/long_duration_support.py +786 -786
- tapps_agents/core/mcp_setup.py +106 -106
- tapps_agents/core/memory_integration.py +396 -396
- tapps_agents/core/meta_learning.py +666 -666
- tapps_agents/core/module_path_sanitizer.py +199 -199
- tapps_agents/core/multi_agent_orchestrator.py +382 -382
- tapps_agents/core/network_errors.py +125 -125
- tapps_agents/core/nfr_validator.py +336 -336
- tapps_agents/core/offline_mode.py +158 -158
- tapps_agents/core/output_contracts.py +300 -300
- tapps_agents/core/output_formatter.py +300 -300
- tapps_agents/core/path_normalizer.py +174 -174
- tapps_agents/core/path_validator.py +322 -322
- tapps_agents/core/pattern_library.py +250 -250
- tapps_agents/core/performance_benchmark.py +301 -301
- tapps_agents/core/performance_monitor.py +184 -184
- tapps_agents/core/playwright_mcp_controller.py +771 -771
- tapps_agents/core/policy_loader.py +135 -135
- tapps_agents/core/progress.py +166 -166
- tapps_agents/core/project_profile.py +354 -354
- tapps_agents/core/project_type_detector.py +454 -454
- tapps_agents/core/prompt_base.py +223 -223
- tapps_agents/core/prompt_learning/__init__.py +2 -2
- tapps_agents/core/prompt_learning/learning_loop.py +24 -24
- tapps_agents/core/prompt_learning/project_prompt_store.py +25 -25
- tapps_agents/core/prompt_learning/skills_prompt_analyzer.py +35 -35
- tapps_agents/core/prompt_optimization/__init__.py +6 -6
- tapps_agents/core/prompt_optimization/ab_tester.py +114 -114
- tapps_agents/core/prompt_optimization/correlation_analyzer.py +160 -160
- tapps_agents/core/prompt_optimization/progressive_refiner.py +129 -129
- tapps_agents/core/prompt_optimization/prompt_library.py +37 -37
- tapps_agents/core/requirements_evaluator.py +431 -431
- tapps_agents/core/resource_aware_executor.py +449 -449
- tapps_agents/core/resource_monitor.py +343 -343
- tapps_agents/core/resume_handler.py +298 -298
- tapps_agents/core/retry_handler.py +197 -197
- tapps_agents/core/review_checklists.py +479 -479
- tapps_agents/core/role_loader.py +201 -201
- tapps_agents/core/role_template_loader.py +201 -201
- tapps_agents/core/runtime_mode.py +60 -60
- tapps_agents/core/security_scanner.py +342 -342
- tapps_agents/core/skill_agent_registry.py +194 -194
- tapps_agents/core/skill_integration.py +208 -208
- tapps_agents/core/skill_loader.py +492 -492
- tapps_agents/core/skill_template.py +341 -341
- tapps_agents/core/skill_validator.py +478 -478
- tapps_agents/core/stack_analyzer.py +35 -35
- tapps_agents/core/startup.py +174 -174
- tapps_agents/core/storage_manager.py +397 -397
- tapps_agents/core/storage_models.py +166 -166
- tapps_agents/core/story_evaluator.py +410 -410
- tapps_agents/core/subprocess_utils.py +170 -170
- tapps_agents/core/task_duration.py +296 -296
- tapps_agents/core/task_memory.py +582 -582
- tapps_agents/core/task_state.py +226 -226
- tapps_agents/core/tech_stack_priorities.py +208 -208
- tapps_agents/core/temp_directory.py +194 -194
- tapps_agents/core/template_merger.py +600 -600
- tapps_agents/core/template_selector.py +280 -280
- tapps_agents/core/test_generator.py +286 -286
- tapps_agents/core/tiered_context.py +253 -253
- tapps_agents/core/token_monitor.py +345 -345
- tapps_agents/core/traceability.py +254 -254
- tapps_agents/core/trajectory_tracker.py +50 -50
- tapps_agents/core/unicode_safe.py +143 -143
- tapps_agents/core/unified_cache_config.py +170 -170
- tapps_agents/core/unified_state.py +324 -324
- tapps_agents/core/validate_cursor_setup.py +237 -237
- tapps_agents/core/validation_registry.py +136 -136
- tapps_agents/core/validators/__init__.py +4 -4
- tapps_agents/core/validators/python_validator.py +87 -87
- tapps_agents/core/verification_agent.py +90 -90
- tapps_agents/core/visual_feedback.py +644 -644
- tapps_agents/core/workflow_validator.py +197 -197
- tapps_agents/core/worktree.py +367 -367
- tapps_agents/docker/__init__.py +10 -10
- tapps_agents/docker/analyzer.py +186 -186
- tapps_agents/docker/debugger.py +229 -229
- tapps_agents/docker/error_patterns.py +216 -216
- tapps_agents/epic/__init__.py +22 -22
- tapps_agents/epic/beads_sync.py +115 -115
- tapps_agents/epic/markdown_sync.py +105 -105
- tapps_agents/epic/models.py +96 -96
- tapps_agents/experts/__init__.py +163 -163
- tapps_agents/experts/agent_integration.py +243 -243
- tapps_agents/experts/auto_generator.py +331 -331
- tapps_agents/experts/base_expert.py +536 -536
- tapps_agents/experts/builtin_registry.py +261 -261
- tapps_agents/experts/business_metrics.py +565 -565
- tapps_agents/experts/cache.py +266 -266
- tapps_agents/experts/confidence_breakdown.py +306 -306
- tapps_agents/experts/confidence_calculator.py +336 -336
- tapps_agents/experts/confidence_metrics.py +236 -236
- tapps_agents/experts/domain_config.py +311 -311
- tapps_agents/experts/domain_detector.py +550 -550
- tapps_agents/experts/domain_utils.py +84 -84
- tapps_agents/experts/expert_config.py +113 -113
- tapps_agents/experts/expert_engine.py +465 -465
- tapps_agents/experts/expert_registry.py +744 -744
- tapps_agents/experts/expert_synthesizer.py +70 -70
- tapps_agents/experts/governance.py +197 -197
- tapps_agents/experts/history_logger.py +312 -312
- tapps_agents/experts/knowledge/README.md +180 -180
- tapps_agents/experts/knowledge/accessibility/accessible-forms.md +331 -331
- tapps_agents/experts/knowledge/accessibility/aria-patterns.md +344 -344
- tapps_agents/experts/knowledge/accessibility/color-contrast.md +285 -285
- tapps_agents/experts/knowledge/accessibility/keyboard-navigation.md +332 -332
- tapps_agents/experts/knowledge/accessibility/screen-readers.md +282 -282
- tapps_agents/experts/knowledge/accessibility/semantic-html.md +355 -355
- tapps_agents/experts/knowledge/accessibility/testing-accessibility.md +369 -369
- tapps_agents/experts/knowledge/accessibility/wcag-2.1.md +296 -296
- tapps_agents/experts/knowledge/accessibility/wcag-2.2.md +211 -211
- tapps_agents/experts/knowledge/agent-learning/best-practices.md +715 -715
- tapps_agents/experts/knowledge/agent-learning/pattern-extraction.md +282 -282
- tapps_agents/experts/knowledge/agent-learning/prompt-optimization.md +320 -320
- tapps_agents/experts/knowledge/ai-frameworks/model-optimization.md +90 -90
- tapps_agents/experts/knowledge/ai-frameworks/openvino-patterns.md +260 -260
- tapps_agents/experts/knowledge/api-design-integration/api-gateway-patterns.md +309 -309
- tapps_agents/experts/knowledge/api-design-integration/api-security-patterns.md +521 -521
- tapps_agents/experts/knowledge/api-design-integration/api-versioning.md +421 -421
- tapps_agents/experts/knowledge/api-design-integration/async-protocol-patterns.md +61 -61
- tapps_agents/experts/knowledge/api-design-integration/contract-testing.md +221 -221
- tapps_agents/experts/knowledge/api-design-integration/external-api-integration.md +489 -489
- tapps_agents/experts/knowledge/api-design-integration/fastapi-patterns.md +360 -360
- tapps_agents/experts/knowledge/api-design-integration/fastapi-testing.md +262 -262
- tapps_agents/experts/knowledge/api-design-integration/graphql-patterns.md +582 -582
- tapps_agents/experts/knowledge/api-design-integration/grpc-best-practices.md +499 -499
- tapps_agents/experts/knowledge/api-design-integration/mqtt-patterns.md +455 -455
- tapps_agents/experts/knowledge/api-design-integration/rate-limiting.md +507 -507
- tapps_agents/experts/knowledge/api-design-integration/restful-api-design.md +618 -618
- tapps_agents/experts/knowledge/api-design-integration/websocket-patterns.md +480 -480
- tapps_agents/experts/knowledge/cloud-infrastructure/cloud-native-patterns.md +175 -175
- tapps_agents/experts/knowledge/cloud-infrastructure/container-health-checks.md +261 -261
- tapps_agents/experts/knowledge/cloud-infrastructure/containerization.md +222 -222
- tapps_agents/experts/knowledge/cloud-infrastructure/cost-optimization.md +122 -122
- tapps_agents/experts/knowledge/cloud-infrastructure/disaster-recovery.md +153 -153
- tapps_agents/experts/knowledge/cloud-infrastructure/dockerfile-patterns.md +285 -285
- tapps_agents/experts/knowledge/cloud-infrastructure/infrastructure-as-code.md +187 -187
- tapps_agents/experts/knowledge/cloud-infrastructure/kubernetes-patterns.md +253 -253
- tapps_agents/experts/knowledge/cloud-infrastructure/multi-cloud-strategies.md +155 -155
- tapps_agents/experts/knowledge/cloud-infrastructure/serverless-architecture.md +200 -200
- tapps_agents/experts/knowledge/code-quality-analysis/README.md +16 -16
- tapps_agents/experts/knowledge/code-quality-analysis/code-metrics.md +137 -137
- tapps_agents/experts/knowledge/code-quality-analysis/complexity-analysis.md +181 -181
- tapps_agents/experts/knowledge/code-quality-analysis/technical-debt-patterns.md +191 -191
- tapps_agents/experts/knowledge/data-privacy-compliance/anonymization.md +313 -313
- tapps_agents/experts/knowledge/data-privacy-compliance/ccpa.md +255 -255
- tapps_agents/experts/knowledge/data-privacy-compliance/consent-management.md +282 -282
- tapps_agents/experts/knowledge/data-privacy-compliance/data-minimization.md +275 -275
- tapps_agents/experts/knowledge/data-privacy-compliance/data-retention.md +297 -297
- tapps_agents/experts/knowledge/data-privacy-compliance/data-subject-rights.md +383 -383
- tapps_agents/experts/knowledge/data-privacy-compliance/encryption-privacy.md +285 -285
- tapps_agents/experts/knowledge/data-privacy-compliance/gdpr.md +344 -344
- tapps_agents/experts/knowledge/data-privacy-compliance/hipaa.md +385 -385
- tapps_agents/experts/knowledge/data-privacy-compliance/privacy-by-design.md +280 -280
- tapps_agents/experts/knowledge/database-data-management/acid-vs-cap.md +164 -164
- tapps_agents/experts/knowledge/database-data-management/backup-and-recovery.md +182 -182
- tapps_agents/experts/knowledge/database-data-management/data-modeling.md +172 -172
- tapps_agents/experts/knowledge/database-data-management/database-design.md +187 -187
- tapps_agents/experts/knowledge/database-data-management/flux-query-optimization.md +342 -342
- tapps_agents/experts/knowledge/database-data-management/influxdb-connection-patterns.md +432 -432
- tapps_agents/experts/knowledge/database-data-management/influxdb-patterns.md +442 -442
- tapps_agents/experts/knowledge/database-data-management/migration-strategies.md +216 -216
- tapps_agents/experts/knowledge/database-data-management/nosql-patterns.md +259 -259
- tapps_agents/experts/knowledge/database-data-management/scalability-patterns.md +184 -184
- tapps_agents/experts/knowledge/database-data-management/sql-optimization.md +175 -175
- tapps_agents/experts/knowledge/database-data-management/time-series-modeling.md +444 -444
- tapps_agents/experts/knowledge/development-workflow/README.md +16 -16
- tapps_agents/experts/knowledge/development-workflow/automation-best-practices.md +216 -216
- tapps_agents/experts/knowledge/development-workflow/build-strategies.md +198 -198
- tapps_agents/experts/knowledge/development-workflow/deployment-patterns.md +205 -205
- tapps_agents/experts/knowledge/development-workflow/git-workflows.md +205 -205
- tapps_agents/experts/knowledge/documentation-knowledge-management/README.md +16 -16
- tapps_agents/experts/knowledge/documentation-knowledge-management/api-documentation-patterns.md +231 -231
- tapps_agents/experts/knowledge/documentation-knowledge-management/documentation-standards.md +191 -191
- tapps_agents/experts/knowledge/documentation-knowledge-management/knowledge-management.md +171 -171
- tapps_agents/experts/knowledge/documentation-knowledge-management/technical-writing-guide.md +192 -192
- tapps_agents/experts/knowledge/observability-monitoring/alerting-patterns.md +461 -461
- tapps_agents/experts/knowledge/observability-monitoring/apm-tools.md +459 -459
- tapps_agents/experts/knowledge/observability-monitoring/distributed-tracing.md +367 -367
- tapps_agents/experts/knowledge/observability-monitoring/logging-strategies.md +478 -478
- tapps_agents/experts/knowledge/observability-monitoring/metrics-and-monitoring.md +510 -510
- tapps_agents/experts/knowledge/observability-monitoring/observability-best-practices.md +492 -492
- tapps_agents/experts/knowledge/observability-monitoring/open-telemetry.md +573 -573
- tapps_agents/experts/knowledge/observability-monitoring/slo-sli-sla.md +419 -419
- tapps_agents/experts/knowledge/performance/anti-patterns.md +284 -284
- tapps_agents/experts/knowledge/performance/api-performance.md +256 -256
- tapps_agents/experts/knowledge/performance/caching.md +327 -327
- tapps_agents/experts/knowledge/performance/database-performance.md +252 -252
- tapps_agents/experts/knowledge/performance/optimization-patterns.md +327 -327
- tapps_agents/experts/knowledge/performance/profiling.md +297 -297
- tapps_agents/experts/knowledge/performance/resource-management.md +293 -293
- tapps_agents/experts/knowledge/performance/scalability.md +306 -306
- tapps_agents/experts/knowledge/security/owasp-top10.md +209 -209
- tapps_agents/experts/knowledge/security/secure-coding-practices.md +207 -207
- tapps_agents/experts/knowledge/security/threat-modeling.md +220 -220
- tapps_agents/experts/knowledge/security/vulnerability-patterns.md +342 -342
- tapps_agents/experts/knowledge/software-architecture/docker-compose-patterns.md +314 -314
- tapps_agents/experts/knowledge/software-architecture/microservices-patterns.md +379 -379
- tapps_agents/experts/knowledge/software-architecture/service-communication.md +316 -316
- tapps_agents/experts/knowledge/testing/best-practices.md +310 -310
- tapps_agents/experts/knowledge/testing/coverage-analysis.md +293 -293
- tapps_agents/experts/knowledge/testing/mocking.md +256 -256
- tapps_agents/experts/knowledge/testing/test-automation.md +276 -276
- tapps_agents/experts/knowledge/testing/test-data.md +271 -271
- tapps_agents/experts/knowledge/testing/test-design-patterns.md +280 -280
- tapps_agents/experts/knowledge/testing/test-maintenance.md +236 -236
- tapps_agents/experts/knowledge/testing/test-strategies.md +311 -311
- tapps_agents/experts/knowledge/user-experience/information-architecture.md +325 -325
- tapps_agents/experts/knowledge/user-experience/interaction-design.md +363 -363
- tapps_agents/experts/knowledge/user-experience/prototyping.md +293 -293
- tapps_agents/experts/knowledge/user-experience/usability-heuristics.md +337 -337
- tapps_agents/experts/knowledge/user-experience/usability-testing.md +311 -311
- tapps_agents/experts/knowledge/user-experience/user-journeys.md +296 -296
- tapps_agents/experts/knowledge/user-experience/user-research.md +373 -373
- tapps_agents/experts/knowledge/user-experience/ux-principles.md +340 -340
- tapps_agents/experts/knowledge_freshness.py +321 -321
- tapps_agents/experts/knowledge_ingestion.py +438 -438
- tapps_agents/experts/knowledge_need_detector.py +93 -93
- tapps_agents/experts/knowledge_validator.py +382 -382
- tapps_agents/experts/observability.py +440 -440
- tapps_agents/experts/passive_notifier.py +238 -238
- tapps_agents/experts/proactive_orchestrator.py +32 -32
- tapps_agents/experts/rag_chunker.py +205 -205
- tapps_agents/experts/rag_embedder.py +152 -152
- tapps_agents/experts/rag_evaluation.py +299 -299
- tapps_agents/experts/rag_index.py +303 -303
- tapps_agents/experts/rag_metrics.py +293 -293
- tapps_agents/experts/rag_safety.py +263 -263
- tapps_agents/experts/report_generator.py +296 -296
- tapps_agents/experts/setup_wizard.py +441 -441
- tapps_agents/experts/simple_rag.py +431 -431
- tapps_agents/experts/vector_rag.py +354 -354
- tapps_agents/experts/weight_distributor.py +304 -304
- tapps_agents/health/__init__.py +24 -24
- tapps_agents/health/base.py +75 -75
- tapps_agents/health/checks/__init__.py +22 -22
- tapps_agents/health/checks/automation.py +127 -127
- tapps_agents/health/checks/context7_cache.py +210 -210
- tapps_agents/health/checks/environment.py +116 -116
- tapps_agents/health/checks/execution.py +170 -170
- tapps_agents/health/checks/knowledge_base.py +187 -187
- tapps_agents/health/checks/outcomes.backup_20260204_064058.py +324 -0
- tapps_agents/health/checks/outcomes.backup_20260204_064256.py +324 -0
- tapps_agents/health/checks/outcomes.backup_20260204_064600.py +324 -0
- tapps_agents/health/checks/outcomes.py +324 -324
- tapps_agents/health/collector.py +280 -280
- tapps_agents/health/dashboard.py +137 -137
- tapps_agents/health/metrics.py +151 -151
- tapps_agents/health/registry.py +166 -166
- tapps_agents/hooks/__init__.py +33 -33
- tapps_agents/hooks/config.py +140 -140
- tapps_agents/hooks/events.py +135 -135
- tapps_agents/hooks/executor.py +128 -128
- tapps_agents/hooks/manager.py +143 -143
- tapps_agents/integration/__init__.py +8 -8
- tapps_agents/integration/service_integrator.py +121 -121
- tapps_agents/integrations/__init__.py +10 -10
- tapps_agents/integrations/clawdbot.py +525 -525
- tapps_agents/integrations/memory_bridge.py +356 -356
- tapps_agents/mcp/__init__.py +18 -18
- tapps_agents/mcp/gateway.py +112 -112
- tapps_agents/mcp/servers/__init__.py +13 -13
- tapps_agents/mcp/servers/analysis.py +204 -204
- tapps_agents/mcp/servers/context7.py +198 -198
- tapps_agents/mcp/servers/filesystem.py +218 -218
- tapps_agents/mcp/servers/git.py +201 -201
- tapps_agents/mcp/tool_registry.py +115 -115
- tapps_agents/quality/__init__.py +54 -54
- tapps_agents/quality/coverage_analyzer.py +379 -379
- tapps_agents/quality/enforcement.py +82 -82
- tapps_agents/quality/gates/__init__.py +37 -37
- tapps_agents/quality/gates/approval_gate.py +255 -255
- tapps_agents/quality/gates/base.py +84 -84
- tapps_agents/quality/gates/exceptions.py +43 -43
- tapps_agents/quality/gates/policy_gate.py +195 -195
- tapps_agents/quality/gates/registry.py +239 -239
- tapps_agents/quality/gates/security_gate.py +156 -156
- tapps_agents/quality/quality_gates.py +369 -369
- tapps_agents/quality/secret_scanner.py +335 -335
- tapps_agents/resources/__init__.py +5 -0
- tapps_agents/resources/claude/__init__.py +1 -0
- tapps_agents/resources/claude/commands/README.md +156 -0
- tapps_agents/resources/claude/commands/__init__.py +1 -0
- tapps_agents/resources/claude/commands/build-fix.md +22 -0
- tapps_agents/resources/claude/commands/build.md +77 -0
- tapps_agents/resources/claude/commands/debug.md +53 -0
- tapps_agents/resources/claude/commands/design.md +68 -0
- tapps_agents/resources/claude/commands/docs.md +53 -0
- tapps_agents/resources/claude/commands/e2e.md +22 -0
- tapps_agents/resources/claude/commands/fix.md +54 -0
- tapps_agents/resources/claude/commands/implement.md +53 -0
- tapps_agents/resources/claude/commands/improve.md +53 -0
- tapps_agents/resources/claude/commands/library-docs.md +64 -0
- tapps_agents/resources/claude/commands/lint.md +52 -0
- tapps_agents/resources/claude/commands/plan.md +65 -0
- tapps_agents/resources/claude/commands/refactor-clean.md +21 -0
- tapps_agents/resources/claude/commands/refactor.md +55 -0
- tapps_agents/resources/claude/commands/review.md +67 -0
- tapps_agents/resources/claude/commands/score.md +60 -0
- tapps_agents/resources/claude/commands/security-review.md +22 -0
- tapps_agents/resources/claude/commands/security-scan.md +54 -0
- tapps_agents/resources/claude/commands/tdd.md +24 -0
- tapps_agents/resources/claude/commands/test-coverage.md +21 -0
- tapps_agents/resources/claude/commands/test.md +54 -0
- tapps_agents/resources/claude/commands/update-codemaps.md +20 -0
- tapps_agents/resources/claude/commands/update-docs.md +21 -0
- tapps_agents/resources/claude/skills/__init__.py +1 -0
- tapps_agents/resources/claude/skills/analyst/SKILL.md +272 -0
- tapps_agents/resources/claude/skills/analyst/__init__.py +1 -0
- tapps_agents/resources/claude/skills/architect/SKILL.md +282 -0
- tapps_agents/resources/claude/skills/architect/__init__.py +1 -0
- tapps_agents/resources/claude/skills/backend-patterns/SKILL.md +30 -0
- tapps_agents/resources/claude/skills/backend-patterns/__init__.py +1 -0
- tapps_agents/resources/claude/skills/coding-standards/SKILL.md +29 -0
- tapps_agents/resources/claude/skills/coding-standards/__init__.py +1 -0
- tapps_agents/resources/claude/skills/debugger/SKILL.md +203 -0
- tapps_agents/resources/claude/skills/debugger/__init__.py +1 -0
- tapps_agents/resources/claude/skills/designer/SKILL.md +243 -0
- tapps_agents/resources/claude/skills/designer/__init__.py +1 -0
- tapps_agents/resources/claude/skills/documenter/SKILL.md +252 -0
- tapps_agents/resources/claude/skills/documenter/__init__.py +1 -0
- tapps_agents/resources/claude/skills/enhancer/SKILL.md +307 -0
- tapps_agents/resources/claude/skills/enhancer/__init__.py +1 -0
- tapps_agents/resources/claude/skills/evaluator/SKILL.md +204 -0
- tapps_agents/resources/claude/skills/evaluator/__init__.py +1 -0
- tapps_agents/resources/claude/skills/frontend-patterns/SKILL.md +29 -0
- tapps_agents/resources/claude/skills/frontend-patterns/__init__.py +1 -0
- tapps_agents/resources/claude/skills/implementer/SKILL.md +188 -0
- tapps_agents/resources/claude/skills/implementer/__init__.py +1 -0
- tapps_agents/resources/claude/skills/improver/SKILL.md +218 -0
- tapps_agents/resources/claude/skills/improver/__init__.py +1 -0
- tapps_agents/resources/claude/skills/ops/SKILL.md +281 -0
- tapps_agents/resources/claude/skills/ops/__init__.py +1 -0
- tapps_agents/resources/claude/skills/orchestrator/SKILL.md +390 -0
- tapps_agents/resources/claude/skills/orchestrator/__init__.py +1 -0
- tapps_agents/resources/claude/skills/planner/SKILL.md +254 -0
- tapps_agents/resources/claude/skills/planner/__init__.py +1 -0
- tapps_agents/resources/claude/skills/reviewer/SKILL.md +434 -0
- tapps_agents/resources/claude/skills/reviewer/__init__.py +1 -0
- tapps_agents/resources/claude/skills/security-review/SKILL.md +31 -0
- tapps_agents/resources/claude/skills/security-review/__init__.py +1 -0
- tapps_agents/resources/claude/skills/simple-mode/SKILL.md +695 -0
- tapps_agents/resources/claude/skills/simple-mode/__init__.py +1 -0
- tapps_agents/resources/claude/skills/tester/SKILL.md +219 -0
- tapps_agents/resources/claude/skills/tester/__init__.py +1 -0
- tapps_agents/resources/cursor/.cursorignore +35 -0
- tapps_agents/resources/cursor/__init__.py +1 -0
- tapps_agents/resources/cursor/commands/__init__.py +1 -0
- tapps_agents/resources/cursor/commands/build-fix.md +11 -0
- tapps_agents/resources/cursor/commands/build.md +11 -0
- tapps_agents/resources/cursor/commands/e2e.md +11 -0
- tapps_agents/resources/cursor/commands/fix.md +11 -0
- tapps_agents/resources/cursor/commands/refactor-clean.md +11 -0
- tapps_agents/resources/cursor/commands/review.md +11 -0
- tapps_agents/resources/cursor/commands/security-review.md +11 -0
- tapps_agents/resources/cursor/commands/tdd.md +11 -0
- tapps_agents/resources/cursor/commands/test-coverage.md +11 -0
- tapps_agents/resources/cursor/commands/test.md +11 -0
- tapps_agents/resources/cursor/commands/update-codemaps.md +10 -0
- tapps_agents/resources/cursor/commands/update-docs.md +11 -0
- tapps_agents/resources/cursor/rules/__init__.py +1 -0
- tapps_agents/resources/cursor/rules/agent-capabilities.mdc +687 -0
- tapps_agents/resources/cursor/rules/coding-style.mdc +31 -0
- tapps_agents/resources/cursor/rules/command-reference.mdc +2081 -0
- tapps_agents/resources/cursor/rules/cursor-mode-usage.mdc +125 -0
- tapps_agents/resources/cursor/rules/git-workflow.mdc +29 -0
- tapps_agents/resources/cursor/rules/performance.mdc +29 -0
- tapps_agents/resources/cursor/rules/project-context.mdc +163 -0
- tapps_agents/resources/cursor/rules/project-profiling.mdc +197 -0
- tapps_agents/resources/cursor/rules/quick-reference.mdc +630 -0
- tapps_agents/resources/cursor/rules/security.mdc +32 -0
- tapps_agents/resources/cursor/rules/simple-mode.mdc +500 -0
- tapps_agents/resources/cursor/rules/testing.mdc +31 -0
- tapps_agents/resources/cursor/rules/when-to-use.mdc +156 -0
- tapps_agents/resources/cursor/rules/workflow-presets.mdc +179 -0
- tapps_agents/resources/customizations/__init__.py +1 -0
- tapps_agents/resources/customizations/example-custom.yaml +83 -0
- tapps_agents/resources/hooks/__init__.py +1 -0
- tapps_agents/resources/hooks/templates/README.md +5 -0
- tapps_agents/resources/hooks/templates/__init__.py +1 -0
- tapps_agents/resources/hooks/templates/add-project-context.yaml +8 -0
- tapps_agents/resources/hooks/templates/auto-format-js.yaml +10 -0
- tapps_agents/resources/hooks/templates/auto-format-python.yaml +10 -0
- tapps_agents/resources/hooks/templates/git-commit-check.yaml +7 -0
- tapps_agents/resources/hooks/templates/notify-on-complete.yaml +8 -0
- tapps_agents/resources/hooks/templates/quality-gate.yaml +8 -0
- tapps_agents/resources/hooks/templates/security-scan-on-edit.yaml +10 -0
- tapps_agents/resources/hooks/templates/session-end-log.yaml +7 -0
- tapps_agents/resources/hooks/templates/show-beads-ready.yaml +8 -0
- tapps_agents/resources/hooks/templates/test-on-edit.yaml +10 -0
- tapps_agents/resources/hooks/templates/update-docs-on-complete.yaml +8 -0
- tapps_agents/resources/hooks/templates/user-prompt-log.yaml +7 -0
- tapps_agents/resources/scripts/__init__.py +1 -0
- tapps_agents/resources/scripts/set_bd_path.ps1 +51 -0
- tapps_agents/resources/workflows/__init__.py +1 -0
- tapps_agents/resources/workflows/presets/__init__.py +1 -0
- tapps_agents/resources/workflows/presets/brownfield-analysis.yaml +235 -0
- tapps_agents/resources/workflows/presets/fix.yaml +78 -0
- tapps_agents/resources/workflows/presets/full-sdlc.yaml +122 -0
- tapps_agents/resources/workflows/presets/quality.yaml +82 -0
- tapps_agents/resources/workflows/presets/rapid-dev.yaml +84 -0
- tapps_agents/session/__init__.py +19 -19
- tapps_agents/session/manager.py +256 -256
- tapps_agents/simple_mode/__init__.py +66 -66
- tapps_agents/simple_mode/agent_contracts.py +357 -357
- tapps_agents/simple_mode/beads_hooks.py +151 -151
- tapps_agents/simple_mode/code_snippet_handler.py +382 -382
- tapps_agents/simple_mode/documentation_manager.py +395 -395
- tapps_agents/simple_mode/documentation_reader.py +187 -187
- tapps_agents/simple_mode/file_inference.py +292 -292
- tapps_agents/simple_mode/framework_change_detector.py +268 -268
- tapps_agents/simple_mode/intent_parser.py +510 -510
- tapps_agents/simple_mode/learning_progression.py +358 -358
- tapps_agents/simple_mode/nl_handler.py +700 -700
- tapps_agents/simple_mode/onboarding.py +253 -253
- tapps_agents/simple_mode/orchestrators/__init__.py +38 -38
- tapps_agents/simple_mode/orchestrators/breakdown_orchestrator.py +49 -49
- tapps_agents/simple_mode/orchestrators/brownfield_orchestrator.py +135 -135
- tapps_agents/simple_mode/orchestrators/deliverable_checklist.py +349 -349
- tapps_agents/simple_mode/orchestrators/enhance_orchestrator.py +53 -53
- tapps_agents/simple_mode/orchestrators/epic_orchestrator.py +122 -122
- tapps_agents/simple_mode/orchestrators/explore_orchestrator.py +184 -184
- tapps_agents/simple_mode/orchestrators/plan_analysis_orchestrator.py +206 -206
- tapps_agents/simple_mode/orchestrators/pr_orchestrator.py +237 -237
- tapps_agents/simple_mode/orchestrators/refactor_orchestrator.py +222 -222
- tapps_agents/simple_mode/orchestrators/requirements_tracer.py +262 -262
- tapps_agents/simple_mode/orchestrators/resume_orchestrator.py +210 -210
- tapps_agents/simple_mode/orchestrators/review_orchestrator.py +161 -161
- tapps_agents/simple_mode/orchestrators/test_orchestrator.py +82 -82
- tapps_agents/simple_mode/output_aggregator.py +340 -340
- tapps_agents/simple_mode/result_formatters.py +598 -598
- tapps_agents/simple_mode/step_dependencies.py +382 -382
- tapps_agents/simple_mode/step_results.py +276 -276
- tapps_agents/simple_mode/streaming.py +388 -388
- tapps_agents/simple_mode/variations.py +129 -129
- tapps_agents/simple_mode/visual_feedback.py +238 -238
- tapps_agents/simple_mode/zero_config.py +274 -274
- tapps_agents/suggestions/__init__.py +8 -8
- tapps_agents/suggestions/inline_suggester.py +52 -52
- tapps_agents/templates/__init__.py +8 -8
- tapps_agents/templates/microservice_generator.py +274 -274
- tapps_agents/utils/env_validator.py +291 -291
- tapps_agents/workflow/__init__.py +171 -171
- tapps_agents/workflow/acceptance_verifier.py +132 -132
- tapps_agents/workflow/agent_handlers/__init__.py +41 -41
- tapps_agents/workflow/agent_handlers/analyst_handler.py +75 -75
- tapps_agents/workflow/agent_handlers/architect_handler.py +107 -107
- tapps_agents/workflow/agent_handlers/base.py +84 -84
- tapps_agents/workflow/agent_handlers/debugger_handler.py +100 -100
- tapps_agents/workflow/agent_handlers/designer_handler.py +110 -110
- tapps_agents/workflow/agent_handlers/documenter_handler.py +94 -94
- tapps_agents/workflow/agent_handlers/implementer_handler.py +235 -235
- tapps_agents/workflow/agent_handlers/ops_handler.py +62 -62
- tapps_agents/workflow/agent_handlers/orchestrator_handler.py +43 -43
- tapps_agents/workflow/agent_handlers/planner_handler.py +98 -98
- tapps_agents/workflow/agent_handlers/registry.py +119 -119
- tapps_agents/workflow/agent_handlers/reviewer_handler.py +119 -119
- tapps_agents/workflow/agent_handlers/tester_handler.py +69 -69
- tapps_agents/workflow/analytics_accessor.py +337 -337
- tapps_agents/workflow/analytics_alerts.py +416 -416
- tapps_agents/workflow/analytics_dashboard_cursor.py +281 -281
- tapps_agents/workflow/analytics_dual_write.py +103 -103
- tapps_agents/workflow/analytics_integration.py +119 -119
- tapps_agents/workflow/analytics_query_parser.py +278 -278
- tapps_agents/workflow/analytics_visualizer.py +259 -259
- tapps_agents/workflow/artifact_helper.py +204 -204
- tapps_agents/workflow/audit_logger.py +263 -263
- tapps_agents/workflow/auto_execution_config.py +340 -340
- tapps_agents/workflow/auto_progression.py +586 -586
- tapps_agents/workflow/branch_cleanup.py +349 -349
- tapps_agents/workflow/checkpoint.py +256 -256
- tapps_agents/workflow/checkpoint_manager.py +178 -178
- tapps_agents/workflow/code_artifact.py +179 -179
- tapps_agents/workflow/common_enums.py +96 -96
- tapps_agents/workflow/confirmation_handler.py +130 -130
- tapps_agents/workflow/context_analyzer.py +222 -222
- tapps_agents/workflow/context_artifact.py +230 -230
- tapps_agents/workflow/cursor_chat.py +94 -94
- tapps_agents/workflow/cursor_skill_helper.py +516 -516
- tapps_agents/workflow/dependency_resolver.py +244 -244
- tapps_agents/workflow/design_artifact.py +156 -156
- tapps_agents/workflow/detector.py +751 -751
- tapps_agents/workflow/direct_execution_fallback.py +301 -301
- tapps_agents/workflow/docs_artifact.py +168 -168
- tapps_agents/workflow/enforcer.py +389 -389
- tapps_agents/workflow/enhancement_artifact.py +142 -142
- tapps_agents/workflow/error_recovery.py +806 -806
- tapps_agents/workflow/event_bus.py +183 -183
- tapps_agents/workflow/event_log.py +612 -612
- tapps_agents/workflow/events.py +63 -63
- tapps_agents/workflow/exceptions.py +43 -43
- tapps_agents/workflow/execution_graph.py +498 -498
- tapps_agents/workflow/execution_plan.py +126 -126
- tapps_agents/workflow/file_utils.py +186 -186
- tapps_agents/workflow/gate_evaluator.py +182 -182
- tapps_agents/workflow/gate_integration.py +200 -200
- tapps_agents/workflow/graph_visualizer.py +130 -130
- tapps_agents/workflow/health_checker.py +206 -206
- tapps_agents/workflow/logging_helper.py +243 -243
- tapps_agents/workflow/manifest.py +582 -582
- tapps_agents/workflow/marker_writer.py +250 -250
- tapps_agents/workflow/messaging.py +325 -325
- tapps_agents/workflow/metadata_models.py +91 -91
- tapps_agents/workflow/metrics_integration.py +226 -226
- tapps_agents/workflow/migration_utils.py +116 -116
- tapps_agents/workflow/models.py +148 -148
- tapps_agents/workflow/nlp_config.py +198 -198
- tapps_agents/workflow/nlp_error_handler.py +207 -207
- tapps_agents/workflow/nlp_executor.py +163 -163
- tapps_agents/workflow/nlp_parser.py +528 -528
- tapps_agents/workflow/observability_dashboard.py +451 -451
- tapps_agents/workflow/observer.py +170 -170
- tapps_agents/workflow/ops_artifact.py +257 -257
- tapps_agents/workflow/output_passing.py +214 -214
- tapps_agents/workflow/parallel_executor.py +463 -463
- tapps_agents/workflow/planning_artifact.py +179 -179
- tapps_agents/workflow/preset_loader.py +285 -285
- tapps_agents/workflow/preset_recommender.py +270 -270
- tapps_agents/workflow/progress_logger.py +145 -145
- tapps_agents/workflow/progress_manager.py +303 -303
- tapps_agents/workflow/progress_monitor.py +186 -186
- tapps_agents/workflow/progress_updates.py +423 -423
- tapps_agents/workflow/quality_artifact.py +158 -158
- tapps_agents/workflow/quality_loopback.py +101 -101
- tapps_agents/workflow/recommender.py +387 -387
- tapps_agents/workflow/remediation_loop.py +166 -166
- tapps_agents/workflow/result_aggregator.py +300 -300
- tapps_agents/workflow/review_artifact.py +185 -185
- tapps_agents/workflow/schema_validator.py +522 -522
- tapps_agents/workflow/session_handoff.py +178 -178
- tapps_agents/workflow/skill_invoker.py +648 -648
- tapps_agents/workflow/state_manager.py +756 -756
- tapps_agents/workflow/state_persistence_config.py +331 -331
- tapps_agents/workflow/status_monitor.py +449 -449
- tapps_agents/workflow/step_checkpoint.py +314 -314
- tapps_agents/workflow/step_details.py +201 -201
- tapps_agents/workflow/story_models.py +147 -147
- tapps_agents/workflow/streaming.py +416 -416
- tapps_agents/workflow/suggestion_engine.py +552 -552
- tapps_agents/workflow/testing_artifact.py +186 -186
- tapps_agents/workflow/timeline.py +158 -158
- tapps_agents/workflow/token_integration.py +209 -209
- tapps_agents/workflow/validation.py +217 -217
- tapps_agents/workflow/visual_feedback.py +391 -391
- tapps_agents/workflow/workflow_chain.py +95 -95
- tapps_agents/workflow/workflow_summary.py +219 -219
- tapps_agents/workflow/worktree_manager.py +724 -724
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/METADATA +672 -672
- tapps_agents-3.6.1.dist-info/RECORD +883 -0
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/licenses/LICENSE +22 -22
- tapps_agents-3.6.0.dist-info/RECORD +0 -758
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/WHEEL +0 -0
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/entry_points.txt +0 -0
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/top_level.txt +0 -0
|
@@ -1,641 +1,641 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Priority Evaluator - Objective priority evaluation engine for recommendations.
|
|
3
|
-
|
|
4
|
-
Provides consistent, independent, and reproducible priority classification
|
|
5
|
-
for fixes and enhancements based on multiple objective factors.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import json
|
|
9
|
-
from dataclasses import dataclass
|
|
10
|
-
from datetime import datetime, timedelta
|
|
11
|
-
from pathlib import Path
|
|
12
|
-
from typing import Any
|
|
13
|
-
|
|
14
|
-
from ...core.config import ProjectConfig, load_config
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@dataclass
|
|
18
|
-
class PriorityResult:
|
|
19
|
-
"""Result of priority evaluation."""
|
|
20
|
-
priority: str # "critical", "high", "medium", "low"
|
|
21
|
-
score: float # 0.0-10.0
|
|
22
|
-
factors: dict[str, float] # Factor scores
|
|
23
|
-
rationale: str # Explanation of priority assignment
|
|
24
|
-
recommendation_id: str | None = None # Optional recommendation ID
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class FactorExtractor:
|
|
28
|
-
"""
|
|
29
|
-
Extracts objective factors from recommendations and data sources.
|
|
30
|
-
|
|
31
|
-
Analyzes recommendation descriptions, quality data, workflow data,
|
|
32
|
-
and usage data to extract objective metrics for priority evaluation.
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
# Keyword patterns for factor extraction
|
|
36
|
-
IMPACT_SEVERITY_KEYWORDS = {
|
|
37
|
-
"security": 10,
|
|
38
|
-
"vulnerability": 10,
|
|
39
|
-
"breach": 10,
|
|
40
|
-
"data loss": 9,
|
|
41
|
-
"corruption": 9,
|
|
42
|
-
"failure": 8,
|
|
43
|
-
"broken": 7,
|
|
44
|
-
"error": 6,
|
|
45
|
-
"issue": 5,
|
|
46
|
-
"improvement": 3,
|
|
47
|
-
"enhancement": 2,
|
|
48
|
-
"cosmetic": 1,
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
EFFORT_KEYWORDS = {
|
|
52
|
-
"quick fix": 1,
|
|
53
|
-
"simple": 2,
|
|
54
|
-
"easy": 2,
|
|
55
|
-
"minor": 3,
|
|
56
|
-
"moderate": 4,
|
|
57
|
-
"complex": 6,
|
|
58
|
-
"refactor": 7,
|
|
59
|
-
"major": 8,
|
|
60
|
-
"rewrite": 9,
|
|
61
|
-
"architectural": 10,
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
RISK_KEYWORDS = {
|
|
65
|
-
"outage": 10,
|
|
66
|
-
"downtime": 9,
|
|
67
|
-
"security breach": 9,
|
|
68
|
-
"data corruption": 8,
|
|
69
|
-
"vulnerability": 9,
|
|
70
|
-
"injection": 9,
|
|
71
|
-
"xss": 8,
|
|
72
|
-
"csrf": 8,
|
|
73
|
-
"frustration": 6,
|
|
74
|
-
"confusion": 4,
|
|
75
|
-
"minor": 2,
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
def extract(
|
|
79
|
-
self,
|
|
80
|
-
recommendation: dict[str, Any],
|
|
81
|
-
quality_data: dict[str, Any] | None = None,
|
|
82
|
-
workflow_data: dict[str, Any] | None = None,
|
|
83
|
-
usage_data: dict[str, Any] | None = None
|
|
84
|
-
) -> dict[str, float]:
|
|
85
|
-
"""
|
|
86
|
-
Extract objective factors from recommendation.
|
|
87
|
-
|
|
88
|
-
Args:
|
|
89
|
-
recommendation: Recommendation dictionary
|
|
90
|
-
quality_data: Quality analysis data
|
|
91
|
-
workflow_data: Workflow analysis data
|
|
92
|
-
usage_data: Usage analysis data
|
|
93
|
-
|
|
94
|
-
Returns:
|
|
95
|
-
Dictionary with factor scores (0-10)
|
|
96
|
-
"""
|
|
97
|
-
description = (recommendation.get("description") or recommendation.get("recommendation") or "").lower()
|
|
98
|
-
|
|
99
|
-
return {
|
|
100
|
-
"impact_severity": self._extract_impact_severity(description, quality_data, workflow_data),
|
|
101
|
-
"effort_complexity": self._extract_effort_complexity(description, quality_data),
|
|
102
|
-
"risk_level": self._extract_risk_level(description, quality_data),
|
|
103
|
-
"user_impact": self._extract_user_impact(usage_data, workflow_data),
|
|
104
|
-
"business_value": self._extract_business_value(description),
|
|
105
|
-
"code_quality_impact": self._extract_code_quality_impact(description, quality_data),
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
def _extract_impact_severity(
|
|
109
|
-
self,
|
|
110
|
-
description: str,
|
|
111
|
-
quality_data: dict[str, Any] | None,
|
|
112
|
-
workflow_data: dict[str, Any] | None
|
|
113
|
-
) -> float:
|
|
114
|
-
"""Extract impact severity factor (0-10)."""
|
|
115
|
-
score = 5.0 # Default: medium
|
|
116
|
-
|
|
117
|
-
# Keyword matching (0.6 weight)
|
|
118
|
-
keyword_score = self._match_keywords(description, self.IMPACT_SEVERITY_KEYWORDS)
|
|
119
|
-
score = score * 0.4 + keyword_score * 0.6
|
|
120
|
-
|
|
121
|
-
# Quality score analysis (0.3 weight)
|
|
122
|
-
if quality_data:
|
|
123
|
-
overall_score = quality_data.get("scores", {}).get("overall", 70.0)
|
|
124
|
-
if overall_score < 50:
|
|
125
|
-
score = max(score, 8.0) # Low quality = high severity
|
|
126
|
-
elif overall_score < 60:
|
|
127
|
-
score = max(score, 6.0)
|
|
128
|
-
|
|
129
|
-
# Workflow deviations (0.1 weight)
|
|
130
|
-
if workflow_data:
|
|
131
|
-
deviations = workflow_data.get("deviations", [])
|
|
132
|
-
if deviations:
|
|
133
|
-
high_impact_deviations = [d for d in deviations if d.get("impact") == "high"]
|
|
134
|
-
if high_impact_deviations:
|
|
135
|
-
score = max(score, 7.0)
|
|
136
|
-
|
|
137
|
-
return self._clamp(score, 0.0, 10.0)
|
|
138
|
-
|
|
139
|
-
def _extract_effort_complexity(
|
|
140
|
-
self,
|
|
141
|
-
description: str,
|
|
142
|
-
quality_data: dict[str, Any] | None
|
|
143
|
-
) -> float:
|
|
144
|
-
"""Extract effort complexity factor (0-10, inverted: lower = higher priority)."""
|
|
145
|
-
score = 5.0 # Default: medium
|
|
146
|
-
|
|
147
|
-
# Keyword matching (0.7 weight)
|
|
148
|
-
keyword_score = self._match_keywords(description, self.EFFORT_KEYWORDS)
|
|
149
|
-
score = score * 0.3 + keyword_score * 0.7
|
|
150
|
-
|
|
151
|
-
return self._clamp(score, 0.0, 10.0)
|
|
152
|
-
|
|
153
|
-
def _extract_risk_level(
|
|
154
|
-
self,
|
|
155
|
-
description: str,
|
|
156
|
-
quality_data: dict[str, Any] | None
|
|
157
|
-
) -> float:
|
|
158
|
-
"""Extract risk level factor (0-10)."""
|
|
159
|
-
score = 5.0 # Default: medium
|
|
160
|
-
|
|
161
|
-
# Keyword matching (0.8 weight)
|
|
162
|
-
keyword_score = self._match_keywords(description, self.RISK_KEYWORDS)
|
|
163
|
-
score = score * 0.2 + keyword_score * 0.8
|
|
164
|
-
|
|
165
|
-
# Security indicators (0.2 weight)
|
|
166
|
-
security_keywords = ["security", "vulnerability", "breach", "injection", "xss", "csrf"]
|
|
167
|
-
if any(kw in description for kw in security_keywords):
|
|
168
|
-
score = max(score, 8.0)
|
|
169
|
-
|
|
170
|
-
return self._clamp(score, 0.0, 10.0)
|
|
171
|
-
|
|
172
|
-
def _extract_user_impact(
|
|
173
|
-
self,
|
|
174
|
-
usage_data: dict[str, Any] | None,
|
|
175
|
-
workflow_data: dict[str, Any] | None
|
|
176
|
-
) -> float:
|
|
177
|
-
"""Extract user impact factor (0-10)."""
|
|
178
|
-
score = 5.0 # Default: medium
|
|
179
|
-
|
|
180
|
-
if usage_data:
|
|
181
|
-
stats = usage_data.get("statistics", {})
|
|
182
|
-
total_commands = stats.get("total_commands", 0)
|
|
183
|
-
|
|
184
|
-
# High usage = high user impact
|
|
185
|
-
if total_commands > 1000:
|
|
186
|
-
score = 8.0
|
|
187
|
-
elif total_commands > 500:
|
|
188
|
-
score = 6.0
|
|
189
|
-
elif total_commands > 100:
|
|
190
|
-
score = 4.0
|
|
191
|
-
|
|
192
|
-
if workflow_data:
|
|
193
|
-
step_analysis = workflow_data.get("step_analysis", {})
|
|
194
|
-
completion_rate = step_analysis.get("completion_rate", 1.0)
|
|
195
|
-
|
|
196
|
-
# Low completion rate = high user impact (workflow broken)
|
|
197
|
-
if completion_rate < 0.5:
|
|
198
|
-
score = max(score, 8.0)
|
|
199
|
-
elif completion_rate < 0.8:
|
|
200
|
-
score = max(score, 6.0)
|
|
201
|
-
|
|
202
|
-
return self._clamp(score, 0.0, 10.0)
|
|
203
|
-
|
|
204
|
-
def _extract_business_value(self, description: str) -> float:
|
|
205
|
-
"""Extract business value factor (0-10)."""
|
|
206
|
-
score = 5.0 # Default: medium
|
|
207
|
-
|
|
208
|
-
business_keywords = {
|
|
209
|
-
"revenue": 10,
|
|
210
|
-
"customer": 8,
|
|
211
|
-
"competitive": 8,
|
|
212
|
-
"adoption": 7,
|
|
213
|
-
"productivity": 6,
|
|
214
|
-
"efficiency": 5,
|
|
215
|
-
"maintainability": 4,
|
|
216
|
-
"technical debt": 3,
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
keyword_score = self._match_keywords(description, business_keywords)
|
|
220
|
-
score = score * 0.3 + keyword_score * 0.7
|
|
221
|
-
|
|
222
|
-
return self._clamp(score, 0.0, 10.0)
|
|
223
|
-
|
|
224
|
-
def _extract_code_quality_impact(
|
|
225
|
-
self,
|
|
226
|
-
description: str,
|
|
227
|
-
quality_data: dict[str, Any] | None
|
|
228
|
-
) -> float:
|
|
229
|
-
"""Extract code quality impact factor (0-10)."""
|
|
230
|
-
score = 5.0 # Default: medium
|
|
231
|
-
|
|
232
|
-
if quality_data:
|
|
233
|
-
scores = quality_data.get("scores", {})
|
|
234
|
-
overall = scores.get("overall", 70.0)
|
|
235
|
-
|
|
236
|
-
# Low quality = high improvement potential
|
|
237
|
-
if overall < 50:
|
|
238
|
-
score = 8.0 # High impact potential
|
|
239
|
-
elif overall < 60:
|
|
240
|
-
score = 6.0
|
|
241
|
-
elif overall < 70:
|
|
242
|
-
score = 4.0
|
|
243
|
-
|
|
244
|
-
quality_keywords = {
|
|
245
|
-
"test coverage": 7,
|
|
246
|
-
"maintainability": 6,
|
|
247
|
-
"technical debt": 5,
|
|
248
|
-
"code quality": 4,
|
|
249
|
-
"refactor": 6,
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
keyword_score = self._match_keywords(description, quality_keywords)
|
|
253
|
-
score = max(score, keyword_score * 0.2)
|
|
254
|
-
|
|
255
|
-
return self._clamp(score, 0.0, 10.0)
|
|
256
|
-
|
|
257
|
-
def _match_keywords(self, text: str, keywords: dict[str, float]) -> float:
|
|
258
|
-
"""Match keywords in text and return highest score found."""
|
|
259
|
-
if not text:
|
|
260
|
-
return 5.0
|
|
261
|
-
|
|
262
|
-
max_score = 0.0
|
|
263
|
-
for keyword, score in keywords.items():
|
|
264
|
-
if keyword in text:
|
|
265
|
-
max_score = max(max_score, score)
|
|
266
|
-
|
|
267
|
-
return max_score if max_score > 0 else 5.0
|
|
268
|
-
|
|
269
|
-
def _clamp(self, value: float, min_val: float, max_val: float) -> float:
|
|
270
|
-
"""Clamp value to range."""
|
|
271
|
-
return max(min_val, min(max_val, value))
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
class ScoreCalculator:
|
|
275
|
-
"""
|
|
276
|
-
Calculates priority scores from factor scores using weighted formula.
|
|
277
|
-
"""
|
|
278
|
-
|
|
279
|
-
DEFAULT_WEIGHTS = {
|
|
280
|
-
"impact_severity": 0.25,
|
|
281
|
-
"effort_complexity": 0.20, # Inverted: easier = higher priority
|
|
282
|
-
"risk_level": 0.20,
|
|
283
|
-
"user_impact": 0.15,
|
|
284
|
-
"business_value": 0.10,
|
|
285
|
-
"code_quality_impact": 0.10
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
def calculate(
|
|
289
|
-
self,
|
|
290
|
-
factors: dict[str, float],
|
|
291
|
-
weights: dict[str, float] | None = None
|
|
292
|
-
) -> float:
|
|
293
|
-
"""
|
|
294
|
-
Calculate priority score from factors.
|
|
295
|
-
|
|
296
|
-
Args:
|
|
297
|
-
factors: Factor scores (0-10)
|
|
298
|
-
weights: Factor weights (default: DEFAULT_WEIGHTS)
|
|
299
|
-
|
|
300
|
-
Returns:
|
|
301
|
-
Priority score (0-10)
|
|
302
|
-
"""
|
|
303
|
-
if weights is None:
|
|
304
|
-
weights = self.DEFAULT_WEIGHTS
|
|
305
|
-
|
|
306
|
-
# Validate weights sum to 1.0
|
|
307
|
-
total_weight = sum(weights.values())
|
|
308
|
-
if abs(total_weight - 1.0) > 0.01:
|
|
309
|
-
raise ValueError(f"Weights must sum to 1.0, got {total_weight}")
|
|
310
|
-
|
|
311
|
-
# Calculate weighted score
|
|
312
|
-
# Note: effort_complexity is inverted (lower effort = higher priority)
|
|
313
|
-
score = (
|
|
314
|
-
factors.get("impact_severity", 5.0) * weights.get("impact_severity", 0.25) +
|
|
315
|
-
(10.0 - factors.get("effort_complexity", 5.0)) * weights.get("effort_complexity", 0.20) +
|
|
316
|
-
factors.get("risk_level", 5.0) * weights.get("risk_level", 0.20) +
|
|
317
|
-
factors.get("user_impact", 5.0) * weights.get("user_impact", 0.15) +
|
|
318
|
-
factors.get("business_value", 5.0) * weights.get("business_value", 0.10) +
|
|
319
|
-
factors.get("code_quality_impact", 5.0) * weights.get("code_quality_impact", 0.10)
|
|
320
|
-
)
|
|
321
|
-
|
|
322
|
-
return self._clamp(score, 0.0, 10.0)
|
|
323
|
-
|
|
324
|
-
def _clamp(self, value: float, min_val: float, max_val: float) -> float:
|
|
325
|
-
"""Clamp value to range."""
|
|
326
|
-
return max(min_val, min(max_val, value))
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
class PriorityClassifier:
|
|
330
|
-
"""
|
|
331
|
-
Classifies priority scores into priority levels.
|
|
332
|
-
"""
|
|
333
|
-
|
|
334
|
-
DEFAULT_THRESHOLDS = {
|
|
335
|
-
"critical": 8.5,
|
|
336
|
-
"high": 7.0,
|
|
337
|
-
"medium": 5.0,
|
|
338
|
-
"low": 0.0
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
PRIORITY_RATIONALE = {
|
|
342
|
-
"critical": "High impact, low effort, or high risk issue requiring immediate attention",
|
|
343
|
-
"high": "Significant impact or moderate risk issue that should be addressed soon",
|
|
344
|
-
"medium": "Moderate impact issue that can be addressed when resources allow",
|
|
345
|
-
"low": "Low impact improvement or nice-to-have feature"
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
def classify(
|
|
349
|
-
self,
|
|
350
|
-
score: float,
|
|
351
|
-
thresholds: dict[str, float] | None = None
|
|
352
|
-
) -> tuple[str, str]:
|
|
353
|
-
"""
|
|
354
|
-
Classify priority score into priority level.
|
|
355
|
-
|
|
356
|
-
Args:
|
|
357
|
-
score: Priority score (0-10)
|
|
358
|
-
thresholds: Priority thresholds (default: DEFAULT_THRESHOLDS)
|
|
359
|
-
|
|
360
|
-
Returns:
|
|
361
|
-
Tuple of (priority_level, rationale)
|
|
362
|
-
"""
|
|
363
|
-
if thresholds is None:
|
|
364
|
-
thresholds = self.DEFAULT_THRESHOLDS
|
|
365
|
-
|
|
366
|
-
# Classify based on thresholds
|
|
367
|
-
if score >= thresholds.get("critical", 8.5):
|
|
368
|
-
priority = "critical"
|
|
369
|
-
elif score >= thresholds.get("high", 7.0):
|
|
370
|
-
priority = "high"
|
|
371
|
-
elif score >= thresholds.get("medium", 5.0):
|
|
372
|
-
priority = "medium"
|
|
373
|
-
else:
|
|
374
|
-
priority = "low"
|
|
375
|
-
|
|
376
|
-
rationale = self.PRIORITY_RATIONALE.get(priority, "Unknown priority")
|
|
377
|
-
|
|
378
|
-
return priority, rationale
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
class PriorityEvaluator:
|
|
382
|
-
"""
|
|
383
|
-
Objective priority evaluation engine for recommendations.
|
|
384
|
-
|
|
385
|
-
Evaluates recommendations using multiple objective factors to produce
|
|
386
|
-
consistent, reproducible priority assignments.
|
|
387
|
-
"""
|
|
388
|
-
|
|
389
|
-
def __init__(
|
|
390
|
-
self,
|
|
391
|
-
config: ProjectConfig | None = None,
|
|
392
|
-
project_root: Path | None = None
|
|
393
|
-
):
|
|
394
|
-
"""
|
|
395
|
-
Initialize priority evaluator.
|
|
396
|
-
|
|
397
|
-
Args:
|
|
398
|
-
config: Project configuration
|
|
399
|
-
project_root: Project root directory for history tracking
|
|
400
|
-
"""
|
|
401
|
-
if config is None:
|
|
402
|
-
config = load_config()
|
|
403
|
-
self.config = config
|
|
404
|
-
self.project_root = project_root or Path.cwd()
|
|
405
|
-
|
|
406
|
-
# Initialize components
|
|
407
|
-
self.factor_extractor = FactorExtractor()
|
|
408
|
-
self.score_calculator = ScoreCalculator()
|
|
409
|
-
self.priority_classifier = PriorityClassifier()
|
|
410
|
-
|
|
411
|
-
# Get configuration (will be added to config later)
|
|
412
|
-
self.weights = self._get_weights()
|
|
413
|
-
self.thresholds = self._get_thresholds()
|
|
414
|
-
self.enable_history = self._get_enable_history()
|
|
415
|
-
|
|
416
|
-
def _get_weights(self) -> dict[str, float]:
|
|
417
|
-
"""Get factor weights from config or use defaults."""
|
|
418
|
-
# TODO: Add to config.yaml structure
|
|
419
|
-
# For now, use defaults
|
|
420
|
-
return ScoreCalculator.DEFAULT_WEIGHTS
|
|
421
|
-
|
|
422
|
-
def _get_thresholds(self) -> dict[str, float]:
|
|
423
|
-
"""Get priority thresholds from config or use defaults."""
|
|
424
|
-
# TODO: Add to config.yaml structure
|
|
425
|
-
# For now, use defaults
|
|
426
|
-
return PriorityClassifier.DEFAULT_THRESHOLDS
|
|
427
|
-
|
|
428
|
-
def _get_enable_history(self) -> bool:
|
|
429
|
-
"""Get enable history flag from config or use defaults."""
|
|
430
|
-
# TODO: Add to config.yaml structure
|
|
431
|
-
# For now, use defaults
|
|
432
|
-
return True
|
|
433
|
-
|
|
434
|
-
def evaluate(
|
|
435
|
-
self,
|
|
436
|
-
recommendation: dict[str, Any],
|
|
437
|
-
quality_data: dict[str, Any] | None = None,
|
|
438
|
-
workflow_data: dict[str, Any] | None = None,
|
|
439
|
-
usage_data: dict[str, Any] | None = None
|
|
440
|
-
) -> PriorityResult:
|
|
441
|
-
"""
|
|
442
|
-
Evaluate recommendation priority.
|
|
443
|
-
|
|
444
|
-
Args:
|
|
445
|
-
recommendation: Recommendation dictionary with description, type, etc.
|
|
446
|
-
quality_data: Quality analysis data (from QualityAnalyzer)
|
|
447
|
-
workflow_data: Workflow analysis data (from WorkflowAnalyzer)
|
|
448
|
-
usage_data: Usage analysis data (from UsageAnalyzer)
|
|
449
|
-
|
|
450
|
-
Returns:
|
|
451
|
-
PriorityResult with priority, score, factors, and rationale
|
|
452
|
-
"""
|
|
453
|
-
# Extract factors
|
|
454
|
-
factors = self.factor_extractor.extract(
|
|
455
|
-
recommendation=recommendation,
|
|
456
|
-
quality_data=quality_data,
|
|
457
|
-
workflow_data=workflow_data,
|
|
458
|
-
usage_data=usage_data
|
|
459
|
-
)
|
|
460
|
-
|
|
461
|
-
# Calculate score
|
|
462
|
-
score = self.score_calculator.calculate(factors=factors, weights=self.weights)
|
|
463
|
-
|
|
464
|
-
# Classify priority
|
|
465
|
-
priority, rationale = self.priority_classifier.classify(score=score, thresholds=self.thresholds)
|
|
466
|
-
|
|
467
|
-
return PriorityResult(
|
|
468
|
-
priority=priority,
|
|
469
|
-
score=score,
|
|
470
|
-
factors=factors,
|
|
471
|
-
rationale=rationale,
|
|
472
|
-
recommendation_id=recommendation.get("id")
|
|
473
|
-
)
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
class HistoryTracker:
|
|
477
|
-
"""
|
|
478
|
-
Tracks priority evaluation history for trend analysis.
|
|
479
|
-
"""
|
|
480
|
-
|
|
481
|
-
def __init__(self, project_root: Path | None = None):
|
|
482
|
-
"""
|
|
483
|
-
Initialize history tracker.
|
|
484
|
-
|
|
485
|
-
Args:
|
|
486
|
-
project_root: Project root directory for history storage
|
|
487
|
-
"""
|
|
488
|
-
self.project_root = project_root or Path.cwd()
|
|
489
|
-
self.history_dir = self.project_root / ".tapps-agents" / "evaluations" / "history"
|
|
490
|
-
self.history_dir.mkdir(parents=True, exist_ok=True)
|
|
491
|
-
|
|
492
|
-
def track(
|
|
493
|
-
self,
|
|
494
|
-
evaluation_id: str,
|
|
495
|
-
recommendations: list[PriorityResult],
|
|
496
|
-
metadata: dict[str, Any] | None = None
|
|
497
|
-
) -> Path:
|
|
498
|
-
"""
|
|
499
|
-
Store evaluation results in history.
|
|
500
|
-
|
|
501
|
-
Args:
|
|
502
|
-
evaluation_id: Unique evaluation identifier
|
|
503
|
-
recommendations: List of priority evaluation results
|
|
504
|
-
metadata: Additional metadata (evaluation date, etc.)
|
|
505
|
-
|
|
506
|
-
Returns:
|
|
507
|
-
Path to stored history file
|
|
508
|
-
"""
|
|
509
|
-
# Calculate priority distribution
|
|
510
|
-
distribution = {
|
|
511
|
-
"critical": sum(1 for r in recommendations if r.priority == "critical"),
|
|
512
|
-
"high": sum(1 for r in recommendations if r.priority == "high"),
|
|
513
|
-
"medium": sum(1 for r in recommendations if r.priority == "medium"),
|
|
514
|
-
"low": sum(1 for r in recommendations if r.priority == "low"),
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
# Calculate average score
|
|
518
|
-
avg_score = sum(r.score for r in recommendations) / len(recommendations) if recommendations else 0.0
|
|
519
|
-
|
|
520
|
-
# Build history record
|
|
521
|
-
history_record = {
|
|
522
|
-
"evaluation_id": evaluation_id,
|
|
523
|
-
"evaluation_date": (metadata or {}).get("evaluation_date", datetime.now().isoformat()),
|
|
524
|
-
"total_recommendations": len(recommendations),
|
|
525
|
-
"priority_distribution": distribution,
|
|
526
|
-
"average_score": avg_score,
|
|
527
|
-
"recommendations": [
|
|
528
|
-
{
|
|
529
|
-
"id": r.recommendation_id or f"rec-{i}",
|
|
530
|
-
"description": (metadata or {}).get("recommendations", [{}])[i].get("description", "") if i < len((metadata or {}).get("recommendations", [])) else "",
|
|
531
|
-
"priority": r.priority,
|
|
532
|
-
"score": r.score,
|
|
533
|
-
"factors": r.factors,
|
|
534
|
-
"rationale": r.rationale
|
|
535
|
-
}
|
|
536
|
-
for i, r in enumerate(recommendations)
|
|
537
|
-
]
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
# Save to file
|
|
541
|
-
timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
|
|
542
|
-
filename = f"evaluation-{timestamp}.json"
|
|
543
|
-
file_path = self.history_dir / filename
|
|
544
|
-
|
|
545
|
-
file_path.write_text(
|
|
546
|
-
json.dumps(history_record, indent=2),
|
|
547
|
-
encoding="utf-8"
|
|
548
|
-
)
|
|
549
|
-
|
|
550
|
-
return file_path
|
|
551
|
-
|
|
552
|
-
def get_trends(
|
|
553
|
-
self,
|
|
554
|
-
days: int = 30
|
|
555
|
-
) -> dict[str, Any]:
|
|
556
|
-
"""
|
|
557
|
-
Get priority distribution trends over time.
|
|
558
|
-
|
|
559
|
-
Args:
|
|
560
|
-
days: Number of days to analyze
|
|
561
|
-
|
|
562
|
-
Returns:
|
|
563
|
-
Dictionary with trend data
|
|
564
|
-
"""
|
|
565
|
-
# Load historical files from last N days
|
|
566
|
-
cutoff_date = datetime.now() - timedelta(days=days)
|
|
567
|
-
history_files = []
|
|
568
|
-
|
|
569
|
-
for file_path in self.history_dir.glob("evaluation-*.json"):
|
|
570
|
-
try:
|
|
571
|
-
data = json.loads(file_path.read_text(encoding="utf-8"))
|
|
572
|
-
eval_date_str = data.get("evaluation_date", "")
|
|
573
|
-
if eval_date_str:
|
|
574
|
-
eval_date = datetime.fromisoformat(eval_date_str.replace("Z", "+00:00"))
|
|
575
|
-
if eval_date >= cutoff_date:
|
|
576
|
-
history_files.append(data)
|
|
577
|
-
except Exception:
|
|
578
|
-
continue
|
|
579
|
-
|
|
580
|
-
# Sort by date
|
|
581
|
-
history_files.sort(key=lambda x: x.get("evaluation_date", ""))
|
|
582
|
-
|
|
583
|
-
if not history_files:
|
|
584
|
-
return {
|
|
585
|
-
"critical_trend": [],
|
|
586
|
-
"high_trend": [],
|
|
587
|
-
"medium_trend": [],
|
|
588
|
-
"low_trend": [],
|
|
589
|
-
"average_score_trend": [],
|
|
590
|
-
"improvement_metrics": {
|
|
591
|
-
"critical_change_percent": 0.0,
|
|
592
|
-
"high_change_percent": 0.0,
|
|
593
|
-
"average_score_change_percent": 0.0,
|
|
594
|
-
"trend_direction": "stable"
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
# Extract trends
|
|
599
|
-
critical_trend = [h["priority_distribution"]["critical"] for h in history_files]
|
|
600
|
-
high_trend = [h["priority_distribution"]["high"] for h in history_files]
|
|
601
|
-
medium_trend = [h["priority_distribution"]["medium"] for h in history_files]
|
|
602
|
-
low_trend = [h["priority_distribution"]["low"] for h in history_files]
|
|
603
|
-
avg_score_trend = [h["average_score"] for h in history_files]
|
|
604
|
-
|
|
605
|
-
# Calculate improvement metrics
|
|
606
|
-
if len(history_files) >= 2:
|
|
607
|
-
first = history_files[0]
|
|
608
|
-
last = history_files[-1]
|
|
609
|
-
|
|
610
|
-
critical_change = (
|
|
611
|
-
(last["priority_distribution"]["critical"] - first["priority_distribution"]["critical"]) /
|
|
612
|
-
max(first["priority_distribution"]["critical"], 1) * 100
|
|
613
|
-
)
|
|
614
|
-
high_change = (
|
|
615
|
-
(last["priority_distribution"]["high"] - first["priority_distribution"]["high"]) /
|
|
616
|
-
max(first["priority_distribution"]["high"], 1) * 100
|
|
617
|
-
)
|
|
618
|
-
avg_score_change = (
|
|
619
|
-
(last["average_score"] - first["average_score"]) /
|
|
620
|
-
max(first["average_score"], 1) * 100
|
|
621
|
-
)
|
|
622
|
-
else:
|
|
623
|
-
critical_change = 0.0
|
|
624
|
-
high_change = 0.0
|
|
625
|
-
avg_score_change = 0.0
|
|
626
|
-
|
|
627
|
-
trend_direction = "improving" if critical_change < 0 and high_change < 0 else ("declining" if critical_change > 0 or high_change > 0 else "stable")
|
|
628
|
-
|
|
629
|
-
return {
|
|
630
|
-
"critical_trend": critical_trend,
|
|
631
|
-
"high_trend": high_trend,
|
|
632
|
-
"medium_trend": medium_trend,
|
|
633
|
-
"low_trend": low_trend,
|
|
634
|
-
"average_score_trend": avg_score_trend,
|
|
635
|
-
"improvement_metrics": {
|
|
636
|
-
"critical_change_percent": critical_change,
|
|
637
|
-
"high_change_percent": high_change,
|
|
638
|
-
"average_score_change_percent": avg_score_change,
|
|
639
|
-
"trend_direction": trend_direction
|
|
640
|
-
}
|
|
641
|
-
}
|
|
1
|
+
"""
|
|
2
|
+
Priority Evaluator - Objective priority evaluation engine for recommendations.
|
|
3
|
+
|
|
4
|
+
Provides consistent, independent, and reproducible priority classification
|
|
5
|
+
for fixes and enhancements based on multiple objective factors.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
from datetime import datetime, timedelta
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
from ...core.config import ProjectConfig, load_config
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class PriorityResult:
|
|
19
|
+
"""Result of priority evaluation."""
|
|
20
|
+
priority: str # "critical", "high", "medium", "low"
|
|
21
|
+
score: float # 0.0-10.0
|
|
22
|
+
factors: dict[str, float] # Factor scores
|
|
23
|
+
rationale: str # Explanation of priority assignment
|
|
24
|
+
recommendation_id: str | None = None # Optional recommendation ID
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class FactorExtractor:
|
|
28
|
+
"""
|
|
29
|
+
Extracts objective factors from recommendations and data sources.
|
|
30
|
+
|
|
31
|
+
Analyzes recommendation descriptions, quality data, workflow data,
|
|
32
|
+
and usage data to extract objective metrics for priority evaluation.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
# Keyword patterns for factor extraction
|
|
36
|
+
IMPACT_SEVERITY_KEYWORDS = {
|
|
37
|
+
"security": 10,
|
|
38
|
+
"vulnerability": 10,
|
|
39
|
+
"breach": 10,
|
|
40
|
+
"data loss": 9,
|
|
41
|
+
"corruption": 9,
|
|
42
|
+
"failure": 8,
|
|
43
|
+
"broken": 7,
|
|
44
|
+
"error": 6,
|
|
45
|
+
"issue": 5,
|
|
46
|
+
"improvement": 3,
|
|
47
|
+
"enhancement": 2,
|
|
48
|
+
"cosmetic": 1,
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
EFFORT_KEYWORDS = {
|
|
52
|
+
"quick fix": 1,
|
|
53
|
+
"simple": 2,
|
|
54
|
+
"easy": 2,
|
|
55
|
+
"minor": 3,
|
|
56
|
+
"moderate": 4,
|
|
57
|
+
"complex": 6,
|
|
58
|
+
"refactor": 7,
|
|
59
|
+
"major": 8,
|
|
60
|
+
"rewrite": 9,
|
|
61
|
+
"architectural": 10,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
RISK_KEYWORDS = {
|
|
65
|
+
"outage": 10,
|
|
66
|
+
"downtime": 9,
|
|
67
|
+
"security breach": 9,
|
|
68
|
+
"data corruption": 8,
|
|
69
|
+
"vulnerability": 9,
|
|
70
|
+
"injection": 9,
|
|
71
|
+
"xss": 8,
|
|
72
|
+
"csrf": 8,
|
|
73
|
+
"frustration": 6,
|
|
74
|
+
"confusion": 4,
|
|
75
|
+
"minor": 2,
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
def extract(
|
|
79
|
+
self,
|
|
80
|
+
recommendation: dict[str, Any],
|
|
81
|
+
quality_data: dict[str, Any] | None = None,
|
|
82
|
+
workflow_data: dict[str, Any] | None = None,
|
|
83
|
+
usage_data: dict[str, Any] | None = None
|
|
84
|
+
) -> dict[str, float]:
|
|
85
|
+
"""
|
|
86
|
+
Extract objective factors from recommendation.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
recommendation: Recommendation dictionary
|
|
90
|
+
quality_data: Quality analysis data
|
|
91
|
+
workflow_data: Workflow analysis data
|
|
92
|
+
usage_data: Usage analysis data
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
Dictionary with factor scores (0-10)
|
|
96
|
+
"""
|
|
97
|
+
description = (recommendation.get("description") or recommendation.get("recommendation") or "").lower()
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
"impact_severity": self._extract_impact_severity(description, quality_data, workflow_data),
|
|
101
|
+
"effort_complexity": self._extract_effort_complexity(description, quality_data),
|
|
102
|
+
"risk_level": self._extract_risk_level(description, quality_data),
|
|
103
|
+
"user_impact": self._extract_user_impact(usage_data, workflow_data),
|
|
104
|
+
"business_value": self._extract_business_value(description),
|
|
105
|
+
"code_quality_impact": self._extract_code_quality_impact(description, quality_data),
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
def _extract_impact_severity(
|
|
109
|
+
self,
|
|
110
|
+
description: str,
|
|
111
|
+
quality_data: dict[str, Any] | None,
|
|
112
|
+
workflow_data: dict[str, Any] | None
|
|
113
|
+
) -> float:
|
|
114
|
+
"""Extract impact severity factor (0-10)."""
|
|
115
|
+
score = 5.0 # Default: medium
|
|
116
|
+
|
|
117
|
+
# Keyword matching (0.6 weight)
|
|
118
|
+
keyword_score = self._match_keywords(description, self.IMPACT_SEVERITY_KEYWORDS)
|
|
119
|
+
score = score * 0.4 + keyword_score * 0.6
|
|
120
|
+
|
|
121
|
+
# Quality score analysis (0.3 weight)
|
|
122
|
+
if quality_data:
|
|
123
|
+
overall_score = quality_data.get("scores", {}).get("overall", 70.0)
|
|
124
|
+
if overall_score < 50:
|
|
125
|
+
score = max(score, 8.0) # Low quality = high severity
|
|
126
|
+
elif overall_score < 60:
|
|
127
|
+
score = max(score, 6.0)
|
|
128
|
+
|
|
129
|
+
# Workflow deviations (0.1 weight)
|
|
130
|
+
if workflow_data:
|
|
131
|
+
deviations = workflow_data.get("deviations", [])
|
|
132
|
+
if deviations:
|
|
133
|
+
high_impact_deviations = [d for d in deviations if d.get("impact") == "high"]
|
|
134
|
+
if high_impact_deviations:
|
|
135
|
+
score = max(score, 7.0)
|
|
136
|
+
|
|
137
|
+
return self._clamp(score, 0.0, 10.0)
|
|
138
|
+
|
|
139
|
+
def _extract_effort_complexity(
|
|
140
|
+
self,
|
|
141
|
+
description: str,
|
|
142
|
+
quality_data: dict[str, Any] | None
|
|
143
|
+
) -> float:
|
|
144
|
+
"""Extract effort complexity factor (0-10, inverted: lower = higher priority)."""
|
|
145
|
+
score = 5.0 # Default: medium
|
|
146
|
+
|
|
147
|
+
# Keyword matching (0.7 weight)
|
|
148
|
+
keyword_score = self._match_keywords(description, self.EFFORT_KEYWORDS)
|
|
149
|
+
score = score * 0.3 + keyword_score * 0.7
|
|
150
|
+
|
|
151
|
+
return self._clamp(score, 0.0, 10.0)
|
|
152
|
+
|
|
153
|
+
def _extract_risk_level(
|
|
154
|
+
self,
|
|
155
|
+
description: str,
|
|
156
|
+
quality_data: dict[str, Any] | None
|
|
157
|
+
) -> float:
|
|
158
|
+
"""Extract risk level factor (0-10)."""
|
|
159
|
+
score = 5.0 # Default: medium
|
|
160
|
+
|
|
161
|
+
# Keyword matching (0.8 weight)
|
|
162
|
+
keyword_score = self._match_keywords(description, self.RISK_KEYWORDS)
|
|
163
|
+
score = score * 0.2 + keyword_score * 0.8
|
|
164
|
+
|
|
165
|
+
# Security indicators (0.2 weight)
|
|
166
|
+
security_keywords = ["security", "vulnerability", "breach", "injection", "xss", "csrf"]
|
|
167
|
+
if any(kw in description for kw in security_keywords):
|
|
168
|
+
score = max(score, 8.0)
|
|
169
|
+
|
|
170
|
+
return self._clamp(score, 0.0, 10.0)
|
|
171
|
+
|
|
172
|
+
def _extract_user_impact(
|
|
173
|
+
self,
|
|
174
|
+
usage_data: dict[str, Any] | None,
|
|
175
|
+
workflow_data: dict[str, Any] | None
|
|
176
|
+
) -> float:
|
|
177
|
+
"""Extract user impact factor (0-10)."""
|
|
178
|
+
score = 5.0 # Default: medium
|
|
179
|
+
|
|
180
|
+
if usage_data:
|
|
181
|
+
stats = usage_data.get("statistics", {})
|
|
182
|
+
total_commands = stats.get("total_commands", 0)
|
|
183
|
+
|
|
184
|
+
# High usage = high user impact
|
|
185
|
+
if total_commands > 1000:
|
|
186
|
+
score = 8.0
|
|
187
|
+
elif total_commands > 500:
|
|
188
|
+
score = 6.0
|
|
189
|
+
elif total_commands > 100:
|
|
190
|
+
score = 4.0
|
|
191
|
+
|
|
192
|
+
if workflow_data:
|
|
193
|
+
step_analysis = workflow_data.get("step_analysis", {})
|
|
194
|
+
completion_rate = step_analysis.get("completion_rate", 1.0)
|
|
195
|
+
|
|
196
|
+
# Low completion rate = high user impact (workflow broken)
|
|
197
|
+
if completion_rate < 0.5:
|
|
198
|
+
score = max(score, 8.0)
|
|
199
|
+
elif completion_rate < 0.8:
|
|
200
|
+
score = max(score, 6.0)
|
|
201
|
+
|
|
202
|
+
return self._clamp(score, 0.0, 10.0)
|
|
203
|
+
|
|
204
|
+
def _extract_business_value(self, description: str) -> float:
|
|
205
|
+
"""Extract business value factor (0-10)."""
|
|
206
|
+
score = 5.0 # Default: medium
|
|
207
|
+
|
|
208
|
+
business_keywords = {
|
|
209
|
+
"revenue": 10,
|
|
210
|
+
"customer": 8,
|
|
211
|
+
"competitive": 8,
|
|
212
|
+
"adoption": 7,
|
|
213
|
+
"productivity": 6,
|
|
214
|
+
"efficiency": 5,
|
|
215
|
+
"maintainability": 4,
|
|
216
|
+
"technical debt": 3,
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
keyword_score = self._match_keywords(description, business_keywords)
|
|
220
|
+
score = score * 0.3 + keyword_score * 0.7
|
|
221
|
+
|
|
222
|
+
return self._clamp(score, 0.0, 10.0)
|
|
223
|
+
|
|
224
|
+
def _extract_code_quality_impact(
|
|
225
|
+
self,
|
|
226
|
+
description: str,
|
|
227
|
+
quality_data: dict[str, Any] | None
|
|
228
|
+
) -> float:
|
|
229
|
+
"""Extract code quality impact factor (0-10)."""
|
|
230
|
+
score = 5.0 # Default: medium
|
|
231
|
+
|
|
232
|
+
if quality_data:
|
|
233
|
+
scores = quality_data.get("scores", {})
|
|
234
|
+
overall = scores.get("overall", 70.0)
|
|
235
|
+
|
|
236
|
+
# Low quality = high improvement potential
|
|
237
|
+
if overall < 50:
|
|
238
|
+
score = 8.0 # High impact potential
|
|
239
|
+
elif overall < 60:
|
|
240
|
+
score = 6.0
|
|
241
|
+
elif overall < 70:
|
|
242
|
+
score = 4.0
|
|
243
|
+
|
|
244
|
+
quality_keywords = {
|
|
245
|
+
"test coverage": 7,
|
|
246
|
+
"maintainability": 6,
|
|
247
|
+
"technical debt": 5,
|
|
248
|
+
"code quality": 4,
|
|
249
|
+
"refactor": 6,
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
keyword_score = self._match_keywords(description, quality_keywords)
|
|
253
|
+
score = max(score, keyword_score * 0.2)
|
|
254
|
+
|
|
255
|
+
return self._clamp(score, 0.0, 10.0)
|
|
256
|
+
|
|
257
|
+
def _match_keywords(self, text: str, keywords: dict[str, float]) -> float:
|
|
258
|
+
"""Match keywords in text and return highest score found."""
|
|
259
|
+
if not text:
|
|
260
|
+
return 5.0
|
|
261
|
+
|
|
262
|
+
max_score = 0.0
|
|
263
|
+
for keyword, score in keywords.items():
|
|
264
|
+
if keyword in text:
|
|
265
|
+
max_score = max(max_score, score)
|
|
266
|
+
|
|
267
|
+
return max_score if max_score > 0 else 5.0
|
|
268
|
+
|
|
269
|
+
def _clamp(self, value: float, min_val: float, max_val: float) -> float:
|
|
270
|
+
"""Clamp value to range."""
|
|
271
|
+
return max(min_val, min(max_val, value))
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
class ScoreCalculator:
|
|
275
|
+
"""
|
|
276
|
+
Calculates priority scores from factor scores using weighted formula.
|
|
277
|
+
"""
|
|
278
|
+
|
|
279
|
+
DEFAULT_WEIGHTS = {
|
|
280
|
+
"impact_severity": 0.25,
|
|
281
|
+
"effort_complexity": 0.20, # Inverted: easier = higher priority
|
|
282
|
+
"risk_level": 0.20,
|
|
283
|
+
"user_impact": 0.15,
|
|
284
|
+
"business_value": 0.10,
|
|
285
|
+
"code_quality_impact": 0.10
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
def calculate(
|
|
289
|
+
self,
|
|
290
|
+
factors: dict[str, float],
|
|
291
|
+
weights: dict[str, float] | None = None
|
|
292
|
+
) -> float:
|
|
293
|
+
"""
|
|
294
|
+
Calculate priority score from factors.
|
|
295
|
+
|
|
296
|
+
Args:
|
|
297
|
+
factors: Factor scores (0-10)
|
|
298
|
+
weights: Factor weights (default: DEFAULT_WEIGHTS)
|
|
299
|
+
|
|
300
|
+
Returns:
|
|
301
|
+
Priority score (0-10)
|
|
302
|
+
"""
|
|
303
|
+
if weights is None:
|
|
304
|
+
weights = self.DEFAULT_WEIGHTS
|
|
305
|
+
|
|
306
|
+
# Validate weights sum to 1.0
|
|
307
|
+
total_weight = sum(weights.values())
|
|
308
|
+
if abs(total_weight - 1.0) > 0.01:
|
|
309
|
+
raise ValueError(f"Weights must sum to 1.0, got {total_weight}")
|
|
310
|
+
|
|
311
|
+
# Calculate weighted score
|
|
312
|
+
# Note: effort_complexity is inverted (lower effort = higher priority)
|
|
313
|
+
score = (
|
|
314
|
+
factors.get("impact_severity", 5.0) * weights.get("impact_severity", 0.25) +
|
|
315
|
+
(10.0 - factors.get("effort_complexity", 5.0)) * weights.get("effort_complexity", 0.20) +
|
|
316
|
+
factors.get("risk_level", 5.0) * weights.get("risk_level", 0.20) +
|
|
317
|
+
factors.get("user_impact", 5.0) * weights.get("user_impact", 0.15) +
|
|
318
|
+
factors.get("business_value", 5.0) * weights.get("business_value", 0.10) +
|
|
319
|
+
factors.get("code_quality_impact", 5.0) * weights.get("code_quality_impact", 0.10)
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
return self._clamp(score, 0.0, 10.0)
|
|
323
|
+
|
|
324
|
+
def _clamp(self, value: float, min_val: float, max_val: float) -> float:
|
|
325
|
+
"""Clamp value to range."""
|
|
326
|
+
return max(min_val, min(max_val, value))
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
class PriorityClassifier:
|
|
330
|
+
"""
|
|
331
|
+
Classifies priority scores into priority levels.
|
|
332
|
+
"""
|
|
333
|
+
|
|
334
|
+
DEFAULT_THRESHOLDS = {
|
|
335
|
+
"critical": 8.5,
|
|
336
|
+
"high": 7.0,
|
|
337
|
+
"medium": 5.0,
|
|
338
|
+
"low": 0.0
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
PRIORITY_RATIONALE = {
|
|
342
|
+
"critical": "High impact, low effort, or high risk issue requiring immediate attention",
|
|
343
|
+
"high": "Significant impact or moderate risk issue that should be addressed soon",
|
|
344
|
+
"medium": "Moderate impact issue that can be addressed when resources allow",
|
|
345
|
+
"low": "Low impact improvement or nice-to-have feature"
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
def classify(
|
|
349
|
+
self,
|
|
350
|
+
score: float,
|
|
351
|
+
thresholds: dict[str, float] | None = None
|
|
352
|
+
) -> tuple[str, str]:
|
|
353
|
+
"""
|
|
354
|
+
Classify priority score into priority level.
|
|
355
|
+
|
|
356
|
+
Args:
|
|
357
|
+
score: Priority score (0-10)
|
|
358
|
+
thresholds: Priority thresholds (default: DEFAULT_THRESHOLDS)
|
|
359
|
+
|
|
360
|
+
Returns:
|
|
361
|
+
Tuple of (priority_level, rationale)
|
|
362
|
+
"""
|
|
363
|
+
if thresholds is None:
|
|
364
|
+
thresholds = self.DEFAULT_THRESHOLDS
|
|
365
|
+
|
|
366
|
+
# Classify based on thresholds
|
|
367
|
+
if score >= thresholds.get("critical", 8.5):
|
|
368
|
+
priority = "critical"
|
|
369
|
+
elif score >= thresholds.get("high", 7.0):
|
|
370
|
+
priority = "high"
|
|
371
|
+
elif score >= thresholds.get("medium", 5.0):
|
|
372
|
+
priority = "medium"
|
|
373
|
+
else:
|
|
374
|
+
priority = "low"
|
|
375
|
+
|
|
376
|
+
rationale = self.PRIORITY_RATIONALE.get(priority, "Unknown priority")
|
|
377
|
+
|
|
378
|
+
return priority, rationale
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
class PriorityEvaluator:
|
|
382
|
+
"""
|
|
383
|
+
Objective priority evaluation engine for recommendations.
|
|
384
|
+
|
|
385
|
+
Evaluates recommendations using multiple objective factors to produce
|
|
386
|
+
consistent, reproducible priority assignments.
|
|
387
|
+
"""
|
|
388
|
+
|
|
389
|
+
def __init__(
|
|
390
|
+
self,
|
|
391
|
+
config: ProjectConfig | None = None,
|
|
392
|
+
project_root: Path | None = None
|
|
393
|
+
):
|
|
394
|
+
"""
|
|
395
|
+
Initialize priority evaluator.
|
|
396
|
+
|
|
397
|
+
Args:
|
|
398
|
+
config: Project configuration
|
|
399
|
+
project_root: Project root directory for history tracking
|
|
400
|
+
"""
|
|
401
|
+
if config is None:
|
|
402
|
+
config = load_config()
|
|
403
|
+
self.config = config
|
|
404
|
+
self.project_root = project_root or Path.cwd()
|
|
405
|
+
|
|
406
|
+
# Initialize components
|
|
407
|
+
self.factor_extractor = FactorExtractor()
|
|
408
|
+
self.score_calculator = ScoreCalculator()
|
|
409
|
+
self.priority_classifier = PriorityClassifier()
|
|
410
|
+
|
|
411
|
+
# Get configuration (will be added to config later)
|
|
412
|
+
self.weights = self._get_weights()
|
|
413
|
+
self.thresholds = self._get_thresholds()
|
|
414
|
+
self.enable_history = self._get_enable_history()
|
|
415
|
+
|
|
416
|
+
def _get_weights(self) -> dict[str, float]:
|
|
417
|
+
"""Get factor weights from config or use defaults."""
|
|
418
|
+
# TODO: Add to config.yaml structure
|
|
419
|
+
# For now, use defaults
|
|
420
|
+
return ScoreCalculator.DEFAULT_WEIGHTS
|
|
421
|
+
|
|
422
|
+
def _get_thresholds(self) -> dict[str, float]:
|
|
423
|
+
"""Get priority thresholds from config or use defaults."""
|
|
424
|
+
# TODO: Add to config.yaml structure
|
|
425
|
+
# For now, use defaults
|
|
426
|
+
return PriorityClassifier.DEFAULT_THRESHOLDS
|
|
427
|
+
|
|
428
|
+
def _get_enable_history(self) -> bool:
|
|
429
|
+
"""Get enable history flag from config or use defaults."""
|
|
430
|
+
# TODO: Add to config.yaml structure
|
|
431
|
+
# For now, use defaults
|
|
432
|
+
return True
|
|
433
|
+
|
|
434
|
+
def evaluate(
|
|
435
|
+
self,
|
|
436
|
+
recommendation: dict[str, Any],
|
|
437
|
+
quality_data: dict[str, Any] | None = None,
|
|
438
|
+
workflow_data: dict[str, Any] | None = None,
|
|
439
|
+
usage_data: dict[str, Any] | None = None
|
|
440
|
+
) -> PriorityResult:
|
|
441
|
+
"""
|
|
442
|
+
Evaluate recommendation priority.
|
|
443
|
+
|
|
444
|
+
Args:
|
|
445
|
+
recommendation: Recommendation dictionary with description, type, etc.
|
|
446
|
+
quality_data: Quality analysis data (from QualityAnalyzer)
|
|
447
|
+
workflow_data: Workflow analysis data (from WorkflowAnalyzer)
|
|
448
|
+
usage_data: Usage analysis data (from UsageAnalyzer)
|
|
449
|
+
|
|
450
|
+
Returns:
|
|
451
|
+
PriorityResult with priority, score, factors, and rationale
|
|
452
|
+
"""
|
|
453
|
+
# Extract factors
|
|
454
|
+
factors = self.factor_extractor.extract(
|
|
455
|
+
recommendation=recommendation,
|
|
456
|
+
quality_data=quality_data,
|
|
457
|
+
workflow_data=workflow_data,
|
|
458
|
+
usage_data=usage_data
|
|
459
|
+
)
|
|
460
|
+
|
|
461
|
+
# Calculate score
|
|
462
|
+
score = self.score_calculator.calculate(factors=factors, weights=self.weights)
|
|
463
|
+
|
|
464
|
+
# Classify priority
|
|
465
|
+
priority, rationale = self.priority_classifier.classify(score=score, thresholds=self.thresholds)
|
|
466
|
+
|
|
467
|
+
return PriorityResult(
|
|
468
|
+
priority=priority,
|
|
469
|
+
score=score,
|
|
470
|
+
factors=factors,
|
|
471
|
+
rationale=rationale,
|
|
472
|
+
recommendation_id=recommendation.get("id")
|
|
473
|
+
)
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
class HistoryTracker:
|
|
477
|
+
"""
|
|
478
|
+
Tracks priority evaluation history for trend analysis.
|
|
479
|
+
"""
|
|
480
|
+
|
|
481
|
+
def __init__(self, project_root: Path | None = None):
|
|
482
|
+
"""
|
|
483
|
+
Initialize history tracker.
|
|
484
|
+
|
|
485
|
+
Args:
|
|
486
|
+
project_root: Project root directory for history storage
|
|
487
|
+
"""
|
|
488
|
+
self.project_root = project_root or Path.cwd()
|
|
489
|
+
self.history_dir = self.project_root / ".tapps-agents" / "evaluations" / "history"
|
|
490
|
+
self.history_dir.mkdir(parents=True, exist_ok=True)
|
|
491
|
+
|
|
492
|
+
def track(
|
|
493
|
+
self,
|
|
494
|
+
evaluation_id: str,
|
|
495
|
+
recommendations: list[PriorityResult],
|
|
496
|
+
metadata: dict[str, Any] | None = None
|
|
497
|
+
) -> Path:
|
|
498
|
+
"""
|
|
499
|
+
Store evaluation results in history.
|
|
500
|
+
|
|
501
|
+
Args:
|
|
502
|
+
evaluation_id: Unique evaluation identifier
|
|
503
|
+
recommendations: List of priority evaluation results
|
|
504
|
+
metadata: Additional metadata (evaluation date, etc.)
|
|
505
|
+
|
|
506
|
+
Returns:
|
|
507
|
+
Path to stored history file
|
|
508
|
+
"""
|
|
509
|
+
# Calculate priority distribution
|
|
510
|
+
distribution = {
|
|
511
|
+
"critical": sum(1 for r in recommendations if r.priority == "critical"),
|
|
512
|
+
"high": sum(1 for r in recommendations if r.priority == "high"),
|
|
513
|
+
"medium": sum(1 for r in recommendations if r.priority == "medium"),
|
|
514
|
+
"low": sum(1 for r in recommendations if r.priority == "low"),
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
# Calculate average score
|
|
518
|
+
avg_score = sum(r.score for r in recommendations) / len(recommendations) if recommendations else 0.0
|
|
519
|
+
|
|
520
|
+
# Build history record
|
|
521
|
+
history_record = {
|
|
522
|
+
"evaluation_id": evaluation_id,
|
|
523
|
+
"evaluation_date": (metadata or {}).get("evaluation_date", datetime.now().isoformat()),
|
|
524
|
+
"total_recommendations": len(recommendations),
|
|
525
|
+
"priority_distribution": distribution,
|
|
526
|
+
"average_score": avg_score,
|
|
527
|
+
"recommendations": [
|
|
528
|
+
{
|
|
529
|
+
"id": r.recommendation_id or f"rec-{i}",
|
|
530
|
+
"description": (metadata or {}).get("recommendations", [{}])[i].get("description", "") if i < len((metadata or {}).get("recommendations", [])) else "",
|
|
531
|
+
"priority": r.priority,
|
|
532
|
+
"score": r.score,
|
|
533
|
+
"factors": r.factors,
|
|
534
|
+
"rationale": r.rationale
|
|
535
|
+
}
|
|
536
|
+
for i, r in enumerate(recommendations)
|
|
537
|
+
]
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
# Save to file
|
|
541
|
+
timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
|
|
542
|
+
filename = f"evaluation-{timestamp}.json"
|
|
543
|
+
file_path = self.history_dir / filename
|
|
544
|
+
|
|
545
|
+
file_path.write_text(
|
|
546
|
+
json.dumps(history_record, indent=2),
|
|
547
|
+
encoding="utf-8"
|
|
548
|
+
)
|
|
549
|
+
|
|
550
|
+
return file_path
|
|
551
|
+
|
|
552
|
+
def get_trends(
|
|
553
|
+
self,
|
|
554
|
+
days: int = 30
|
|
555
|
+
) -> dict[str, Any]:
|
|
556
|
+
"""
|
|
557
|
+
Get priority distribution trends over time.
|
|
558
|
+
|
|
559
|
+
Args:
|
|
560
|
+
days: Number of days to analyze
|
|
561
|
+
|
|
562
|
+
Returns:
|
|
563
|
+
Dictionary with trend data
|
|
564
|
+
"""
|
|
565
|
+
# Load historical files from last N days
|
|
566
|
+
cutoff_date = datetime.now() - timedelta(days=days)
|
|
567
|
+
history_files = []
|
|
568
|
+
|
|
569
|
+
for file_path in self.history_dir.glob("evaluation-*.json"):
|
|
570
|
+
try:
|
|
571
|
+
data = json.loads(file_path.read_text(encoding="utf-8"))
|
|
572
|
+
eval_date_str = data.get("evaluation_date", "")
|
|
573
|
+
if eval_date_str:
|
|
574
|
+
eval_date = datetime.fromisoformat(eval_date_str.replace("Z", "+00:00"))
|
|
575
|
+
if eval_date >= cutoff_date:
|
|
576
|
+
history_files.append(data)
|
|
577
|
+
except Exception:
|
|
578
|
+
continue
|
|
579
|
+
|
|
580
|
+
# Sort by date
|
|
581
|
+
history_files.sort(key=lambda x: x.get("evaluation_date", ""))
|
|
582
|
+
|
|
583
|
+
if not history_files:
|
|
584
|
+
return {
|
|
585
|
+
"critical_trend": [],
|
|
586
|
+
"high_trend": [],
|
|
587
|
+
"medium_trend": [],
|
|
588
|
+
"low_trend": [],
|
|
589
|
+
"average_score_trend": [],
|
|
590
|
+
"improvement_metrics": {
|
|
591
|
+
"critical_change_percent": 0.0,
|
|
592
|
+
"high_change_percent": 0.0,
|
|
593
|
+
"average_score_change_percent": 0.0,
|
|
594
|
+
"trend_direction": "stable"
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
# Extract trends
|
|
599
|
+
critical_trend = [h["priority_distribution"]["critical"] for h in history_files]
|
|
600
|
+
high_trend = [h["priority_distribution"]["high"] for h in history_files]
|
|
601
|
+
medium_trend = [h["priority_distribution"]["medium"] for h in history_files]
|
|
602
|
+
low_trend = [h["priority_distribution"]["low"] for h in history_files]
|
|
603
|
+
avg_score_trend = [h["average_score"] for h in history_files]
|
|
604
|
+
|
|
605
|
+
# Calculate improvement metrics
|
|
606
|
+
if len(history_files) >= 2:
|
|
607
|
+
first = history_files[0]
|
|
608
|
+
last = history_files[-1]
|
|
609
|
+
|
|
610
|
+
critical_change = (
|
|
611
|
+
(last["priority_distribution"]["critical"] - first["priority_distribution"]["critical"]) /
|
|
612
|
+
max(first["priority_distribution"]["critical"], 1) * 100
|
|
613
|
+
)
|
|
614
|
+
high_change = (
|
|
615
|
+
(last["priority_distribution"]["high"] - first["priority_distribution"]["high"]) /
|
|
616
|
+
max(first["priority_distribution"]["high"], 1) * 100
|
|
617
|
+
)
|
|
618
|
+
avg_score_change = (
|
|
619
|
+
(last["average_score"] - first["average_score"]) /
|
|
620
|
+
max(first["average_score"], 1) * 100
|
|
621
|
+
)
|
|
622
|
+
else:
|
|
623
|
+
critical_change = 0.0
|
|
624
|
+
high_change = 0.0
|
|
625
|
+
avg_score_change = 0.0
|
|
626
|
+
|
|
627
|
+
trend_direction = "improving" if critical_change < 0 and high_change < 0 else ("declining" if critical_change > 0 or high_change > 0 else "stable")
|
|
628
|
+
|
|
629
|
+
return {
|
|
630
|
+
"critical_trend": critical_trend,
|
|
631
|
+
"high_trend": high_trend,
|
|
632
|
+
"medium_trend": medium_trend,
|
|
633
|
+
"low_trend": low_trend,
|
|
634
|
+
"average_score_trend": avg_score_trend,
|
|
635
|
+
"improvement_metrics": {
|
|
636
|
+
"critical_change_percent": critical_change,
|
|
637
|
+
"high_change_percent": high_change,
|
|
638
|
+
"average_score_change_percent": avg_score_change,
|
|
639
|
+
"trend_direction": trend_direction
|
|
640
|
+
}
|
|
641
|
+
}
|