tapps-agents 3.5.40__py3-none-any.whl → 3.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/scoring.py +1566 -1566
- tapps_agents/agents/reviewer/service_discovery.py +534 -534
- tapps_agents/agents/reviewer/tools/__init__.py +41 -41
- 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/health.py +665 -665
- 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 -219
- tapps_agents/cli/commands/tester.py +191 -191
- tapps_agents/cli/commands/top_level.py +3586 -3586
- 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/artifact_context_builder.py +293 -0
- 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/config.py +33 -0
- 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.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/orchestrator.py +271 -271
- 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/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/base.py +185 -185
- 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/build_orchestrator.py +2700 -2667
- 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/fix_orchestrator.py +723 -723
- 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_executor.py +2337 -2196
- 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/message_formatter.py +188 -188
- 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 -111
- 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.5.40.dist-info → tapps_agents-3.6.0.dist-info}/METADATA +672 -672
- tapps_agents-3.6.0.dist-info/RECORD +758 -0
- {tapps_agents-3.5.40.dist-info → tapps_agents-3.6.0.dist-info}/licenses/LICENSE +22 -22
- tapps_agents/health/checks/outcomes.backup_20260204_064058.py +0 -324
- tapps_agents/health/checks/outcomes.backup_20260204_064256.py +0 -324
- tapps_agents/health/checks/outcomes.backup_20260204_064600.py +0 -324
- tapps_agents-3.5.40.dist-info/RECORD +0 -760
- {tapps_agents-3.5.40.dist-info → tapps_agents-3.6.0.dist-info}/WHEEL +0 -0
- {tapps_agents-3.5.40.dist-info → tapps_agents-3.6.0.dist-info}/entry_points.txt +0 -0
- {tapps_agents-3.5.40.dist-info → tapps_agents-3.6.0.dist-info}/top_level.txt +0 -0
|
@@ -1,534 +1,534 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Service Discovery - Auto-detect services in project structure
|
|
3
|
-
|
|
4
|
-
Phase 6.4.2: Multi-Service Analysis
|
|
5
|
-
Phase 4.1: Enhanced with prioritization, dependency analysis, and language grouping
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from __future__ import annotations
|
|
9
|
-
|
|
10
|
-
import json
|
|
11
|
-
import logging
|
|
12
|
-
import re
|
|
13
|
-
from dataclasses import dataclass, field
|
|
14
|
-
from enum import Enum
|
|
15
|
-
from pathlib import Path
|
|
16
|
-
from typing import Any
|
|
17
|
-
|
|
18
|
-
from ...core.language_detector import Language, LanguageDetector
|
|
19
|
-
|
|
20
|
-
logger = logging.getLogger(__name__)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class Priority(str, Enum):
|
|
24
|
-
"""Service priority levels for phased review."""
|
|
25
|
-
|
|
26
|
-
CRITICAL = "critical"
|
|
27
|
-
HIGH = "high"
|
|
28
|
-
MEDIUM = "medium"
|
|
29
|
-
LOW = "low"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
@dataclass
|
|
33
|
-
class Service:
|
|
34
|
-
"""
|
|
35
|
-
Service model with enhanced metadata.
|
|
36
|
-
|
|
37
|
-
Phase 4.1: Service Discovery Enhancement
|
|
38
|
-
"""
|
|
39
|
-
|
|
40
|
-
name: str
|
|
41
|
-
path: Path
|
|
42
|
-
relative_path: str
|
|
43
|
-
language: Language = Language.UNKNOWN
|
|
44
|
-
priority: Priority = Priority.MEDIUM
|
|
45
|
-
dependencies: list[str] = field(default_factory=list)
|
|
46
|
-
file_count: int = 0
|
|
47
|
-
pattern: str = ""
|
|
48
|
-
|
|
49
|
-
def to_dict(self) -> dict[str, Any]:
|
|
50
|
-
"""Convert Service to dictionary."""
|
|
51
|
-
return {
|
|
52
|
-
"name": self.name,
|
|
53
|
-
"path": str(self.path),
|
|
54
|
-
"relative_path": self.relative_path,
|
|
55
|
-
"language": self.language.value,
|
|
56
|
-
"priority": self.priority.value, # Convert enum to string
|
|
57
|
-
"dependencies": self.dependencies,
|
|
58
|
-
"file_count": self.file_count,
|
|
59
|
-
"pattern": self.pattern,
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
class ServiceDiscovery:
|
|
64
|
-
"""
|
|
65
|
-
Discover services in a project structure.
|
|
66
|
-
|
|
67
|
-
Phase 6.4.2: Multi-Service Analysis
|
|
68
|
-
"""
|
|
69
|
-
|
|
70
|
-
def __init__(
|
|
71
|
-
self,
|
|
72
|
-
project_root: Path | None = None,
|
|
73
|
-
service_patterns: list[str] | None = None,
|
|
74
|
-
exclude_patterns: list[str] | None = None,
|
|
75
|
-
):
|
|
76
|
-
"""
|
|
77
|
-
Initialize service discovery.
|
|
78
|
-
|
|
79
|
-
Args:
|
|
80
|
-
project_root: Root directory of the project (default: current directory)
|
|
81
|
-
service_patterns: List of patterns to match service directories
|
|
82
|
-
(default: ['services/*/', 'src/*/', 'apps/*/'])
|
|
83
|
-
exclude_patterns: List of patterns to exclude (default: ['node_modules', '.git', '__pycache__'])
|
|
84
|
-
"""
|
|
85
|
-
if project_root is None:
|
|
86
|
-
project_root = Path.cwd()
|
|
87
|
-
self.project_root = Path(project_root).resolve()
|
|
88
|
-
|
|
89
|
-
if service_patterns is None:
|
|
90
|
-
service_patterns = [
|
|
91
|
-
"services/*/",
|
|
92
|
-
"src/*/",
|
|
93
|
-
"apps/*/",
|
|
94
|
-
"microservices/*/",
|
|
95
|
-
"packages/*/",
|
|
96
|
-
# Treat the main Python package as a first-class service root for project analysis.
|
|
97
|
-
"tapps_agents/",
|
|
98
|
-
]
|
|
99
|
-
self.service_patterns = service_patterns
|
|
100
|
-
|
|
101
|
-
if exclude_patterns is None:
|
|
102
|
-
exclude_patterns = [
|
|
103
|
-
"node_modules",
|
|
104
|
-
".git",
|
|
105
|
-
"__pycache__",
|
|
106
|
-
".pytest_cache",
|
|
107
|
-
".venv",
|
|
108
|
-
"venv",
|
|
109
|
-
"env",
|
|
110
|
-
".env",
|
|
111
|
-
"dist",
|
|
112
|
-
"build",
|
|
113
|
-
]
|
|
114
|
-
self.exclude_patterns = exclude_patterns
|
|
115
|
-
self.language_detector = LanguageDetector()
|
|
116
|
-
|
|
117
|
-
def discover_services_enhanced(self) -> list[Service]:
|
|
118
|
-
"""
|
|
119
|
-
Discover all services with enhanced metadata.
|
|
120
|
-
|
|
121
|
-
Phase 4.1: Enhanced service discovery with language detection, priority, and dependencies.
|
|
122
|
-
|
|
123
|
-
Returns:
|
|
124
|
-
List of Service objects with language, priority, and dependencies
|
|
125
|
-
"""
|
|
126
|
-
# Get basic service discovery
|
|
127
|
-
basic_services = self.discover_services()
|
|
128
|
-
|
|
129
|
-
# Convert to Service objects with enhanced metadata
|
|
130
|
-
services = []
|
|
131
|
-
for service_dict in basic_services:
|
|
132
|
-
service_path = Path(service_dict["path"])
|
|
133
|
-
|
|
134
|
-
# Detect language
|
|
135
|
-
language = self._detect_service_language(service_path)
|
|
136
|
-
|
|
137
|
-
# Count files
|
|
138
|
-
file_count = self._count_service_files(service_path)
|
|
139
|
-
|
|
140
|
-
# Detect dependencies
|
|
141
|
-
dependencies = self._detect_dependencies(service_path)
|
|
142
|
-
|
|
143
|
-
# Determine priority
|
|
144
|
-
priority = self._determine_priority(
|
|
145
|
-
service_dict["name"], dependencies, file_count
|
|
146
|
-
)
|
|
147
|
-
|
|
148
|
-
service = Service(
|
|
149
|
-
name=service_dict["name"],
|
|
150
|
-
path=service_path,
|
|
151
|
-
relative_path=service_dict["relative_path"],
|
|
152
|
-
language=language,
|
|
153
|
-
priority=priority,
|
|
154
|
-
dependencies=dependencies,
|
|
155
|
-
file_count=file_count,
|
|
156
|
-
pattern=service_dict.get("pattern", ""),
|
|
157
|
-
)
|
|
158
|
-
services.append(service)
|
|
159
|
-
|
|
160
|
-
return services
|
|
161
|
-
|
|
162
|
-
def _detect_service_language(self, service_path: Path) -> Language:
|
|
163
|
-
"""Detect the primary language of a service."""
|
|
164
|
-
# Try to detect from common config files
|
|
165
|
-
if (service_path / "package.json").exists():
|
|
166
|
-
try:
|
|
167
|
-
with (service_path / "package.json").open(encoding="utf-8") as f:
|
|
168
|
-
package_data = json.load(f)
|
|
169
|
-
if package_data.get("dependencies", {}).get("react"):
|
|
170
|
-
return Language.REACT
|
|
171
|
-
return Language.TYPESCRIPT
|
|
172
|
-
except (json.JSONDecodeError, Exception) as e:
|
|
173
|
-
logger.debug(f"Failed to parse package.json for language detection in {service_path.name}: {e}")
|
|
174
|
-
|
|
175
|
-
if (service_path / "requirements.txt").exists() or (
|
|
176
|
-
service_path / "pyproject.toml"
|
|
177
|
-
).exists():
|
|
178
|
-
return Language.PYTHON
|
|
179
|
-
|
|
180
|
-
# Detect from file extensions in service directory
|
|
181
|
-
code_files = []
|
|
182
|
-
for ext in [".py", ".ts", ".tsx", ".js", ".jsx"]:
|
|
183
|
-
code_files.extend(list(service_path.rglob(f"*{ext}"))[:10])
|
|
184
|
-
|
|
185
|
-
if not code_files:
|
|
186
|
-
return Language.UNKNOWN
|
|
187
|
-
|
|
188
|
-
# Use LanguageDetector on a sample file
|
|
189
|
-
sample_file = code_files[0]
|
|
190
|
-
result = self.language_detector.detect_language(sample_file)
|
|
191
|
-
return result.language
|
|
192
|
-
|
|
193
|
-
def _count_service_files(self, service_path: Path) -> int:
|
|
194
|
-
"""Count code files in service directory."""
|
|
195
|
-
count = 0
|
|
196
|
-
code_extensions = [".py", ".ts", ".tsx", ".js", ".jsx"]
|
|
197
|
-
for ext in code_extensions:
|
|
198
|
-
count += len(list(service_path.rglob(f"*{ext}")))
|
|
199
|
-
return count
|
|
200
|
-
|
|
201
|
-
def _detect_dependencies(self, service_path: Path) -> list[str]:
|
|
202
|
-
"""
|
|
203
|
-
Detect service dependencies from config files.
|
|
204
|
-
|
|
205
|
-
Phase 4.1: Dependency Analysis
|
|
206
|
-
"""
|
|
207
|
-
dependencies = []
|
|
208
|
-
|
|
209
|
-
# Check package.json (Node.js/TypeScript/React)
|
|
210
|
-
package_json = service_path / "package.json"
|
|
211
|
-
if package_json.exists():
|
|
212
|
-
try:
|
|
213
|
-
with package_json.open(encoding="utf-8") as f:
|
|
214
|
-
package_data = json.load(f)
|
|
215
|
-
# Get both dependencies and devDependencies
|
|
216
|
-
deps = package_data.get("dependencies", {})
|
|
217
|
-
deps.update(package_data.get("devDependencies", {}))
|
|
218
|
-
dependencies.extend(list(deps.keys()))
|
|
219
|
-
except (json.JSONDecodeError, Exception):
|
|
220
|
-
pass
|
|
221
|
-
|
|
222
|
-
# Check requirements.txt (Python)
|
|
223
|
-
requirements_txt = service_path / "requirements.txt"
|
|
224
|
-
if requirements_txt.exists():
|
|
225
|
-
try:
|
|
226
|
-
with requirements_txt.open(encoding="utf-8") as f:
|
|
227
|
-
for line in f:
|
|
228
|
-
line = line.strip()
|
|
229
|
-
if line and not line.startswith("#"):
|
|
230
|
-
# Extract package name (before ==, >=, etc.)
|
|
231
|
-
package_name = line.split("==")[0].split(">=")[0].split("<=")[0].strip()
|
|
232
|
-
if package_name:
|
|
233
|
-
dependencies.append(package_name)
|
|
234
|
-
except Exception as e:
|
|
235
|
-
logger.debug(f"Failed to parse requirements.txt for service {service_path.name}: {e}")
|
|
236
|
-
|
|
237
|
-
# Check pyproject.toml (Python)
|
|
238
|
-
pyproject_toml = service_path / "pyproject.toml"
|
|
239
|
-
if pyproject_toml.exists():
|
|
240
|
-
try:
|
|
241
|
-
import tomllib # Python 3.11+
|
|
242
|
-
|
|
243
|
-
with pyproject_toml.open("rb") as f:
|
|
244
|
-
pyproject_data = tomllib.load(f)
|
|
245
|
-
project_deps = pyproject_data.get("project", {}).get(
|
|
246
|
-
"dependencies", []
|
|
247
|
-
)
|
|
248
|
-
for dep in project_deps:
|
|
249
|
-
# Extract package name (before version specifiers)
|
|
250
|
-
package_name = dep.split("==")[0].split(">=")[0].split("<=")[0].strip()
|
|
251
|
-
if package_name:
|
|
252
|
-
dependencies.append(package_name)
|
|
253
|
-
except ImportError:
|
|
254
|
-
# Fallback for Python < 3.11 (could use tomli)
|
|
255
|
-
pass
|
|
256
|
-
except Exception as e:
|
|
257
|
-
logger.debug(f"Failed to parse requirements.txt for service {service_path.name}: {e}")
|
|
258
|
-
|
|
259
|
-
return sorted(set(dependencies))
|
|
260
|
-
|
|
261
|
-
def _determine_priority(
|
|
262
|
-
self, service_name: str, dependencies: list[str], file_count: int
|
|
263
|
-
) -> Priority:
|
|
264
|
-
"""
|
|
265
|
-
Determine service priority based on name patterns, dependencies, and file count.
|
|
266
|
-
|
|
267
|
-
Phase 4.1: Prioritization Logic
|
|
268
|
-
"""
|
|
269
|
-
service_name_lower = service_name.lower()
|
|
270
|
-
|
|
271
|
-
# Critical priority patterns
|
|
272
|
-
critical_patterns = [
|
|
273
|
-
"auth",
|
|
274
|
-
"security",
|
|
275
|
-
"api",
|
|
276
|
-
"gateway",
|
|
277
|
-
"core",
|
|
278
|
-
"base",
|
|
279
|
-
"common",
|
|
280
|
-
]
|
|
281
|
-
if any(pattern in service_name_lower for pattern in critical_patterns):
|
|
282
|
-
return Priority.CRITICAL
|
|
283
|
-
|
|
284
|
-
# High priority: many dependencies or high file count
|
|
285
|
-
if len(dependencies) > 20 or file_count > 100:
|
|
286
|
-
return Priority.HIGH
|
|
287
|
-
|
|
288
|
-
# High priority patterns
|
|
289
|
-
high_patterns = ["service", "server", "backend", "frontend", "client"]
|
|
290
|
-
if any(pattern in service_name_lower for pattern in high_patterns):
|
|
291
|
-
return Priority.HIGH
|
|
292
|
-
|
|
293
|
-
# Low priority: minimal dependencies and low file count
|
|
294
|
-
if len(dependencies) < 3 and file_count < 10:
|
|
295
|
-
return Priority.LOW
|
|
296
|
-
|
|
297
|
-
# Default to medium
|
|
298
|
-
return Priority.MEDIUM
|
|
299
|
-
|
|
300
|
-
def prioritize_services(self, services: list[Service]) -> list[Service]:
|
|
301
|
-
"""
|
|
302
|
-
Prioritize services: critical → high → medium → low.
|
|
303
|
-
|
|
304
|
-
Phase 4.1: Service Prioritization
|
|
305
|
-
"""
|
|
306
|
-
priority_order = {
|
|
307
|
-
Priority.CRITICAL: 0,
|
|
308
|
-
Priority.HIGH: 1,
|
|
309
|
-
Priority.MEDIUM: 2,
|
|
310
|
-
Priority.LOW: 3,
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
def priority_key(service: Service) -> tuple[int, str]:
|
|
314
|
-
return (priority_order.get(service.priority, 99), service.name)
|
|
315
|
-
|
|
316
|
-
return sorted(services, key=priority_key)
|
|
317
|
-
|
|
318
|
-
def group_by_language(self, services: list[Service]) -> dict[Language, list[Service]]:
|
|
319
|
-
"""
|
|
320
|
-
Group services by detected primary language.
|
|
321
|
-
|
|
322
|
-
Phase 4.1: Language Grouping
|
|
323
|
-
"""
|
|
324
|
-
grouped: dict[Language, list[Service]] = {}
|
|
325
|
-
for service in services:
|
|
326
|
-
if service.language not in grouped:
|
|
327
|
-
grouped[service.language] = []
|
|
328
|
-
grouped[service.language].append(service)
|
|
329
|
-
return grouped
|
|
330
|
-
|
|
331
|
-
def discover_services_with_priority(
|
|
332
|
-
self, prioritize: bool = True, group_by_language: bool = False
|
|
333
|
-
) -> list[Service] | dict[Language, list[Service]]:
|
|
334
|
-
"""
|
|
335
|
-
Discover services with prioritization and optional language grouping.
|
|
336
|
-
|
|
337
|
-
Phase 4.1: Enhanced Service Discovery
|
|
338
|
-
|
|
339
|
-
Args:
|
|
340
|
-
prioritize: Whether to prioritize services (critical → high → medium → low)
|
|
341
|
-
group_by_language: Whether to group services by language
|
|
342
|
-
|
|
343
|
-
Returns:
|
|
344
|
-
List of prioritized Service objects, or dict grouped by language
|
|
345
|
-
"""
|
|
346
|
-
services = self.discover_services_enhanced()
|
|
347
|
-
|
|
348
|
-
if prioritize:
|
|
349
|
-
services = self.prioritize_services(services)
|
|
350
|
-
|
|
351
|
-
if group_by_language:
|
|
352
|
-
return self.group_by_language(services)
|
|
353
|
-
|
|
354
|
-
return services
|
|
355
|
-
|
|
356
|
-
def discover_services(self) -> list[dict[str, Any]]:
|
|
357
|
-
"""
|
|
358
|
-
Discover all services in the project.
|
|
359
|
-
|
|
360
|
-
Returns:
|
|
361
|
-
List of service dictionaries with:
|
|
362
|
-
- name: Service name (directory name)
|
|
363
|
-
- path: Full path to service directory
|
|
364
|
-
- relative_path: Relative path from project root
|
|
365
|
-
"""
|
|
366
|
-
services: list[dict[str, Any]] = []
|
|
367
|
-
|
|
368
|
-
# Try each service pattern
|
|
369
|
-
for pattern in self.service_patterns:
|
|
370
|
-
# If the pattern points directly at a service root (no wildcard), include that directory itself.
|
|
371
|
-
# This lets us analyze mono-package repos like `tapps_agents/` as a single “service”.
|
|
372
|
-
if "*" not in pattern and "?" not in pattern:
|
|
373
|
-
base_dir = pattern.rstrip("/").rstrip("\\")
|
|
374
|
-
candidate = self.project_root / base_dir
|
|
375
|
-
if (
|
|
376
|
-
candidate.exists()
|
|
377
|
-
and candidate.is_dir()
|
|
378
|
-
and not self._should_exclude(candidate)
|
|
379
|
-
):
|
|
380
|
-
if self._is_service_directory(candidate):
|
|
381
|
-
services.append(
|
|
382
|
-
{
|
|
383
|
-
"name": candidate.name,
|
|
384
|
-
"path": str(candidate),
|
|
385
|
-
"relative_path": str(
|
|
386
|
-
candidate.relative_to(self.project_root)
|
|
387
|
-
),
|
|
388
|
-
"pattern": pattern,
|
|
389
|
-
}
|
|
390
|
-
)
|
|
391
|
-
continue
|
|
392
|
-
|
|
393
|
-
# Convert glob pattern to directory structure
|
|
394
|
-
# e.g., "services/*/" -> "services/"
|
|
395
|
-
base_dir = pattern.split("*")[0].rstrip("/")
|
|
396
|
-
base_path = self.project_root / base_dir
|
|
397
|
-
|
|
398
|
-
if not base_path.exists() or not base_path.is_dir():
|
|
399
|
-
continue
|
|
400
|
-
|
|
401
|
-
# Find all subdirectories
|
|
402
|
-
for item in base_path.iterdir():
|
|
403
|
-
if not item.is_dir():
|
|
404
|
-
continue
|
|
405
|
-
|
|
406
|
-
# Check exclusion patterns
|
|
407
|
-
if self._should_exclude(item):
|
|
408
|
-
continue
|
|
409
|
-
|
|
410
|
-
# Check if it looks like a service (has code files)
|
|
411
|
-
if self._is_service_directory(item):
|
|
412
|
-
service_name = item.name
|
|
413
|
-
services.append(
|
|
414
|
-
{
|
|
415
|
-
"name": service_name,
|
|
416
|
-
"path": str(item),
|
|
417
|
-
"relative_path": str(item.relative_to(self.project_root)),
|
|
418
|
-
"pattern": pattern,
|
|
419
|
-
}
|
|
420
|
-
)
|
|
421
|
-
|
|
422
|
-
# Remove duplicates (services might match multiple patterns)
|
|
423
|
-
seen = set()
|
|
424
|
-
unique_services = []
|
|
425
|
-
for service in services:
|
|
426
|
-
key = service["path"]
|
|
427
|
-
if key not in seen:
|
|
428
|
-
seen.add(key)
|
|
429
|
-
unique_services.append(service)
|
|
430
|
-
|
|
431
|
-
return sorted(unique_services, key=lambda x: x["name"])
|
|
432
|
-
|
|
433
|
-
def _should_exclude(self, path: Path) -> bool:
|
|
434
|
-
"""Check if a path should be excluded."""
|
|
435
|
-
path_str = str(path)
|
|
436
|
-
path_name = path.name
|
|
437
|
-
|
|
438
|
-
# Check exclusion patterns
|
|
439
|
-
for exclude_pattern in self.exclude_patterns:
|
|
440
|
-
if exclude_pattern in path_str or path_name.startswith(exclude_pattern):
|
|
441
|
-
return True
|
|
442
|
-
|
|
443
|
-
# Exclude hidden directories
|
|
444
|
-
if path_name.startswith("."):
|
|
445
|
-
return True
|
|
446
|
-
|
|
447
|
-
return False
|
|
448
|
-
|
|
449
|
-
def _is_service_directory(self, path: Path) -> bool:
|
|
450
|
-
"""
|
|
451
|
-
Check if a directory looks like a service directory.
|
|
452
|
-
|
|
453
|
-
A service directory should have:
|
|
454
|
-
- Python files (*.py)
|
|
455
|
-
- Or TypeScript files (*.ts, *.tsx)
|
|
456
|
-
- Or JavaScript files (*.js, *.jsx)
|
|
457
|
-
- Or a requirements.txt / package.json
|
|
458
|
-
- Or a Dockerfile / docker-compose.yml
|
|
459
|
-
"""
|
|
460
|
-
service_indicators = [
|
|
461
|
-
# Code files
|
|
462
|
-
"*.py",
|
|
463
|
-
"*.ts",
|
|
464
|
-
"*.tsx",
|
|
465
|
-
"*.js",
|
|
466
|
-
"*.jsx",
|
|
467
|
-
# Configuration files
|
|
468
|
-
"requirements.txt",
|
|
469
|
-
"package.json",
|
|
470
|
-
"pyproject.toml",
|
|
471
|
-
"setup.py",
|
|
472
|
-
"Dockerfile",
|
|
473
|
-
"docker-compose.yml",
|
|
474
|
-
"*.yaml",
|
|
475
|
-
"*.yml",
|
|
476
|
-
]
|
|
477
|
-
|
|
478
|
-
# Check for service indicators
|
|
479
|
-
for indicator in service_indicators:
|
|
480
|
-
if indicator.startswith("*."):
|
|
481
|
-
# File extension pattern
|
|
482
|
-
extension = indicator[1:]
|
|
483
|
-
matches = list(path.rglob(f"*{extension}"))
|
|
484
|
-
if matches:
|
|
485
|
-
# Make sure it's not just in a subdirectory like node_modules
|
|
486
|
-
for match in matches[:5]: # Check first 5 matches
|
|
487
|
-
if not self._should_exclude(match.parent):
|
|
488
|
-
return True
|
|
489
|
-
else:
|
|
490
|
-
# Specific file pattern
|
|
491
|
-
matches = list(path.glob(indicator))
|
|
492
|
-
if matches:
|
|
493
|
-
return True
|
|
494
|
-
|
|
495
|
-
return False
|
|
496
|
-
|
|
497
|
-
def discover_service(self, service_name: str) -> dict[str, Any] | None:
|
|
498
|
-
"""
|
|
499
|
-
Discover a specific service by name.
|
|
500
|
-
|
|
501
|
-
Args:
|
|
502
|
-
service_name: Name of the service to find
|
|
503
|
-
|
|
504
|
-
Returns:
|
|
505
|
-
Service dictionary if found, None otherwise
|
|
506
|
-
"""
|
|
507
|
-
services = self.discover_services()
|
|
508
|
-
for service in services:
|
|
509
|
-
if service["name"] == service_name:
|
|
510
|
-
return service
|
|
511
|
-
return None
|
|
512
|
-
|
|
513
|
-
def discover_by_pattern(self, pattern: str) -> list[dict[str, Any]]:
|
|
514
|
-
"""
|
|
515
|
-
Discover services matching a specific pattern.
|
|
516
|
-
|
|
517
|
-
Args:
|
|
518
|
-
pattern: Pattern to match service names (supports wildcards)
|
|
519
|
-
|
|
520
|
-
Returns:
|
|
521
|
-
List of matching services
|
|
522
|
-
"""
|
|
523
|
-
services = self.discover_services()
|
|
524
|
-
|
|
525
|
-
# Convert pattern to regex
|
|
526
|
-
regex_pattern = pattern.replace("*", ".*").replace("?", ".")
|
|
527
|
-
regex = re.compile(f"^{regex_pattern}$", re.IGNORECASE)
|
|
528
|
-
|
|
529
|
-
matching_services = []
|
|
530
|
-
for service in services:
|
|
531
|
-
if regex.match(service["name"]):
|
|
532
|
-
matching_services.append(service)
|
|
533
|
-
|
|
534
|
-
return matching_services
|
|
1
|
+
"""
|
|
2
|
+
Service Discovery - Auto-detect services in project structure
|
|
3
|
+
|
|
4
|
+
Phase 6.4.2: Multi-Service Analysis
|
|
5
|
+
Phase 4.1: Enhanced with prioritization, dependency analysis, and language grouping
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
import logging
|
|
12
|
+
import re
|
|
13
|
+
from dataclasses import dataclass, field
|
|
14
|
+
from enum import Enum
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
18
|
+
from ...core.language_detector import Language, LanguageDetector
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Priority(str, Enum):
|
|
24
|
+
"""Service priority levels for phased review."""
|
|
25
|
+
|
|
26
|
+
CRITICAL = "critical"
|
|
27
|
+
HIGH = "high"
|
|
28
|
+
MEDIUM = "medium"
|
|
29
|
+
LOW = "low"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class Service:
|
|
34
|
+
"""
|
|
35
|
+
Service model with enhanced metadata.
|
|
36
|
+
|
|
37
|
+
Phase 4.1: Service Discovery Enhancement
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
name: str
|
|
41
|
+
path: Path
|
|
42
|
+
relative_path: str
|
|
43
|
+
language: Language = Language.UNKNOWN
|
|
44
|
+
priority: Priority = Priority.MEDIUM
|
|
45
|
+
dependencies: list[str] = field(default_factory=list)
|
|
46
|
+
file_count: int = 0
|
|
47
|
+
pattern: str = ""
|
|
48
|
+
|
|
49
|
+
def to_dict(self) -> dict[str, Any]:
|
|
50
|
+
"""Convert Service to dictionary."""
|
|
51
|
+
return {
|
|
52
|
+
"name": self.name,
|
|
53
|
+
"path": str(self.path),
|
|
54
|
+
"relative_path": self.relative_path,
|
|
55
|
+
"language": self.language.value,
|
|
56
|
+
"priority": self.priority.value, # Convert enum to string
|
|
57
|
+
"dependencies": self.dependencies,
|
|
58
|
+
"file_count": self.file_count,
|
|
59
|
+
"pattern": self.pattern,
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class ServiceDiscovery:
|
|
64
|
+
"""
|
|
65
|
+
Discover services in a project structure.
|
|
66
|
+
|
|
67
|
+
Phase 6.4.2: Multi-Service Analysis
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
def __init__(
|
|
71
|
+
self,
|
|
72
|
+
project_root: Path | None = None,
|
|
73
|
+
service_patterns: list[str] | None = None,
|
|
74
|
+
exclude_patterns: list[str] | None = None,
|
|
75
|
+
):
|
|
76
|
+
"""
|
|
77
|
+
Initialize service discovery.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
project_root: Root directory of the project (default: current directory)
|
|
81
|
+
service_patterns: List of patterns to match service directories
|
|
82
|
+
(default: ['services/*/', 'src/*/', 'apps/*/'])
|
|
83
|
+
exclude_patterns: List of patterns to exclude (default: ['node_modules', '.git', '__pycache__'])
|
|
84
|
+
"""
|
|
85
|
+
if project_root is None:
|
|
86
|
+
project_root = Path.cwd()
|
|
87
|
+
self.project_root = Path(project_root).resolve()
|
|
88
|
+
|
|
89
|
+
if service_patterns is None:
|
|
90
|
+
service_patterns = [
|
|
91
|
+
"services/*/",
|
|
92
|
+
"src/*/",
|
|
93
|
+
"apps/*/",
|
|
94
|
+
"microservices/*/",
|
|
95
|
+
"packages/*/",
|
|
96
|
+
# Treat the main Python package as a first-class service root for project analysis.
|
|
97
|
+
"tapps_agents/",
|
|
98
|
+
]
|
|
99
|
+
self.service_patterns = service_patterns
|
|
100
|
+
|
|
101
|
+
if exclude_patterns is None:
|
|
102
|
+
exclude_patterns = [
|
|
103
|
+
"node_modules",
|
|
104
|
+
".git",
|
|
105
|
+
"__pycache__",
|
|
106
|
+
".pytest_cache",
|
|
107
|
+
".venv",
|
|
108
|
+
"venv",
|
|
109
|
+
"env",
|
|
110
|
+
".env",
|
|
111
|
+
"dist",
|
|
112
|
+
"build",
|
|
113
|
+
]
|
|
114
|
+
self.exclude_patterns = exclude_patterns
|
|
115
|
+
self.language_detector = LanguageDetector()
|
|
116
|
+
|
|
117
|
+
def discover_services_enhanced(self) -> list[Service]:
|
|
118
|
+
"""
|
|
119
|
+
Discover all services with enhanced metadata.
|
|
120
|
+
|
|
121
|
+
Phase 4.1: Enhanced service discovery with language detection, priority, and dependencies.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
List of Service objects with language, priority, and dependencies
|
|
125
|
+
"""
|
|
126
|
+
# Get basic service discovery
|
|
127
|
+
basic_services = self.discover_services()
|
|
128
|
+
|
|
129
|
+
# Convert to Service objects with enhanced metadata
|
|
130
|
+
services = []
|
|
131
|
+
for service_dict in basic_services:
|
|
132
|
+
service_path = Path(service_dict["path"])
|
|
133
|
+
|
|
134
|
+
# Detect language
|
|
135
|
+
language = self._detect_service_language(service_path)
|
|
136
|
+
|
|
137
|
+
# Count files
|
|
138
|
+
file_count = self._count_service_files(service_path)
|
|
139
|
+
|
|
140
|
+
# Detect dependencies
|
|
141
|
+
dependencies = self._detect_dependencies(service_path)
|
|
142
|
+
|
|
143
|
+
# Determine priority
|
|
144
|
+
priority = self._determine_priority(
|
|
145
|
+
service_dict["name"], dependencies, file_count
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
service = Service(
|
|
149
|
+
name=service_dict["name"],
|
|
150
|
+
path=service_path,
|
|
151
|
+
relative_path=service_dict["relative_path"],
|
|
152
|
+
language=language,
|
|
153
|
+
priority=priority,
|
|
154
|
+
dependencies=dependencies,
|
|
155
|
+
file_count=file_count,
|
|
156
|
+
pattern=service_dict.get("pattern", ""),
|
|
157
|
+
)
|
|
158
|
+
services.append(service)
|
|
159
|
+
|
|
160
|
+
return services
|
|
161
|
+
|
|
162
|
+
def _detect_service_language(self, service_path: Path) -> Language:
|
|
163
|
+
"""Detect the primary language of a service."""
|
|
164
|
+
# Try to detect from common config files
|
|
165
|
+
if (service_path / "package.json").exists():
|
|
166
|
+
try:
|
|
167
|
+
with (service_path / "package.json").open(encoding="utf-8") as f:
|
|
168
|
+
package_data = json.load(f)
|
|
169
|
+
if package_data.get("dependencies", {}).get("react"):
|
|
170
|
+
return Language.REACT
|
|
171
|
+
return Language.TYPESCRIPT
|
|
172
|
+
except (json.JSONDecodeError, Exception) as e:
|
|
173
|
+
logger.debug(f"Failed to parse package.json for language detection in {service_path.name}: {e}")
|
|
174
|
+
|
|
175
|
+
if (service_path / "requirements.txt").exists() or (
|
|
176
|
+
service_path / "pyproject.toml"
|
|
177
|
+
).exists():
|
|
178
|
+
return Language.PYTHON
|
|
179
|
+
|
|
180
|
+
# Detect from file extensions in service directory
|
|
181
|
+
code_files = []
|
|
182
|
+
for ext in [".py", ".ts", ".tsx", ".js", ".jsx"]:
|
|
183
|
+
code_files.extend(list(service_path.rglob(f"*{ext}"))[:10])
|
|
184
|
+
|
|
185
|
+
if not code_files:
|
|
186
|
+
return Language.UNKNOWN
|
|
187
|
+
|
|
188
|
+
# Use LanguageDetector on a sample file
|
|
189
|
+
sample_file = code_files[0]
|
|
190
|
+
result = self.language_detector.detect_language(sample_file)
|
|
191
|
+
return result.language
|
|
192
|
+
|
|
193
|
+
def _count_service_files(self, service_path: Path) -> int:
|
|
194
|
+
"""Count code files in service directory."""
|
|
195
|
+
count = 0
|
|
196
|
+
code_extensions = [".py", ".ts", ".tsx", ".js", ".jsx"]
|
|
197
|
+
for ext in code_extensions:
|
|
198
|
+
count += len(list(service_path.rglob(f"*{ext}")))
|
|
199
|
+
return count
|
|
200
|
+
|
|
201
|
+
def _detect_dependencies(self, service_path: Path) -> list[str]:
|
|
202
|
+
"""
|
|
203
|
+
Detect service dependencies from config files.
|
|
204
|
+
|
|
205
|
+
Phase 4.1: Dependency Analysis
|
|
206
|
+
"""
|
|
207
|
+
dependencies = []
|
|
208
|
+
|
|
209
|
+
# Check package.json (Node.js/TypeScript/React)
|
|
210
|
+
package_json = service_path / "package.json"
|
|
211
|
+
if package_json.exists():
|
|
212
|
+
try:
|
|
213
|
+
with package_json.open(encoding="utf-8") as f:
|
|
214
|
+
package_data = json.load(f)
|
|
215
|
+
# Get both dependencies and devDependencies
|
|
216
|
+
deps = package_data.get("dependencies", {})
|
|
217
|
+
deps.update(package_data.get("devDependencies", {}))
|
|
218
|
+
dependencies.extend(list(deps.keys()))
|
|
219
|
+
except (json.JSONDecodeError, Exception):
|
|
220
|
+
pass
|
|
221
|
+
|
|
222
|
+
# Check requirements.txt (Python)
|
|
223
|
+
requirements_txt = service_path / "requirements.txt"
|
|
224
|
+
if requirements_txt.exists():
|
|
225
|
+
try:
|
|
226
|
+
with requirements_txt.open(encoding="utf-8") as f:
|
|
227
|
+
for line in f:
|
|
228
|
+
line = line.strip()
|
|
229
|
+
if line and not line.startswith("#"):
|
|
230
|
+
# Extract package name (before ==, >=, etc.)
|
|
231
|
+
package_name = line.split("==")[0].split(">=")[0].split("<=")[0].strip()
|
|
232
|
+
if package_name:
|
|
233
|
+
dependencies.append(package_name)
|
|
234
|
+
except Exception as e:
|
|
235
|
+
logger.debug(f"Failed to parse requirements.txt for service {service_path.name}: {e}")
|
|
236
|
+
|
|
237
|
+
# Check pyproject.toml (Python)
|
|
238
|
+
pyproject_toml = service_path / "pyproject.toml"
|
|
239
|
+
if pyproject_toml.exists():
|
|
240
|
+
try:
|
|
241
|
+
import tomllib # Python 3.11+
|
|
242
|
+
|
|
243
|
+
with pyproject_toml.open("rb") as f:
|
|
244
|
+
pyproject_data = tomllib.load(f)
|
|
245
|
+
project_deps = pyproject_data.get("project", {}).get(
|
|
246
|
+
"dependencies", []
|
|
247
|
+
)
|
|
248
|
+
for dep in project_deps:
|
|
249
|
+
# Extract package name (before version specifiers)
|
|
250
|
+
package_name = dep.split("==")[0].split(">=")[0].split("<=")[0].strip()
|
|
251
|
+
if package_name:
|
|
252
|
+
dependencies.append(package_name)
|
|
253
|
+
except ImportError:
|
|
254
|
+
# Fallback for Python < 3.11 (could use tomli)
|
|
255
|
+
pass
|
|
256
|
+
except Exception as e:
|
|
257
|
+
logger.debug(f"Failed to parse requirements.txt for service {service_path.name}: {e}")
|
|
258
|
+
|
|
259
|
+
return sorted(set(dependencies))
|
|
260
|
+
|
|
261
|
+
def _determine_priority(
|
|
262
|
+
self, service_name: str, dependencies: list[str], file_count: int
|
|
263
|
+
) -> Priority:
|
|
264
|
+
"""
|
|
265
|
+
Determine service priority based on name patterns, dependencies, and file count.
|
|
266
|
+
|
|
267
|
+
Phase 4.1: Prioritization Logic
|
|
268
|
+
"""
|
|
269
|
+
service_name_lower = service_name.lower()
|
|
270
|
+
|
|
271
|
+
# Critical priority patterns
|
|
272
|
+
critical_patterns = [
|
|
273
|
+
"auth",
|
|
274
|
+
"security",
|
|
275
|
+
"api",
|
|
276
|
+
"gateway",
|
|
277
|
+
"core",
|
|
278
|
+
"base",
|
|
279
|
+
"common",
|
|
280
|
+
]
|
|
281
|
+
if any(pattern in service_name_lower for pattern in critical_patterns):
|
|
282
|
+
return Priority.CRITICAL
|
|
283
|
+
|
|
284
|
+
# High priority: many dependencies or high file count
|
|
285
|
+
if len(dependencies) > 20 or file_count > 100:
|
|
286
|
+
return Priority.HIGH
|
|
287
|
+
|
|
288
|
+
# High priority patterns
|
|
289
|
+
high_patterns = ["service", "server", "backend", "frontend", "client"]
|
|
290
|
+
if any(pattern in service_name_lower for pattern in high_patterns):
|
|
291
|
+
return Priority.HIGH
|
|
292
|
+
|
|
293
|
+
# Low priority: minimal dependencies and low file count
|
|
294
|
+
if len(dependencies) < 3 and file_count < 10:
|
|
295
|
+
return Priority.LOW
|
|
296
|
+
|
|
297
|
+
# Default to medium
|
|
298
|
+
return Priority.MEDIUM
|
|
299
|
+
|
|
300
|
+
def prioritize_services(self, services: list[Service]) -> list[Service]:
|
|
301
|
+
"""
|
|
302
|
+
Prioritize services: critical → high → medium → low.
|
|
303
|
+
|
|
304
|
+
Phase 4.1: Service Prioritization
|
|
305
|
+
"""
|
|
306
|
+
priority_order = {
|
|
307
|
+
Priority.CRITICAL: 0,
|
|
308
|
+
Priority.HIGH: 1,
|
|
309
|
+
Priority.MEDIUM: 2,
|
|
310
|
+
Priority.LOW: 3,
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
def priority_key(service: Service) -> tuple[int, str]:
|
|
314
|
+
return (priority_order.get(service.priority, 99), service.name)
|
|
315
|
+
|
|
316
|
+
return sorted(services, key=priority_key)
|
|
317
|
+
|
|
318
|
+
def group_by_language(self, services: list[Service]) -> dict[Language, list[Service]]:
|
|
319
|
+
"""
|
|
320
|
+
Group services by detected primary language.
|
|
321
|
+
|
|
322
|
+
Phase 4.1: Language Grouping
|
|
323
|
+
"""
|
|
324
|
+
grouped: dict[Language, list[Service]] = {}
|
|
325
|
+
for service in services:
|
|
326
|
+
if service.language not in grouped:
|
|
327
|
+
grouped[service.language] = []
|
|
328
|
+
grouped[service.language].append(service)
|
|
329
|
+
return grouped
|
|
330
|
+
|
|
331
|
+
def discover_services_with_priority(
|
|
332
|
+
self, prioritize: bool = True, group_by_language: bool = False
|
|
333
|
+
) -> list[Service] | dict[Language, list[Service]]:
|
|
334
|
+
"""
|
|
335
|
+
Discover services with prioritization and optional language grouping.
|
|
336
|
+
|
|
337
|
+
Phase 4.1: Enhanced Service Discovery
|
|
338
|
+
|
|
339
|
+
Args:
|
|
340
|
+
prioritize: Whether to prioritize services (critical → high → medium → low)
|
|
341
|
+
group_by_language: Whether to group services by language
|
|
342
|
+
|
|
343
|
+
Returns:
|
|
344
|
+
List of prioritized Service objects, or dict grouped by language
|
|
345
|
+
"""
|
|
346
|
+
services = self.discover_services_enhanced()
|
|
347
|
+
|
|
348
|
+
if prioritize:
|
|
349
|
+
services = self.prioritize_services(services)
|
|
350
|
+
|
|
351
|
+
if group_by_language:
|
|
352
|
+
return self.group_by_language(services)
|
|
353
|
+
|
|
354
|
+
return services
|
|
355
|
+
|
|
356
|
+
def discover_services(self) -> list[dict[str, Any]]:
|
|
357
|
+
"""
|
|
358
|
+
Discover all services in the project.
|
|
359
|
+
|
|
360
|
+
Returns:
|
|
361
|
+
List of service dictionaries with:
|
|
362
|
+
- name: Service name (directory name)
|
|
363
|
+
- path: Full path to service directory
|
|
364
|
+
- relative_path: Relative path from project root
|
|
365
|
+
"""
|
|
366
|
+
services: list[dict[str, Any]] = []
|
|
367
|
+
|
|
368
|
+
# Try each service pattern
|
|
369
|
+
for pattern in self.service_patterns:
|
|
370
|
+
# If the pattern points directly at a service root (no wildcard), include that directory itself.
|
|
371
|
+
# This lets us analyze mono-package repos like `tapps_agents/` as a single “service”.
|
|
372
|
+
if "*" not in pattern and "?" not in pattern:
|
|
373
|
+
base_dir = pattern.rstrip("/").rstrip("\\")
|
|
374
|
+
candidate = self.project_root / base_dir
|
|
375
|
+
if (
|
|
376
|
+
candidate.exists()
|
|
377
|
+
and candidate.is_dir()
|
|
378
|
+
and not self._should_exclude(candidate)
|
|
379
|
+
):
|
|
380
|
+
if self._is_service_directory(candidate):
|
|
381
|
+
services.append(
|
|
382
|
+
{
|
|
383
|
+
"name": candidate.name,
|
|
384
|
+
"path": str(candidate),
|
|
385
|
+
"relative_path": str(
|
|
386
|
+
candidate.relative_to(self.project_root)
|
|
387
|
+
),
|
|
388
|
+
"pattern": pattern,
|
|
389
|
+
}
|
|
390
|
+
)
|
|
391
|
+
continue
|
|
392
|
+
|
|
393
|
+
# Convert glob pattern to directory structure
|
|
394
|
+
# e.g., "services/*/" -> "services/"
|
|
395
|
+
base_dir = pattern.split("*")[0].rstrip("/")
|
|
396
|
+
base_path = self.project_root / base_dir
|
|
397
|
+
|
|
398
|
+
if not base_path.exists() or not base_path.is_dir():
|
|
399
|
+
continue
|
|
400
|
+
|
|
401
|
+
# Find all subdirectories
|
|
402
|
+
for item in base_path.iterdir():
|
|
403
|
+
if not item.is_dir():
|
|
404
|
+
continue
|
|
405
|
+
|
|
406
|
+
# Check exclusion patterns
|
|
407
|
+
if self._should_exclude(item):
|
|
408
|
+
continue
|
|
409
|
+
|
|
410
|
+
# Check if it looks like a service (has code files)
|
|
411
|
+
if self._is_service_directory(item):
|
|
412
|
+
service_name = item.name
|
|
413
|
+
services.append(
|
|
414
|
+
{
|
|
415
|
+
"name": service_name,
|
|
416
|
+
"path": str(item),
|
|
417
|
+
"relative_path": str(item.relative_to(self.project_root)),
|
|
418
|
+
"pattern": pattern,
|
|
419
|
+
}
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
# Remove duplicates (services might match multiple patterns)
|
|
423
|
+
seen = set()
|
|
424
|
+
unique_services = []
|
|
425
|
+
for service in services:
|
|
426
|
+
key = service["path"]
|
|
427
|
+
if key not in seen:
|
|
428
|
+
seen.add(key)
|
|
429
|
+
unique_services.append(service)
|
|
430
|
+
|
|
431
|
+
return sorted(unique_services, key=lambda x: x["name"])
|
|
432
|
+
|
|
433
|
+
def _should_exclude(self, path: Path) -> bool:
|
|
434
|
+
"""Check if a path should be excluded."""
|
|
435
|
+
path_str = str(path)
|
|
436
|
+
path_name = path.name
|
|
437
|
+
|
|
438
|
+
# Check exclusion patterns
|
|
439
|
+
for exclude_pattern in self.exclude_patterns:
|
|
440
|
+
if exclude_pattern in path_str or path_name.startswith(exclude_pattern):
|
|
441
|
+
return True
|
|
442
|
+
|
|
443
|
+
# Exclude hidden directories
|
|
444
|
+
if path_name.startswith("."):
|
|
445
|
+
return True
|
|
446
|
+
|
|
447
|
+
return False
|
|
448
|
+
|
|
449
|
+
def _is_service_directory(self, path: Path) -> bool:
|
|
450
|
+
"""
|
|
451
|
+
Check if a directory looks like a service directory.
|
|
452
|
+
|
|
453
|
+
A service directory should have:
|
|
454
|
+
- Python files (*.py)
|
|
455
|
+
- Or TypeScript files (*.ts, *.tsx)
|
|
456
|
+
- Or JavaScript files (*.js, *.jsx)
|
|
457
|
+
- Or a requirements.txt / package.json
|
|
458
|
+
- Or a Dockerfile / docker-compose.yml
|
|
459
|
+
"""
|
|
460
|
+
service_indicators = [
|
|
461
|
+
# Code files
|
|
462
|
+
"*.py",
|
|
463
|
+
"*.ts",
|
|
464
|
+
"*.tsx",
|
|
465
|
+
"*.js",
|
|
466
|
+
"*.jsx",
|
|
467
|
+
# Configuration files
|
|
468
|
+
"requirements.txt",
|
|
469
|
+
"package.json",
|
|
470
|
+
"pyproject.toml",
|
|
471
|
+
"setup.py",
|
|
472
|
+
"Dockerfile",
|
|
473
|
+
"docker-compose.yml",
|
|
474
|
+
"*.yaml",
|
|
475
|
+
"*.yml",
|
|
476
|
+
]
|
|
477
|
+
|
|
478
|
+
# Check for service indicators
|
|
479
|
+
for indicator in service_indicators:
|
|
480
|
+
if indicator.startswith("*."):
|
|
481
|
+
# File extension pattern
|
|
482
|
+
extension = indicator[1:]
|
|
483
|
+
matches = list(path.rglob(f"*{extension}"))
|
|
484
|
+
if matches:
|
|
485
|
+
# Make sure it's not just in a subdirectory like node_modules
|
|
486
|
+
for match in matches[:5]: # Check first 5 matches
|
|
487
|
+
if not self._should_exclude(match.parent):
|
|
488
|
+
return True
|
|
489
|
+
else:
|
|
490
|
+
# Specific file pattern
|
|
491
|
+
matches = list(path.glob(indicator))
|
|
492
|
+
if matches:
|
|
493
|
+
return True
|
|
494
|
+
|
|
495
|
+
return False
|
|
496
|
+
|
|
497
|
+
def discover_service(self, service_name: str) -> dict[str, Any] | None:
|
|
498
|
+
"""
|
|
499
|
+
Discover a specific service by name.
|
|
500
|
+
|
|
501
|
+
Args:
|
|
502
|
+
service_name: Name of the service to find
|
|
503
|
+
|
|
504
|
+
Returns:
|
|
505
|
+
Service dictionary if found, None otherwise
|
|
506
|
+
"""
|
|
507
|
+
services = self.discover_services()
|
|
508
|
+
for service in services:
|
|
509
|
+
if service["name"] == service_name:
|
|
510
|
+
return service
|
|
511
|
+
return None
|
|
512
|
+
|
|
513
|
+
def discover_by_pattern(self, pattern: str) -> list[dict[str, Any]]:
|
|
514
|
+
"""
|
|
515
|
+
Discover services matching a specific pattern.
|
|
516
|
+
|
|
517
|
+
Args:
|
|
518
|
+
pattern: Pattern to match service names (supports wildcards)
|
|
519
|
+
|
|
520
|
+
Returns:
|
|
521
|
+
List of matching services
|
|
522
|
+
"""
|
|
523
|
+
services = self.discover_services()
|
|
524
|
+
|
|
525
|
+
# Convert pattern to regex
|
|
526
|
+
regex_pattern = pattern.replace("*", ".*").replace("?", ".")
|
|
527
|
+
regex = re.compile(f"^{regex_pattern}$", re.IGNORECASE)
|
|
528
|
+
|
|
529
|
+
matching_services = []
|
|
530
|
+
for service in services:
|
|
531
|
+
if regex.match(service["name"]):
|
|
532
|
+
matching_services.append(service)
|
|
533
|
+
|
|
534
|
+
return matching_services
|