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,516 +1,516 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Phased Review Strategy - Review services in phases with progress persistence
|
|
3
|
-
|
|
4
|
-
Phase 4.3: Phased Review Strategy
|
|
5
|
-
|
|
6
|
-
Reviews services in phases (critical → high → medium → low) with progress
|
|
7
|
-
persistence and resume capability.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
from __future__ import annotations
|
|
11
|
-
|
|
12
|
-
import json
|
|
13
|
-
from datetime import datetime
|
|
14
|
-
from pathlib import Path
|
|
15
|
-
from typing import Any
|
|
16
|
-
|
|
17
|
-
from pydantic import BaseModel, Field
|
|
18
|
-
|
|
19
|
-
from ...core.config import ProjectConfig
|
|
20
|
-
from .batch_review import BatchReviewResult, BatchReviewWorkflow
|
|
21
|
-
from .service_discovery import Priority, Service, ServiceDiscovery
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class PhaseResult(BaseModel):
|
|
25
|
-
"""Result of a single phase review."""
|
|
26
|
-
|
|
27
|
-
phase_name: str
|
|
28
|
-
priority: Priority
|
|
29
|
-
services_count: int
|
|
30
|
-
completed_at: str | None = None # ISO format timestamp
|
|
31
|
-
batch_result: BatchReviewResult | None = None
|
|
32
|
-
status: str = "pending" # pending, in_progress, completed, failed
|
|
33
|
-
error: str | None = None
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
class PhasedReviewProgress(BaseModel):
|
|
37
|
-
"""Progress state for phased review with persistence."""
|
|
38
|
-
|
|
39
|
-
review_id: str
|
|
40
|
-
started_at: str # ISO format timestamp
|
|
41
|
-
completed_phases: list[str] = Field(default_factory=list)
|
|
42
|
-
current_phase: str | None = None
|
|
43
|
-
phases: dict[str, PhaseResult] = Field(default_factory=dict)
|
|
44
|
-
total_services: int = 0
|
|
45
|
-
services_reviewed: int = 0
|
|
46
|
-
status: str = "pending" # pending, in_progress, completed, failed, cancelled
|
|
47
|
-
error: str | None = None
|
|
48
|
-
completed_at: str | None = None # ISO format timestamp
|
|
49
|
-
|
|
50
|
-
def to_dict(self) -> dict[str, Any]:
|
|
51
|
-
"""Convert to dictionary for JSON serialization."""
|
|
52
|
-
return {
|
|
53
|
-
"review_id": self.review_id,
|
|
54
|
-
"started_at": self.started_at,
|
|
55
|
-
"completed_phases": self.completed_phases,
|
|
56
|
-
"current_phase": self.current_phase,
|
|
57
|
-
"phases": {
|
|
58
|
-
name: {
|
|
59
|
-
"phase_name": phase.phase_name,
|
|
60
|
-
"priority": phase.priority.value, # Convert enum to string for JSON
|
|
61
|
-
"services_count": phase.services_count,
|
|
62
|
-
"completed_at": phase.completed_at,
|
|
63
|
-
"status": phase.status,
|
|
64
|
-
"error": phase.error,
|
|
65
|
-
"batch_result": (
|
|
66
|
-
phase.batch_result.model_dump()
|
|
67
|
-
if phase.batch_result
|
|
68
|
-
else None
|
|
69
|
-
),
|
|
70
|
-
}
|
|
71
|
-
for name, phase in self.phases.items()
|
|
72
|
-
},
|
|
73
|
-
"total_services": self.total_services,
|
|
74
|
-
"services_reviewed": self.services_reviewed,
|
|
75
|
-
"status": self.status,
|
|
76
|
-
"error": self.error,
|
|
77
|
-
"completed_at": self.completed_at,
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
@classmethod
|
|
81
|
-
def from_dict(cls, data: dict[str, Any]) -> PhasedReviewProgress:
|
|
82
|
-
"""Create from dictionary."""
|
|
83
|
-
phases_dict = {}
|
|
84
|
-
for name, phase_data in data.get("phases", {}).items():
|
|
85
|
-
batch_result_data = phase_data.get("batch_result")
|
|
86
|
-
batch_result = (
|
|
87
|
-
BatchReviewResult.model_validate(batch_result_data)
|
|
88
|
-
if batch_result_data
|
|
89
|
-
else None
|
|
90
|
-
)
|
|
91
|
-
# Convert string priority to Priority enum
|
|
92
|
-
priority_str = phase_data["priority"]
|
|
93
|
-
priority = Priority(priority_str) if isinstance(priority_str, str) else priority_str
|
|
94
|
-
|
|
95
|
-
phases_dict[name] = PhaseResult(
|
|
96
|
-
phase_name=phase_data["phase_name"],
|
|
97
|
-
priority=priority,
|
|
98
|
-
services_count=phase_data["services_count"],
|
|
99
|
-
completed_at=phase_data.get("completed_at"),
|
|
100
|
-
status=phase_data.get("status", "pending"),
|
|
101
|
-
error=phase_data.get("error"),
|
|
102
|
-
batch_result=batch_result,
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
return cls(
|
|
106
|
-
review_id=data["review_id"],
|
|
107
|
-
started_at=data["started_at"],
|
|
108
|
-
completed_phases=data.get("completed_phases", []),
|
|
109
|
-
current_phase=data.get("current_phase"),
|
|
110
|
-
phases=phases_dict,
|
|
111
|
-
total_services=data.get("total_services", 0),
|
|
112
|
-
services_reviewed=data.get("services_reviewed", 0),
|
|
113
|
-
status=data.get("status", "pending"),
|
|
114
|
-
error=data.get("error"),
|
|
115
|
-
completed_at=data.get("completed_at"),
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
class PhasedReviewResult(BaseModel):
|
|
120
|
-
"""Final result of phased review."""
|
|
121
|
-
|
|
122
|
-
review_id: str
|
|
123
|
-
total_phases: int
|
|
124
|
-
completed_phases: int
|
|
125
|
-
total_services: int
|
|
126
|
-
services_reviewed: int
|
|
127
|
-
passed: int
|
|
128
|
-
failed: int
|
|
129
|
-
average_score: float
|
|
130
|
-
phases: dict[str, PhaseResult]
|
|
131
|
-
status: str # completed, failed, cancelled
|
|
132
|
-
completed_at: str | None = None
|
|
133
|
-
error: str | None = None
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
class PhasedReviewStrategy:
|
|
137
|
-
"""
|
|
138
|
-
Phased review strategy for reviewing services in priority-based phases.
|
|
139
|
-
|
|
140
|
-
Phase 4.3: Phased Review Strategy
|
|
141
|
-
|
|
142
|
-
Reviews services in phases: critical → high → medium → low
|
|
143
|
-
with progress persistence and resume capability.
|
|
144
|
-
"""
|
|
145
|
-
|
|
146
|
-
def __init__(
|
|
147
|
-
self,
|
|
148
|
-
config: ProjectConfig | None = None,
|
|
149
|
-
project_root: Path | None = None,
|
|
150
|
-
progress_file: Path | None = None,
|
|
151
|
-
max_parallel: int = 4,
|
|
152
|
-
):
|
|
153
|
-
"""
|
|
154
|
-
Initialize phased review strategy.
|
|
155
|
-
|
|
156
|
-
Args:
|
|
157
|
-
config: Optional project configuration
|
|
158
|
-
project_root: Optional project root directory
|
|
159
|
-
progress_file: Optional path to progress file (default: .tapps-agents/review-progress.json)
|
|
160
|
-
max_parallel: Maximum parallel reviews per phase
|
|
161
|
-
"""
|
|
162
|
-
self.config = config
|
|
163
|
-
self.project_root = project_root or Path.cwd()
|
|
164
|
-
self.progress_file = (
|
|
165
|
-
progress_file
|
|
166
|
-
or self.project_root / ".tapps-agents" / "review-progress.json"
|
|
167
|
-
)
|
|
168
|
-
self.max_parallel = max_parallel
|
|
169
|
-
self.batch_workflow = BatchReviewWorkflow(
|
|
170
|
-
config=config, project_root=project_root, max_parallel=max_parallel
|
|
171
|
-
)
|
|
172
|
-
self.service_discovery = ServiceDiscovery(project_root=project_root)
|
|
173
|
-
|
|
174
|
-
async def execute_phased_review(
|
|
175
|
-
self,
|
|
176
|
-
review_id: str | None = None,
|
|
177
|
-
phases: list[Priority] | list[str] | None = None,
|
|
178
|
-
resume: bool = True,
|
|
179
|
-
parallel: bool = True,
|
|
180
|
-
include_scoring: bool = True,
|
|
181
|
-
include_llm_feedback: bool = True,
|
|
182
|
-
) -> PhasedReviewResult:
|
|
183
|
-
"""
|
|
184
|
-
Execute phased review strategy.
|
|
185
|
-
|
|
186
|
-
Args:
|
|
187
|
-
review_id: Optional review ID (auto-generated if not provided)
|
|
188
|
-
phases: Optional list of phases to execute (default: critical, high, medium, low)
|
|
189
|
-
resume: Whether to resume from saved progress (default: True)
|
|
190
|
-
parallel: Whether to execute reviews in parallel within each phase
|
|
191
|
-
include_scoring: Whether to include code quality scoring
|
|
192
|
-
include_llm_feedback: Whether to include LLM feedback
|
|
193
|
-
|
|
194
|
-
Returns:
|
|
195
|
-
PhasedReviewResult with aggregated results
|
|
196
|
-
"""
|
|
197
|
-
if phases is None:
|
|
198
|
-
phases = [Priority.CRITICAL, Priority.HIGH, Priority.MEDIUM, Priority.LOW]
|
|
199
|
-
else:
|
|
200
|
-
# Convert string phases to Priority enum if needed
|
|
201
|
-
phases = [
|
|
202
|
-
Priority(p) if isinstance(p, str) else p
|
|
203
|
-
for p in phases
|
|
204
|
-
]
|
|
205
|
-
|
|
206
|
-
# Generate review ID if not provided
|
|
207
|
-
if not review_id:
|
|
208
|
-
review_id = f"phased-review-{datetime.now().strftime('%Y%m%d-%H%M%S')}"
|
|
209
|
-
|
|
210
|
-
# Try to load existing progress if resume is enabled
|
|
211
|
-
progress: PhasedReviewProgress | None = None
|
|
212
|
-
if resume:
|
|
213
|
-
progress = self.load_progress(review_id)
|
|
214
|
-
|
|
215
|
-
# If no existing progress, create new progress
|
|
216
|
-
if not progress:
|
|
217
|
-
progress = self._initialize_progress(review_id, phases)
|
|
218
|
-
|
|
219
|
-
# Execute phases sequentially
|
|
220
|
-
for phase_priority in phases:
|
|
221
|
-
phase_name = phase_priority.value # Use string value as key
|
|
222
|
-
phase_result = progress.phases.get(phase_name)
|
|
223
|
-
|
|
224
|
-
# Skip if already completed
|
|
225
|
-
if phase_result and phase_result.status == "completed":
|
|
226
|
-
continue
|
|
227
|
-
|
|
228
|
-
# Skip if not in progress list (might be filtered out)
|
|
229
|
-
if phase_name not in progress.phases:
|
|
230
|
-
continue
|
|
231
|
-
|
|
232
|
-
# Update current phase
|
|
233
|
-
progress.current_phase = phase_name
|
|
234
|
-
progress.status = "in_progress"
|
|
235
|
-
if phase_result:
|
|
236
|
-
phase_result.status = "in_progress"
|
|
237
|
-
self.save_progress(progress)
|
|
238
|
-
|
|
239
|
-
try:
|
|
240
|
-
await self._execute_single_phase(
|
|
241
|
-
phase_priority,
|
|
242
|
-
phase_name,
|
|
243
|
-
phase_result,
|
|
244
|
-
progress,
|
|
245
|
-
parallel,
|
|
246
|
-
include_scoring,
|
|
247
|
-
include_llm_feedback,
|
|
248
|
-
)
|
|
249
|
-
except Exception as e:
|
|
250
|
-
# Mark phase as failed
|
|
251
|
-
if phase_result:
|
|
252
|
-
phase_result.status = "failed"
|
|
253
|
-
phase_result.error = str(e)
|
|
254
|
-
progress.status = "failed"
|
|
255
|
-
progress.error = f"Phase {phase_name} failed: {str(e)}"
|
|
256
|
-
self.save_progress(progress)
|
|
257
|
-
raise
|
|
258
|
-
|
|
259
|
-
# All phases completed
|
|
260
|
-
progress.status = "completed"
|
|
261
|
-
progress.completed_at = datetime.now().isoformat()
|
|
262
|
-
progress.current_phase = None
|
|
263
|
-
self.save_progress(progress)
|
|
264
|
-
|
|
265
|
-
# Aggregate final results
|
|
266
|
-
return self._aggregate_phase_results(review_id, phases, progress)
|
|
267
|
-
|
|
268
|
-
def _initialize_progress(
|
|
269
|
-
self, review_id: str, phases: list[Priority]
|
|
270
|
-
) -> PhasedReviewProgress:
|
|
271
|
-
"""
|
|
272
|
-
Initialize progress for a new phased review.
|
|
273
|
-
|
|
274
|
-
Args:
|
|
275
|
-
review_id: Review ID
|
|
276
|
-
phases: List of phases to execute
|
|
277
|
-
|
|
278
|
-
Returns:
|
|
279
|
-
Initialized PhasedReviewProgress
|
|
280
|
-
"""
|
|
281
|
-
# Discover and prioritize services
|
|
282
|
-
services = self.service_discovery.discover_services_with_priority(
|
|
283
|
-
prioritize=True, group_by_language=False
|
|
284
|
-
)
|
|
285
|
-
|
|
286
|
-
# Group services by priority (phase)
|
|
287
|
-
services_by_phase: dict[Priority, list[Service]] = {}
|
|
288
|
-
for service in services:
|
|
289
|
-
phase = service.priority
|
|
290
|
-
if phase not in services_by_phase:
|
|
291
|
-
services_by_phase[phase] = []
|
|
292
|
-
services_by_phase[phase].append(service)
|
|
293
|
-
|
|
294
|
-
# Initialize progress
|
|
295
|
-
progress = PhasedReviewProgress(
|
|
296
|
-
review_id=review_id,
|
|
297
|
-
started_at=datetime.now().isoformat(),
|
|
298
|
-
total_services=len(services),
|
|
299
|
-
status="in_progress",
|
|
300
|
-
)
|
|
301
|
-
|
|
302
|
-
# Create phase results
|
|
303
|
-
for phase_priority in phases:
|
|
304
|
-
phase_name = phase_priority.value # Use string value as key for phases dict
|
|
305
|
-
services_in_phase = services_by_phase.get(phase_priority, [])
|
|
306
|
-
progress.phases[phase_name] = PhaseResult(
|
|
307
|
-
phase_name=phase_name,
|
|
308
|
-
priority=phase_priority,
|
|
309
|
-
services_count=len(services_in_phase),
|
|
310
|
-
status="pending",
|
|
311
|
-
)
|
|
312
|
-
|
|
313
|
-
# Save initial progress
|
|
314
|
-
self.save_progress(progress)
|
|
315
|
-
return progress
|
|
316
|
-
|
|
317
|
-
async def _execute_single_phase(
|
|
318
|
-
self,
|
|
319
|
-
phase_priority: Priority,
|
|
320
|
-
phase_name: str,
|
|
321
|
-
phase_result: PhaseResult | None,
|
|
322
|
-
progress: PhasedReviewProgress,
|
|
323
|
-
parallel: bool,
|
|
324
|
-
include_scoring: bool,
|
|
325
|
-
include_llm_feedback: bool,
|
|
326
|
-
) -> None:
|
|
327
|
-
"""
|
|
328
|
-
Execute a single phase of the review.
|
|
329
|
-
|
|
330
|
-
Args:
|
|
331
|
-
phase_priority: Priority enum for this phase
|
|
332
|
-
phase_name: String name for this phase
|
|
333
|
-
phase_result: PhaseResult object (may be None)
|
|
334
|
-
progress: Overall progress object
|
|
335
|
-
parallel: Whether to execute reviews in parallel
|
|
336
|
-
include_scoring: Whether to include scoring
|
|
337
|
-
include_llm_feedback: Whether to include LLM feedback
|
|
338
|
-
"""
|
|
339
|
-
# Get services for this phase
|
|
340
|
-
services_in_phase = [
|
|
341
|
-
s
|
|
342
|
-
for s in self.service_discovery.discover_services_with_priority(
|
|
343
|
-
prioritize=True, group_by_language=False
|
|
344
|
-
)
|
|
345
|
-
if s.priority == phase_priority
|
|
346
|
-
]
|
|
347
|
-
|
|
348
|
-
if not services_in_phase:
|
|
349
|
-
# No services in this phase, mark as completed
|
|
350
|
-
if phase_result:
|
|
351
|
-
phase_result.status = "completed"
|
|
352
|
-
phase_result.completed_at = datetime.now().isoformat()
|
|
353
|
-
return
|
|
354
|
-
|
|
355
|
-
# Execute batch review for this phase
|
|
356
|
-
batch_result = await self.batch_workflow.review_services(
|
|
357
|
-
services=services_in_phase,
|
|
358
|
-
parallel=parallel,
|
|
359
|
-
include_scoring=include_scoring,
|
|
360
|
-
include_llm_feedback=include_llm_feedback,
|
|
361
|
-
)
|
|
362
|
-
|
|
363
|
-
# Update phase result
|
|
364
|
-
if phase_result:
|
|
365
|
-
phase_result.batch_result = batch_result
|
|
366
|
-
phase_result.status = "completed"
|
|
367
|
-
phase_result.completed_at = datetime.now().isoformat()
|
|
368
|
-
|
|
369
|
-
# Update progress
|
|
370
|
-
progress.completed_phases.append(phase_name)
|
|
371
|
-
progress.services_reviewed += batch_result.services_reviewed
|
|
372
|
-
self.save_progress(progress)
|
|
373
|
-
|
|
374
|
-
def _aggregate_phase_results(
|
|
375
|
-
self,
|
|
376
|
-
review_id: str,
|
|
377
|
-
phases: list[Priority],
|
|
378
|
-
progress: PhasedReviewProgress,
|
|
379
|
-
) -> PhasedReviewResult:
|
|
380
|
-
"""
|
|
381
|
-
Aggregate results from all phases into final result.
|
|
382
|
-
|
|
383
|
-
Args:
|
|
384
|
-
review_id: Review ID
|
|
385
|
-
phases: List of phases that were executed
|
|
386
|
-
progress: Progress object with all phase results
|
|
387
|
-
|
|
388
|
-
Returns:
|
|
389
|
-
PhasedReviewResult with aggregated statistics
|
|
390
|
-
"""
|
|
391
|
-
total_passed = sum(
|
|
392
|
-
(
|
|
393
|
-
phase.batch_result.passed
|
|
394
|
-
if phase.batch_result
|
|
395
|
-
else 0
|
|
396
|
-
)
|
|
397
|
-
for phase in progress.phases.values()
|
|
398
|
-
)
|
|
399
|
-
total_failed = sum(
|
|
400
|
-
(
|
|
401
|
-
phase.batch_result.failed
|
|
402
|
-
if phase.batch_result
|
|
403
|
-
else 0
|
|
404
|
-
)
|
|
405
|
-
for phase in progress.phases.values()
|
|
406
|
-
)
|
|
407
|
-
|
|
408
|
-
# Calculate average score
|
|
409
|
-
scores = [
|
|
410
|
-
(
|
|
411
|
-
phase.batch_result.average_score
|
|
412
|
-
if phase.batch_result and phase.batch_result.average_score > 0
|
|
413
|
-
else None
|
|
414
|
-
)
|
|
415
|
-
for phase in progress.phases.values()
|
|
416
|
-
]
|
|
417
|
-
valid_scores = [s for s in scores if s is not None]
|
|
418
|
-
average_score = (
|
|
419
|
-
sum(valid_scores) / len(valid_scores) if valid_scores else 0.0
|
|
420
|
-
)
|
|
421
|
-
|
|
422
|
-
return PhasedReviewResult(
|
|
423
|
-
review_id=review_id,
|
|
424
|
-
total_phases=len(phases),
|
|
425
|
-
completed_phases=len(progress.completed_phases),
|
|
426
|
-
total_services=progress.total_services,
|
|
427
|
-
services_reviewed=progress.services_reviewed,
|
|
428
|
-
passed=total_passed,
|
|
429
|
-
failed=total_failed,
|
|
430
|
-
average_score=average_score,
|
|
431
|
-
phases={
|
|
432
|
-
name: phase for name, phase in progress.phases.items()
|
|
433
|
-
},
|
|
434
|
-
status="completed",
|
|
435
|
-
completed_at=progress.completed_at,
|
|
436
|
-
)
|
|
437
|
-
|
|
438
|
-
def save_progress(self, progress: PhasedReviewProgress) -> None:
|
|
439
|
-
"""
|
|
440
|
-
Save progress to disk.
|
|
441
|
-
|
|
442
|
-
Phase 4.3: Progress Persistence
|
|
443
|
-
"""
|
|
444
|
-
try:
|
|
445
|
-
# Ensure directory exists
|
|
446
|
-
self.progress_file.parent.mkdir(parents=True, exist_ok=True)
|
|
447
|
-
|
|
448
|
-
# Use atomic write for safety (similar to workflow file_utils pattern)
|
|
449
|
-
# Write to temp file first, then rename
|
|
450
|
-
temp_file = self.progress_file.with_suffix(".json.tmp")
|
|
451
|
-
with open(temp_file, "w", encoding="utf-8") as f:
|
|
452
|
-
json.dump(progress.to_dict(), f, indent=2)
|
|
453
|
-
|
|
454
|
-
# Atomic rename (Windows-compatible)
|
|
455
|
-
if self.progress_file.exists():
|
|
456
|
-
self.progress_file.unlink()
|
|
457
|
-
temp_file.replace(self.progress_file)
|
|
458
|
-
|
|
459
|
-
except Exception as e:
|
|
460
|
-
# Best-effort save, log but don't fail
|
|
461
|
-
import logging
|
|
462
|
-
|
|
463
|
-
logger = logging.getLogger(__name__)
|
|
464
|
-
logger.warning(f"Failed to save phased review progress: {e}")
|
|
465
|
-
|
|
466
|
-
def load_progress(self, review_id: str | None = None) -> PhasedReviewProgress | None:
|
|
467
|
-
"""
|
|
468
|
-
Load progress from disk.
|
|
469
|
-
|
|
470
|
-
Phase 4.3: Resume Capability
|
|
471
|
-
|
|
472
|
-
Args:
|
|
473
|
-
review_id: Optional review ID to load (loads latest if not provided)
|
|
474
|
-
|
|
475
|
-
Returns:
|
|
476
|
-
PhasedReviewProgress if found, None otherwise
|
|
477
|
-
"""
|
|
478
|
-
if not self.progress_file.exists():
|
|
479
|
-
return None
|
|
480
|
-
|
|
481
|
-
try:
|
|
482
|
-
with open(self.progress_file, "r", encoding="utf-8") as f:
|
|
483
|
-
data = json.load(f)
|
|
484
|
-
|
|
485
|
-
progress = PhasedReviewProgress.from_dict(data)
|
|
486
|
-
|
|
487
|
-
# Filter by review_id if provided
|
|
488
|
-
if review_id and progress.review_id != review_id:
|
|
489
|
-
return None
|
|
490
|
-
|
|
491
|
-
return progress
|
|
492
|
-
|
|
493
|
-
except Exception as e:
|
|
494
|
-
import logging
|
|
495
|
-
|
|
496
|
-
logger = logging.getLogger(__name__)
|
|
497
|
-
logger.warning(f"Failed to load phased review progress: {e}")
|
|
498
|
-
return None
|
|
499
|
-
|
|
500
|
-
def clear_progress(self, review_id: str | None = None) -> None:
|
|
501
|
-
"""
|
|
502
|
-
Clear saved progress.
|
|
503
|
-
|
|
504
|
-
Args:
|
|
505
|
-
review_id: Optional review ID to clear (clears all if not provided)
|
|
506
|
-
"""
|
|
507
|
-
if review_id:
|
|
508
|
-
progress = self.load_progress()
|
|
509
|
-
if progress and progress.review_id == review_id:
|
|
510
|
-
if self.progress_file.exists():
|
|
511
|
-
self.progress_file.unlink()
|
|
512
|
-
else:
|
|
513
|
-
# Clear all progress
|
|
514
|
-
if self.progress_file.exists():
|
|
515
|
-
self.progress_file.unlink()
|
|
516
|
-
|
|
1
|
+
"""
|
|
2
|
+
Phased Review Strategy - Review services in phases with progress persistence
|
|
3
|
+
|
|
4
|
+
Phase 4.3: Phased Review Strategy
|
|
5
|
+
|
|
6
|
+
Reviews services in phases (critical → high → medium → low) with progress
|
|
7
|
+
persistence and resume capability.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import json
|
|
13
|
+
from datetime import datetime
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
from pydantic import BaseModel, Field
|
|
18
|
+
|
|
19
|
+
from ...core.config import ProjectConfig
|
|
20
|
+
from .batch_review import BatchReviewResult, BatchReviewWorkflow
|
|
21
|
+
from .service_discovery import Priority, Service, ServiceDiscovery
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class PhaseResult(BaseModel):
|
|
25
|
+
"""Result of a single phase review."""
|
|
26
|
+
|
|
27
|
+
phase_name: str
|
|
28
|
+
priority: Priority
|
|
29
|
+
services_count: int
|
|
30
|
+
completed_at: str | None = None # ISO format timestamp
|
|
31
|
+
batch_result: BatchReviewResult | None = None
|
|
32
|
+
status: str = "pending" # pending, in_progress, completed, failed
|
|
33
|
+
error: str | None = None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class PhasedReviewProgress(BaseModel):
|
|
37
|
+
"""Progress state for phased review with persistence."""
|
|
38
|
+
|
|
39
|
+
review_id: str
|
|
40
|
+
started_at: str # ISO format timestamp
|
|
41
|
+
completed_phases: list[str] = Field(default_factory=list)
|
|
42
|
+
current_phase: str | None = None
|
|
43
|
+
phases: dict[str, PhaseResult] = Field(default_factory=dict)
|
|
44
|
+
total_services: int = 0
|
|
45
|
+
services_reviewed: int = 0
|
|
46
|
+
status: str = "pending" # pending, in_progress, completed, failed, cancelled
|
|
47
|
+
error: str | None = None
|
|
48
|
+
completed_at: str | None = None # ISO format timestamp
|
|
49
|
+
|
|
50
|
+
def to_dict(self) -> dict[str, Any]:
|
|
51
|
+
"""Convert to dictionary for JSON serialization."""
|
|
52
|
+
return {
|
|
53
|
+
"review_id": self.review_id,
|
|
54
|
+
"started_at": self.started_at,
|
|
55
|
+
"completed_phases": self.completed_phases,
|
|
56
|
+
"current_phase": self.current_phase,
|
|
57
|
+
"phases": {
|
|
58
|
+
name: {
|
|
59
|
+
"phase_name": phase.phase_name,
|
|
60
|
+
"priority": phase.priority.value, # Convert enum to string for JSON
|
|
61
|
+
"services_count": phase.services_count,
|
|
62
|
+
"completed_at": phase.completed_at,
|
|
63
|
+
"status": phase.status,
|
|
64
|
+
"error": phase.error,
|
|
65
|
+
"batch_result": (
|
|
66
|
+
phase.batch_result.model_dump()
|
|
67
|
+
if phase.batch_result
|
|
68
|
+
else None
|
|
69
|
+
),
|
|
70
|
+
}
|
|
71
|
+
for name, phase in self.phases.items()
|
|
72
|
+
},
|
|
73
|
+
"total_services": self.total_services,
|
|
74
|
+
"services_reviewed": self.services_reviewed,
|
|
75
|
+
"status": self.status,
|
|
76
|
+
"error": self.error,
|
|
77
|
+
"completed_at": self.completed_at,
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@classmethod
|
|
81
|
+
def from_dict(cls, data: dict[str, Any]) -> PhasedReviewProgress:
|
|
82
|
+
"""Create from dictionary."""
|
|
83
|
+
phases_dict = {}
|
|
84
|
+
for name, phase_data in data.get("phases", {}).items():
|
|
85
|
+
batch_result_data = phase_data.get("batch_result")
|
|
86
|
+
batch_result = (
|
|
87
|
+
BatchReviewResult.model_validate(batch_result_data)
|
|
88
|
+
if batch_result_data
|
|
89
|
+
else None
|
|
90
|
+
)
|
|
91
|
+
# Convert string priority to Priority enum
|
|
92
|
+
priority_str = phase_data["priority"]
|
|
93
|
+
priority = Priority(priority_str) if isinstance(priority_str, str) else priority_str
|
|
94
|
+
|
|
95
|
+
phases_dict[name] = PhaseResult(
|
|
96
|
+
phase_name=phase_data["phase_name"],
|
|
97
|
+
priority=priority,
|
|
98
|
+
services_count=phase_data["services_count"],
|
|
99
|
+
completed_at=phase_data.get("completed_at"),
|
|
100
|
+
status=phase_data.get("status", "pending"),
|
|
101
|
+
error=phase_data.get("error"),
|
|
102
|
+
batch_result=batch_result,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
return cls(
|
|
106
|
+
review_id=data["review_id"],
|
|
107
|
+
started_at=data["started_at"],
|
|
108
|
+
completed_phases=data.get("completed_phases", []),
|
|
109
|
+
current_phase=data.get("current_phase"),
|
|
110
|
+
phases=phases_dict,
|
|
111
|
+
total_services=data.get("total_services", 0),
|
|
112
|
+
services_reviewed=data.get("services_reviewed", 0),
|
|
113
|
+
status=data.get("status", "pending"),
|
|
114
|
+
error=data.get("error"),
|
|
115
|
+
completed_at=data.get("completed_at"),
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class PhasedReviewResult(BaseModel):
|
|
120
|
+
"""Final result of phased review."""
|
|
121
|
+
|
|
122
|
+
review_id: str
|
|
123
|
+
total_phases: int
|
|
124
|
+
completed_phases: int
|
|
125
|
+
total_services: int
|
|
126
|
+
services_reviewed: int
|
|
127
|
+
passed: int
|
|
128
|
+
failed: int
|
|
129
|
+
average_score: float
|
|
130
|
+
phases: dict[str, PhaseResult]
|
|
131
|
+
status: str # completed, failed, cancelled
|
|
132
|
+
completed_at: str | None = None
|
|
133
|
+
error: str | None = None
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class PhasedReviewStrategy:
|
|
137
|
+
"""
|
|
138
|
+
Phased review strategy for reviewing services in priority-based phases.
|
|
139
|
+
|
|
140
|
+
Phase 4.3: Phased Review Strategy
|
|
141
|
+
|
|
142
|
+
Reviews services in phases: critical → high → medium → low
|
|
143
|
+
with progress persistence and resume capability.
|
|
144
|
+
"""
|
|
145
|
+
|
|
146
|
+
def __init__(
|
|
147
|
+
self,
|
|
148
|
+
config: ProjectConfig | None = None,
|
|
149
|
+
project_root: Path | None = None,
|
|
150
|
+
progress_file: Path | None = None,
|
|
151
|
+
max_parallel: int = 4,
|
|
152
|
+
):
|
|
153
|
+
"""
|
|
154
|
+
Initialize phased review strategy.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
config: Optional project configuration
|
|
158
|
+
project_root: Optional project root directory
|
|
159
|
+
progress_file: Optional path to progress file (default: .tapps-agents/review-progress.json)
|
|
160
|
+
max_parallel: Maximum parallel reviews per phase
|
|
161
|
+
"""
|
|
162
|
+
self.config = config
|
|
163
|
+
self.project_root = project_root or Path.cwd()
|
|
164
|
+
self.progress_file = (
|
|
165
|
+
progress_file
|
|
166
|
+
or self.project_root / ".tapps-agents" / "review-progress.json"
|
|
167
|
+
)
|
|
168
|
+
self.max_parallel = max_parallel
|
|
169
|
+
self.batch_workflow = BatchReviewWorkflow(
|
|
170
|
+
config=config, project_root=project_root, max_parallel=max_parallel
|
|
171
|
+
)
|
|
172
|
+
self.service_discovery = ServiceDiscovery(project_root=project_root)
|
|
173
|
+
|
|
174
|
+
async def execute_phased_review(
|
|
175
|
+
self,
|
|
176
|
+
review_id: str | None = None,
|
|
177
|
+
phases: list[Priority] | list[str] | None = None,
|
|
178
|
+
resume: bool = True,
|
|
179
|
+
parallel: bool = True,
|
|
180
|
+
include_scoring: bool = True,
|
|
181
|
+
include_llm_feedback: bool = True,
|
|
182
|
+
) -> PhasedReviewResult:
|
|
183
|
+
"""
|
|
184
|
+
Execute phased review strategy.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
review_id: Optional review ID (auto-generated if not provided)
|
|
188
|
+
phases: Optional list of phases to execute (default: critical, high, medium, low)
|
|
189
|
+
resume: Whether to resume from saved progress (default: True)
|
|
190
|
+
parallel: Whether to execute reviews in parallel within each phase
|
|
191
|
+
include_scoring: Whether to include code quality scoring
|
|
192
|
+
include_llm_feedback: Whether to include LLM feedback
|
|
193
|
+
|
|
194
|
+
Returns:
|
|
195
|
+
PhasedReviewResult with aggregated results
|
|
196
|
+
"""
|
|
197
|
+
if phases is None:
|
|
198
|
+
phases = [Priority.CRITICAL, Priority.HIGH, Priority.MEDIUM, Priority.LOW]
|
|
199
|
+
else:
|
|
200
|
+
# Convert string phases to Priority enum if needed
|
|
201
|
+
phases = [
|
|
202
|
+
Priority(p) if isinstance(p, str) else p
|
|
203
|
+
for p in phases
|
|
204
|
+
]
|
|
205
|
+
|
|
206
|
+
# Generate review ID if not provided
|
|
207
|
+
if not review_id:
|
|
208
|
+
review_id = f"phased-review-{datetime.now().strftime('%Y%m%d-%H%M%S')}"
|
|
209
|
+
|
|
210
|
+
# Try to load existing progress if resume is enabled
|
|
211
|
+
progress: PhasedReviewProgress | None = None
|
|
212
|
+
if resume:
|
|
213
|
+
progress = self.load_progress(review_id)
|
|
214
|
+
|
|
215
|
+
# If no existing progress, create new progress
|
|
216
|
+
if not progress:
|
|
217
|
+
progress = self._initialize_progress(review_id, phases)
|
|
218
|
+
|
|
219
|
+
# Execute phases sequentially
|
|
220
|
+
for phase_priority in phases:
|
|
221
|
+
phase_name = phase_priority.value # Use string value as key
|
|
222
|
+
phase_result = progress.phases.get(phase_name)
|
|
223
|
+
|
|
224
|
+
# Skip if already completed
|
|
225
|
+
if phase_result and phase_result.status == "completed":
|
|
226
|
+
continue
|
|
227
|
+
|
|
228
|
+
# Skip if not in progress list (might be filtered out)
|
|
229
|
+
if phase_name not in progress.phases:
|
|
230
|
+
continue
|
|
231
|
+
|
|
232
|
+
# Update current phase
|
|
233
|
+
progress.current_phase = phase_name
|
|
234
|
+
progress.status = "in_progress"
|
|
235
|
+
if phase_result:
|
|
236
|
+
phase_result.status = "in_progress"
|
|
237
|
+
self.save_progress(progress)
|
|
238
|
+
|
|
239
|
+
try:
|
|
240
|
+
await self._execute_single_phase(
|
|
241
|
+
phase_priority,
|
|
242
|
+
phase_name,
|
|
243
|
+
phase_result,
|
|
244
|
+
progress,
|
|
245
|
+
parallel,
|
|
246
|
+
include_scoring,
|
|
247
|
+
include_llm_feedback,
|
|
248
|
+
)
|
|
249
|
+
except Exception as e:
|
|
250
|
+
# Mark phase as failed
|
|
251
|
+
if phase_result:
|
|
252
|
+
phase_result.status = "failed"
|
|
253
|
+
phase_result.error = str(e)
|
|
254
|
+
progress.status = "failed"
|
|
255
|
+
progress.error = f"Phase {phase_name} failed: {str(e)}"
|
|
256
|
+
self.save_progress(progress)
|
|
257
|
+
raise
|
|
258
|
+
|
|
259
|
+
# All phases completed
|
|
260
|
+
progress.status = "completed"
|
|
261
|
+
progress.completed_at = datetime.now().isoformat()
|
|
262
|
+
progress.current_phase = None
|
|
263
|
+
self.save_progress(progress)
|
|
264
|
+
|
|
265
|
+
# Aggregate final results
|
|
266
|
+
return self._aggregate_phase_results(review_id, phases, progress)
|
|
267
|
+
|
|
268
|
+
def _initialize_progress(
|
|
269
|
+
self, review_id: str, phases: list[Priority]
|
|
270
|
+
) -> PhasedReviewProgress:
|
|
271
|
+
"""
|
|
272
|
+
Initialize progress for a new phased review.
|
|
273
|
+
|
|
274
|
+
Args:
|
|
275
|
+
review_id: Review ID
|
|
276
|
+
phases: List of phases to execute
|
|
277
|
+
|
|
278
|
+
Returns:
|
|
279
|
+
Initialized PhasedReviewProgress
|
|
280
|
+
"""
|
|
281
|
+
# Discover and prioritize services
|
|
282
|
+
services = self.service_discovery.discover_services_with_priority(
|
|
283
|
+
prioritize=True, group_by_language=False
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
# Group services by priority (phase)
|
|
287
|
+
services_by_phase: dict[Priority, list[Service]] = {}
|
|
288
|
+
for service in services:
|
|
289
|
+
phase = service.priority
|
|
290
|
+
if phase not in services_by_phase:
|
|
291
|
+
services_by_phase[phase] = []
|
|
292
|
+
services_by_phase[phase].append(service)
|
|
293
|
+
|
|
294
|
+
# Initialize progress
|
|
295
|
+
progress = PhasedReviewProgress(
|
|
296
|
+
review_id=review_id,
|
|
297
|
+
started_at=datetime.now().isoformat(),
|
|
298
|
+
total_services=len(services),
|
|
299
|
+
status="in_progress",
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
# Create phase results
|
|
303
|
+
for phase_priority in phases:
|
|
304
|
+
phase_name = phase_priority.value # Use string value as key for phases dict
|
|
305
|
+
services_in_phase = services_by_phase.get(phase_priority, [])
|
|
306
|
+
progress.phases[phase_name] = PhaseResult(
|
|
307
|
+
phase_name=phase_name,
|
|
308
|
+
priority=phase_priority,
|
|
309
|
+
services_count=len(services_in_phase),
|
|
310
|
+
status="pending",
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
# Save initial progress
|
|
314
|
+
self.save_progress(progress)
|
|
315
|
+
return progress
|
|
316
|
+
|
|
317
|
+
async def _execute_single_phase(
|
|
318
|
+
self,
|
|
319
|
+
phase_priority: Priority,
|
|
320
|
+
phase_name: str,
|
|
321
|
+
phase_result: PhaseResult | None,
|
|
322
|
+
progress: PhasedReviewProgress,
|
|
323
|
+
parallel: bool,
|
|
324
|
+
include_scoring: bool,
|
|
325
|
+
include_llm_feedback: bool,
|
|
326
|
+
) -> None:
|
|
327
|
+
"""
|
|
328
|
+
Execute a single phase of the review.
|
|
329
|
+
|
|
330
|
+
Args:
|
|
331
|
+
phase_priority: Priority enum for this phase
|
|
332
|
+
phase_name: String name for this phase
|
|
333
|
+
phase_result: PhaseResult object (may be None)
|
|
334
|
+
progress: Overall progress object
|
|
335
|
+
parallel: Whether to execute reviews in parallel
|
|
336
|
+
include_scoring: Whether to include scoring
|
|
337
|
+
include_llm_feedback: Whether to include LLM feedback
|
|
338
|
+
"""
|
|
339
|
+
# Get services for this phase
|
|
340
|
+
services_in_phase = [
|
|
341
|
+
s
|
|
342
|
+
for s in self.service_discovery.discover_services_with_priority(
|
|
343
|
+
prioritize=True, group_by_language=False
|
|
344
|
+
)
|
|
345
|
+
if s.priority == phase_priority
|
|
346
|
+
]
|
|
347
|
+
|
|
348
|
+
if not services_in_phase:
|
|
349
|
+
# No services in this phase, mark as completed
|
|
350
|
+
if phase_result:
|
|
351
|
+
phase_result.status = "completed"
|
|
352
|
+
phase_result.completed_at = datetime.now().isoformat()
|
|
353
|
+
return
|
|
354
|
+
|
|
355
|
+
# Execute batch review for this phase
|
|
356
|
+
batch_result = await self.batch_workflow.review_services(
|
|
357
|
+
services=services_in_phase,
|
|
358
|
+
parallel=parallel,
|
|
359
|
+
include_scoring=include_scoring,
|
|
360
|
+
include_llm_feedback=include_llm_feedback,
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
# Update phase result
|
|
364
|
+
if phase_result:
|
|
365
|
+
phase_result.batch_result = batch_result
|
|
366
|
+
phase_result.status = "completed"
|
|
367
|
+
phase_result.completed_at = datetime.now().isoformat()
|
|
368
|
+
|
|
369
|
+
# Update progress
|
|
370
|
+
progress.completed_phases.append(phase_name)
|
|
371
|
+
progress.services_reviewed += batch_result.services_reviewed
|
|
372
|
+
self.save_progress(progress)
|
|
373
|
+
|
|
374
|
+
def _aggregate_phase_results(
|
|
375
|
+
self,
|
|
376
|
+
review_id: str,
|
|
377
|
+
phases: list[Priority],
|
|
378
|
+
progress: PhasedReviewProgress,
|
|
379
|
+
) -> PhasedReviewResult:
|
|
380
|
+
"""
|
|
381
|
+
Aggregate results from all phases into final result.
|
|
382
|
+
|
|
383
|
+
Args:
|
|
384
|
+
review_id: Review ID
|
|
385
|
+
phases: List of phases that were executed
|
|
386
|
+
progress: Progress object with all phase results
|
|
387
|
+
|
|
388
|
+
Returns:
|
|
389
|
+
PhasedReviewResult with aggregated statistics
|
|
390
|
+
"""
|
|
391
|
+
total_passed = sum(
|
|
392
|
+
(
|
|
393
|
+
phase.batch_result.passed
|
|
394
|
+
if phase.batch_result
|
|
395
|
+
else 0
|
|
396
|
+
)
|
|
397
|
+
for phase in progress.phases.values()
|
|
398
|
+
)
|
|
399
|
+
total_failed = sum(
|
|
400
|
+
(
|
|
401
|
+
phase.batch_result.failed
|
|
402
|
+
if phase.batch_result
|
|
403
|
+
else 0
|
|
404
|
+
)
|
|
405
|
+
for phase in progress.phases.values()
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
# Calculate average score
|
|
409
|
+
scores = [
|
|
410
|
+
(
|
|
411
|
+
phase.batch_result.average_score
|
|
412
|
+
if phase.batch_result and phase.batch_result.average_score > 0
|
|
413
|
+
else None
|
|
414
|
+
)
|
|
415
|
+
for phase in progress.phases.values()
|
|
416
|
+
]
|
|
417
|
+
valid_scores = [s for s in scores if s is not None]
|
|
418
|
+
average_score = (
|
|
419
|
+
sum(valid_scores) / len(valid_scores) if valid_scores else 0.0
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
return PhasedReviewResult(
|
|
423
|
+
review_id=review_id,
|
|
424
|
+
total_phases=len(phases),
|
|
425
|
+
completed_phases=len(progress.completed_phases),
|
|
426
|
+
total_services=progress.total_services,
|
|
427
|
+
services_reviewed=progress.services_reviewed,
|
|
428
|
+
passed=total_passed,
|
|
429
|
+
failed=total_failed,
|
|
430
|
+
average_score=average_score,
|
|
431
|
+
phases={
|
|
432
|
+
name: phase for name, phase in progress.phases.items()
|
|
433
|
+
},
|
|
434
|
+
status="completed",
|
|
435
|
+
completed_at=progress.completed_at,
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
def save_progress(self, progress: PhasedReviewProgress) -> None:
|
|
439
|
+
"""
|
|
440
|
+
Save progress to disk.
|
|
441
|
+
|
|
442
|
+
Phase 4.3: Progress Persistence
|
|
443
|
+
"""
|
|
444
|
+
try:
|
|
445
|
+
# Ensure directory exists
|
|
446
|
+
self.progress_file.parent.mkdir(parents=True, exist_ok=True)
|
|
447
|
+
|
|
448
|
+
# Use atomic write for safety (similar to workflow file_utils pattern)
|
|
449
|
+
# Write to temp file first, then rename
|
|
450
|
+
temp_file = self.progress_file.with_suffix(".json.tmp")
|
|
451
|
+
with open(temp_file, "w", encoding="utf-8") as f:
|
|
452
|
+
json.dump(progress.to_dict(), f, indent=2)
|
|
453
|
+
|
|
454
|
+
# Atomic rename (Windows-compatible)
|
|
455
|
+
if self.progress_file.exists():
|
|
456
|
+
self.progress_file.unlink()
|
|
457
|
+
temp_file.replace(self.progress_file)
|
|
458
|
+
|
|
459
|
+
except Exception as e:
|
|
460
|
+
# Best-effort save, log but don't fail
|
|
461
|
+
import logging
|
|
462
|
+
|
|
463
|
+
logger = logging.getLogger(__name__)
|
|
464
|
+
logger.warning(f"Failed to save phased review progress: {e}")
|
|
465
|
+
|
|
466
|
+
def load_progress(self, review_id: str | None = None) -> PhasedReviewProgress | None:
|
|
467
|
+
"""
|
|
468
|
+
Load progress from disk.
|
|
469
|
+
|
|
470
|
+
Phase 4.3: Resume Capability
|
|
471
|
+
|
|
472
|
+
Args:
|
|
473
|
+
review_id: Optional review ID to load (loads latest if not provided)
|
|
474
|
+
|
|
475
|
+
Returns:
|
|
476
|
+
PhasedReviewProgress if found, None otherwise
|
|
477
|
+
"""
|
|
478
|
+
if not self.progress_file.exists():
|
|
479
|
+
return None
|
|
480
|
+
|
|
481
|
+
try:
|
|
482
|
+
with open(self.progress_file, "r", encoding="utf-8") as f:
|
|
483
|
+
data = json.load(f)
|
|
484
|
+
|
|
485
|
+
progress = PhasedReviewProgress.from_dict(data)
|
|
486
|
+
|
|
487
|
+
# Filter by review_id if provided
|
|
488
|
+
if review_id and progress.review_id != review_id:
|
|
489
|
+
return None
|
|
490
|
+
|
|
491
|
+
return progress
|
|
492
|
+
|
|
493
|
+
except Exception as e:
|
|
494
|
+
import logging
|
|
495
|
+
|
|
496
|
+
logger = logging.getLogger(__name__)
|
|
497
|
+
logger.warning(f"Failed to load phased review progress: {e}")
|
|
498
|
+
return None
|
|
499
|
+
|
|
500
|
+
def clear_progress(self, review_id: str | None = None) -> None:
|
|
501
|
+
"""
|
|
502
|
+
Clear saved progress.
|
|
503
|
+
|
|
504
|
+
Args:
|
|
505
|
+
review_id: Optional review ID to clear (clears all if not provided)
|
|
506
|
+
"""
|
|
507
|
+
if review_id:
|
|
508
|
+
progress = self.load_progress()
|
|
509
|
+
if progress and progress.review_id == review_id:
|
|
510
|
+
if self.progress_file.exists():
|
|
511
|
+
self.progress_file.unlink()
|
|
512
|
+
else:
|
|
513
|
+
# Clear all progress
|
|
514
|
+
if self.progress_file.exists():
|
|
515
|
+
self.progress_file.unlink()
|
|
516
|
+
|