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,752 +1,752 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Project Type Detector - Auto-detect project characteristics for workflow selection.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import re
|
|
6
|
-
from dataclasses import dataclass
|
|
7
|
-
from enum import Enum
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
from typing import Any
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class ProjectType(Enum):
|
|
13
|
-
"""Project type classification."""
|
|
14
|
-
|
|
15
|
-
GREENFIELD = "greenfield"
|
|
16
|
-
BROWNFIELD = "brownfield"
|
|
17
|
-
QUICK_FIX = "quick_fix"
|
|
18
|
-
HYBRID = "hybrid"
|
|
19
|
-
UNKNOWN = "unknown"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class WorkflowTrack(Enum):
|
|
23
|
-
"""Recommended workflow track."""
|
|
24
|
-
|
|
25
|
-
QUICK_FLOW = "quick_flow" # Bug fixes, small features (< 5 min)
|
|
26
|
-
BMAD_METHOD = "bmad_method" # Standard development (< 15 min)
|
|
27
|
-
ENTERPRISE = "enterprise" # Complex/compliance (< 30 min)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
@dataclass
|
|
31
|
-
class ProjectCharacteristics:
|
|
32
|
-
"""Detected project characteristics."""
|
|
33
|
-
|
|
34
|
-
project_type: ProjectType
|
|
35
|
-
workflow_track: WorkflowTrack
|
|
36
|
-
confidence: float
|
|
37
|
-
indicators: dict[str, Any]
|
|
38
|
-
recommendations: list[str]
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
class ProjectDetector:
|
|
42
|
-
"""Detect project type and recommend workflow track."""
|
|
43
|
-
|
|
44
|
-
def __init__(self, project_root: Path | None = None):
|
|
45
|
-
"""
|
|
46
|
-
Initialize project detector.
|
|
47
|
-
|
|
48
|
-
Args:
|
|
49
|
-
project_root: Root directory of the project
|
|
50
|
-
"""
|
|
51
|
-
self.project_root = project_root or Path.cwd()
|
|
52
|
-
|
|
53
|
-
# Detection rules
|
|
54
|
-
self.greenfield_indicators = [
|
|
55
|
-
("no_src", lambda p: not (p / "src").exists() and not (p / "lib").exists()),
|
|
56
|
-
("no_package_files", lambda p: not self._has_package_files(p)),
|
|
57
|
-
("no_git_history", lambda p: not (p / ".git").exists()),
|
|
58
|
-
("minimal_files", lambda p: len(list(p.glob("*"))) < 5),
|
|
59
|
-
]
|
|
60
|
-
|
|
61
|
-
self.brownfield_indicators = [
|
|
62
|
-
("has_src", lambda p: (p / "src").exists() or (p / "lib").exists()),
|
|
63
|
-
("has_package_files", lambda p: self._has_package_files(p)),
|
|
64
|
-
("has_git_history", lambda p: (p / ".git").exists()),
|
|
65
|
-
("has_tests", lambda p: (p / "tests").exists() or (p / "test").exists()),
|
|
66
|
-
("has_docs", lambda p: (p / "docs").exists() or (p / "README.md").exists()),
|
|
67
|
-
("many_files", lambda p: len(list(p.glob("*"))) >= 5),
|
|
68
|
-
]
|
|
69
|
-
|
|
70
|
-
self.quick_fix_keywords = [
|
|
71
|
-
"bug",
|
|
72
|
-
"fix",
|
|
73
|
-
"hotfix",
|
|
74
|
-
"patch",
|
|
75
|
-
"issue",
|
|
76
|
-
"error",
|
|
77
|
-
"bugfix",
|
|
78
|
-
"repair",
|
|
79
|
-
"correct",
|
|
80
|
-
"resolve",
|
|
81
|
-
]
|
|
82
|
-
|
|
83
|
-
self.complexity_indicators = [
|
|
84
|
-
("has_compliance", lambda p: self._has_compliance_files(p)),
|
|
85
|
-
("has_security", lambda p: self._has_security_files(p)),
|
|
86
|
-
("multiple_domains", lambda p: self._has_multiple_domains(p)),
|
|
87
|
-
("large_codebase", lambda p: self._is_large_codebase(p)),
|
|
88
|
-
]
|
|
89
|
-
|
|
90
|
-
def _has_package_files(self, project_root: Path) -> bool:
|
|
91
|
-
"""Check if project has package management files."""
|
|
92
|
-
package_files = [
|
|
93
|
-
"package.json",
|
|
94
|
-
"requirements.txt",
|
|
95
|
-
"Pipfile",
|
|
96
|
-
"pyproject.toml",
|
|
97
|
-
"Cargo.toml",
|
|
98
|
-
"go.mod",
|
|
99
|
-
"pom.xml",
|
|
100
|
-
"build.gradle",
|
|
101
|
-
"composer.json",
|
|
102
|
-
]
|
|
103
|
-
return any((project_root / f).exists() for f in package_files)
|
|
104
|
-
|
|
105
|
-
def _has_compliance_files(self, project_root: Path) -> bool:
|
|
106
|
-
"""Check if project has compliance-related files."""
|
|
107
|
-
compliance_patterns = ["compliance", "hipaa", "pci", "gdpr", "soc2", "audit"]
|
|
108
|
-
paths = [project_root / f for f in compliance_patterns]
|
|
109
|
-
return any(p.exists() for p in paths) or any(
|
|
110
|
-
compliance_pattern in str(p).lower()
|
|
111
|
-
for p in project_root.rglob("*")
|
|
112
|
-
if p.is_file()
|
|
113
|
-
for compliance_pattern in compliance_patterns
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
def _has_security_files(self, project_root: Path) -> bool:
|
|
117
|
-
"""Check if project has security-related files."""
|
|
118
|
-
security_files = [
|
|
119
|
-
".security",
|
|
120
|
-
"security.md",
|
|
121
|
-
"SECURITY.md",
|
|
122
|
-
".bandit",
|
|
123
|
-
".safety",
|
|
124
|
-
]
|
|
125
|
-
return any((project_root / f).exists() for f in security_files)
|
|
126
|
-
|
|
127
|
-
def _has_multiple_domains(self, project_root: Path) -> bool:
|
|
128
|
-
"""Check if project has multiple domain configurations."""
|
|
129
|
-
domains_file = project_root / ".tapps-agents" / "domains.md"
|
|
130
|
-
if domains_file.exists():
|
|
131
|
-
content = domains_file.read_text(encoding="utf-8")
|
|
132
|
-
# Count domain sections
|
|
133
|
-
domain_count = len(re.findall(r"### Domain \d+:", content))
|
|
134
|
-
return domain_count > 1
|
|
135
|
-
return False
|
|
136
|
-
|
|
137
|
-
def _is_large_codebase(self, project_root: Path) -> bool:
|
|
138
|
-
"""Check if codebase is large (heuristic: >1000 files)."""
|
|
139
|
-
code_extensions = {".py", ".js", ".ts", ".java", ".go", ".rs", ".cpp", ".c"}
|
|
140
|
-
count = 0
|
|
141
|
-
for ext in code_extensions:
|
|
142
|
-
count += len(list(project_root.rglob(f"*{ext}")))
|
|
143
|
-
if count > 1000:
|
|
144
|
-
return True
|
|
145
|
-
return False
|
|
146
|
-
|
|
147
|
-
def detect_deployment_type(self) -> tuple[str | None, float, list[str]]:
|
|
148
|
-
"""
|
|
149
|
-
Detect deployment type with confidence score.
|
|
150
|
-
|
|
151
|
-
Returns:
|
|
152
|
-
Tuple of (deployment_type, confidence, indicators)
|
|
153
|
-
deployment_type: "local", "cloud", or "enterprise" (or None)
|
|
154
|
-
confidence: 0.0-1.0
|
|
155
|
-
indicators: List of indicator names that matched
|
|
156
|
-
"""
|
|
157
|
-
indicators = []
|
|
158
|
-
cloud_score = 0.0
|
|
159
|
-
enterprise_score = 0.0
|
|
160
|
-
local_score = 0.0
|
|
161
|
-
|
|
162
|
-
# Enterprise indicators (Kubernetes, Helm, compliance, security)
|
|
163
|
-
enterprise_checks = [
|
|
164
|
-
(
|
|
165
|
-
"has_kubernetes",
|
|
166
|
-
lambda p: (p / "k8s").exists() or (p / "kubernetes").exists(),
|
|
167
|
-
),
|
|
168
|
-
(
|
|
169
|
-
"has_helm",
|
|
170
|
-
lambda p: (p / "helm").exists()
|
|
171
|
-
or any((p / f).exists() for f in ["Chart.yaml", "values.yaml"]),
|
|
172
|
-
),
|
|
173
|
-
(
|
|
174
|
-
"has_compliance",
|
|
175
|
-
lambda p: (p / "compliance").exists()
|
|
176
|
-
or any((p / f).exists() for f in ["HIPAA.md", "GDPR.md", "SOC2.md"]),
|
|
177
|
-
),
|
|
178
|
-
(
|
|
179
|
-
"has_security",
|
|
180
|
-
lambda p: (p / "security").exists()
|
|
181
|
-
or (p / ".security").exists()
|
|
182
|
-
or (p / "security.md").exists(),
|
|
183
|
-
),
|
|
184
|
-
]
|
|
185
|
-
|
|
186
|
-
for name, check in enterprise_checks:
|
|
187
|
-
if check(self.project_root):
|
|
188
|
-
enterprise_score += 0.25
|
|
189
|
-
indicators.append(name)
|
|
190
|
-
|
|
191
|
-
# Cloud indicators (Docker, serverless, terraform)
|
|
192
|
-
cloud_checks = [
|
|
193
|
-
("has_dockerfile", lambda p: (p / "Dockerfile").exists()),
|
|
194
|
-
(
|
|
195
|
-
"has_docker_compose",
|
|
196
|
-
lambda p: (p / "docker-compose.yml").exists()
|
|
197
|
-
or (p / "docker-compose.yaml").exists(),
|
|
198
|
-
),
|
|
199
|
-
(
|
|
200
|
-
"has_serverless",
|
|
201
|
-
lambda p: (p / "serverless.yml").exists()
|
|
202
|
-
or (p / "serverless.yaml").exists(),
|
|
203
|
-
),
|
|
204
|
-
(
|
|
205
|
-
"has_terraform",
|
|
206
|
-
lambda p: (p / "terraform").exists()
|
|
207
|
-
or any(
|
|
208
|
-
(p / f).exists()
|
|
209
|
-
for f in ["main.tf", "variables.tf", "terraform.tf"]
|
|
210
|
-
),
|
|
211
|
-
),
|
|
212
|
-
]
|
|
213
|
-
|
|
214
|
-
for name, check in cloud_checks:
|
|
215
|
-
if check(self.project_root):
|
|
216
|
-
cloud_score += 0.2
|
|
217
|
-
indicators.append(name)
|
|
218
|
-
|
|
219
|
-
# Local indicators (conservative - default to local)
|
|
220
|
-
if cloud_score < 0.3 and enterprise_score < 0.3:
|
|
221
|
-
local_score = 0.5 # Conservative default
|
|
222
|
-
indicators.append("no_cloud_infrastructure")
|
|
223
|
-
|
|
224
|
-
# Determine result (enterprise takes precedence)
|
|
225
|
-
if enterprise_score >= 0.5:
|
|
226
|
-
return ("enterprise", min(0.95, enterprise_score), indicators)
|
|
227
|
-
elif cloud_score >= 0.6:
|
|
228
|
-
return ("cloud", min(0.9, cloud_score), indicators)
|
|
229
|
-
elif cloud_score >= 0.3:
|
|
230
|
-
return ("cloud", min(0.7, cloud_score), indicators)
|
|
231
|
-
else:
|
|
232
|
-
return ("local", min(0.8, local_score), indicators)
|
|
233
|
-
|
|
234
|
-
def detect_compliance_requirements(self) -> list[tuple[str, float, list[str]]]:
|
|
235
|
-
"""
|
|
236
|
-
Detect compliance requirements from files.
|
|
237
|
-
|
|
238
|
-
Returns:
|
|
239
|
-
List of tuples: (compliance_name, confidence, indicators)
|
|
240
|
-
"""
|
|
241
|
-
compliance_patterns = {
|
|
242
|
-
"GDPR": ["gdpr", "general data protection regulation"],
|
|
243
|
-
"HIPAA": ["hipaa", "health insurance portability"],
|
|
244
|
-
"PCI": ["pci", "payment card industry"],
|
|
245
|
-
"SOC2": ["soc2", "soc 2", "service organization control"],
|
|
246
|
-
"ISO27001": ["iso27001", "iso 27001"],
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
requirements = []
|
|
250
|
-
project_root = self.project_root
|
|
251
|
-
|
|
252
|
-
# Check for compliance files/directories
|
|
253
|
-
for compliance_name, patterns in compliance_patterns.items():
|
|
254
|
-
indicators = []
|
|
255
|
-
confidence = 0.0
|
|
256
|
-
|
|
257
|
-
# Check file/directory names
|
|
258
|
-
for pattern in patterns:
|
|
259
|
-
# Check exact file/directory names
|
|
260
|
-
if (project_root / pattern).exists():
|
|
261
|
-
confidence += 0.4
|
|
262
|
-
indicators.append(f"{pattern}_file_found")
|
|
263
|
-
|
|
264
|
-
# Check in file paths
|
|
265
|
-
matching_files = list(project_root.rglob(f"*{pattern}*"))
|
|
266
|
-
if matching_files:
|
|
267
|
-
confidence += 0.3
|
|
268
|
-
indicators.append(f"{pattern}_pattern_in_paths")
|
|
269
|
-
|
|
270
|
-
# Check in compliance directory
|
|
271
|
-
compliance_dir = project_root / "compliance"
|
|
272
|
-
if compliance_dir.exists():
|
|
273
|
-
# Check if compliance name appears in compliance directory
|
|
274
|
-
for pattern in patterns:
|
|
275
|
-
if any(
|
|
276
|
-
pattern in str(p).lower() for p in compliance_dir.rglob("*")
|
|
277
|
-
):
|
|
278
|
-
confidence += 0.3
|
|
279
|
-
indicators.append(f"{compliance_name}_in_compliance_dir")
|
|
280
|
-
break
|
|
281
|
-
|
|
282
|
-
# If we found indicators, add requirement
|
|
283
|
-
if confidence > 0.0:
|
|
284
|
-
requirements.append((compliance_name, min(0.9, confidence), indicators))
|
|
285
|
-
|
|
286
|
-
return requirements
|
|
287
|
-
|
|
288
|
-
def detect_security_level(self) -> tuple[str | None, float, list[str]]:
|
|
289
|
-
"""
|
|
290
|
-
Detect security level with confidence score.
|
|
291
|
-
|
|
292
|
-
Returns:
|
|
293
|
-
Tuple of (security_level, confidence, indicators)
|
|
294
|
-
security_level: "basic", "standard", "high", or "critical" (or None)
|
|
295
|
-
confidence: 0.0-1.0
|
|
296
|
-
indicators: List of indicator names that matched
|
|
297
|
-
"""
|
|
298
|
-
security_files = [
|
|
299
|
-
".security",
|
|
300
|
-
"security.md",
|
|
301
|
-
"SECURITY.md",
|
|
302
|
-
".bandit",
|
|
303
|
-
".safety",
|
|
304
|
-
".snyk",
|
|
305
|
-
"snyk.yml",
|
|
306
|
-
".dependabot",
|
|
307
|
-
"dependabot.yml",
|
|
308
|
-
]
|
|
309
|
-
|
|
310
|
-
indicators = []
|
|
311
|
-
found_files = []
|
|
312
|
-
|
|
313
|
-
for security_file in security_files:
|
|
314
|
-
if (self.project_root / security_file).exists():
|
|
315
|
-
found_files.append(security_file)
|
|
316
|
-
indicators.append(
|
|
317
|
-
f"has_{security_file.replace('.', '').replace('-', '_')}"
|
|
318
|
-
)
|
|
319
|
-
|
|
320
|
-
# Determine security level based on number of files
|
|
321
|
-
num_files = len(found_files)
|
|
322
|
-
|
|
323
|
-
if num_files >= 3:
|
|
324
|
-
return ("high", 0.8, indicators)
|
|
325
|
-
elif num_files == 2:
|
|
326
|
-
return ("standard", 0.7, indicators)
|
|
327
|
-
elif num_files == 1:
|
|
328
|
-
return ("standard", 0.6, indicators)
|
|
329
|
-
else:
|
|
330
|
-
return ("basic", 0.5, ["no_security_files"])
|
|
331
|
-
|
|
332
|
-
def detect_tenancy(self) -> tuple[str | None, float, list[str]]:
|
|
333
|
-
"""
|
|
334
|
-
Detect tenancy model (single-tenant vs multi-tenant) by grepping code.
|
|
335
|
-
|
|
336
|
-
Returns:
|
|
337
|
-
Tuple of (tenancy, confidence, indicators)
|
|
338
|
-
tenancy: "single-tenant" or "multi-tenant" (or None)
|
|
339
|
-
confidence: 0.0-1.0
|
|
340
|
-
indicators: List of indicator names that matched
|
|
341
|
-
"""
|
|
342
|
-
import re
|
|
343
|
-
|
|
344
|
-
indicators = []
|
|
345
|
-
tenant_patterns = [
|
|
346
|
-
r"\btenant_id\b",
|
|
347
|
-
r"\btenantId\b",
|
|
348
|
-
r"\btenant-id\b",
|
|
349
|
-
r"\btenant_uuid\b",
|
|
350
|
-
r"\btenant_context\b",
|
|
351
|
-
r"\bmulti_tenant\b",
|
|
352
|
-
r"\bmultiTenant\b",
|
|
353
|
-
]
|
|
354
|
-
|
|
355
|
-
# Search in common code files
|
|
356
|
-
code_extensions = {
|
|
357
|
-
".py",
|
|
358
|
-
".js",
|
|
359
|
-
".ts",
|
|
360
|
-
".java",
|
|
361
|
-
".go",
|
|
362
|
-
".rs",
|
|
363
|
-
".cpp",
|
|
364
|
-
".c",
|
|
365
|
-
".cs",
|
|
366
|
-
}
|
|
367
|
-
matching_files = set()
|
|
368
|
-
|
|
369
|
-
for ext in code_extensions:
|
|
370
|
-
for code_file in self.project_root.rglob(f"*{ext}"):
|
|
371
|
-
try:
|
|
372
|
-
# Skip very large files and binary-like files
|
|
373
|
-
if code_file.stat().st_size > 1_000_000: # 1MB limit
|
|
374
|
-
continue
|
|
375
|
-
|
|
376
|
-
content = code_file.read_text(encoding="utf-8", errors="ignore")
|
|
377
|
-
|
|
378
|
-
# Check for tenant patterns
|
|
379
|
-
for pattern in tenant_patterns:
|
|
380
|
-
if re.search(pattern, content, re.IGNORECASE):
|
|
381
|
-
matching_files.add(code_file)
|
|
382
|
-
indicators.append(f"tenant_pattern_in_{code_file.name}")
|
|
383
|
-
break # Count file once even if multiple patterns match
|
|
384
|
-
except (UnicodeDecodeError, PermissionError, OSError):
|
|
385
|
-
# Skip files that can't be read
|
|
386
|
-
continue
|
|
387
|
-
|
|
388
|
-
num_files = len(matching_files)
|
|
389
|
-
|
|
390
|
-
# Determine tenancy based on number of files with tenant patterns
|
|
391
|
-
if num_files > 3:
|
|
392
|
-
return ("multi-tenant", 0.8, indicators)
|
|
393
|
-
elif num_files >= 1:
|
|
394
|
-
return ("multi-tenant", 0.6, indicators) # Medium confidence, suggest
|
|
395
|
-
else:
|
|
396
|
-
# Conservative: default to single-tenant if no patterns found
|
|
397
|
-
return ("single-tenant", 0.7, ["no_tenant_patterns_found"])
|
|
398
|
-
|
|
399
|
-
def detect_user_scale(self) -> tuple[str | None, float, list[str]]:
|
|
400
|
-
"""
|
|
401
|
-
Detect expected user scale from infrastructure patterns.
|
|
402
|
-
|
|
403
|
-
Returns:
|
|
404
|
-
Tuple of (user_scale, confidence, indicators)
|
|
405
|
-
user_scale: "single-user", "small-team", "department", "enterprise" (or None)
|
|
406
|
-
confidence: 0.0-1.0
|
|
407
|
-
indicators: List of indicator names that matched
|
|
408
|
-
"""
|
|
409
|
-
indicators = []
|
|
410
|
-
scale_score = {
|
|
411
|
-
"single-user": 0.0,
|
|
412
|
-
"small-team": 0.0,
|
|
413
|
-
"department": 0.0,
|
|
414
|
-
"enterprise": 0.0,
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
# Enterprise indicators (high scale)
|
|
418
|
-
enterprise_checks = [
|
|
419
|
-
(
|
|
420
|
-
"has_load_balancer",
|
|
421
|
-
lambda p: any(
|
|
422
|
-
(p / f).exists()
|
|
423
|
-
for f in ["nginx.conf", "haproxy.cfg", "traefik.yml"]
|
|
424
|
-
),
|
|
425
|
-
),
|
|
426
|
-
(
|
|
427
|
-
"has_oauth",
|
|
428
|
-
lambda p: any(
|
|
429
|
-
"oauth" in str(f).lower() for f in p.rglob("*") if f.is_file()
|
|
430
|
-
),
|
|
431
|
-
),
|
|
432
|
-
(
|
|
433
|
-
"has_saml",
|
|
434
|
-
lambda p: any(
|
|
435
|
-
"saml" in str(f).lower() for f in p.rglob("*") if f.is_file()
|
|
436
|
-
),
|
|
437
|
-
),
|
|
438
|
-
(
|
|
439
|
-
"has_ldap",
|
|
440
|
-
lambda p: any(
|
|
441
|
-
"ldap" in str(f).lower() for f in p.rglob("*") if f.is_file()
|
|
442
|
-
),
|
|
443
|
-
),
|
|
444
|
-
(
|
|
445
|
-
"has_kubernetes",
|
|
446
|
-
lambda p: (p / "k8s").exists() or (p / "kubernetes").exists(),
|
|
447
|
-
),
|
|
448
|
-
(
|
|
449
|
-
"has_helm",
|
|
450
|
-
lambda p: (p / "helm").exists()
|
|
451
|
-
or any((p / f).exists() for f in ["Chart.yaml", "values.yaml"]),
|
|
452
|
-
),
|
|
453
|
-
]
|
|
454
|
-
|
|
455
|
-
for name, check in enterprise_checks:
|
|
456
|
-
if check(self.project_root):
|
|
457
|
-
scale_score["enterprise"] += 0.15
|
|
458
|
-
indicators.append(name)
|
|
459
|
-
|
|
460
|
-
# Department indicators (medium scale - caching, queues)
|
|
461
|
-
department_checks = [
|
|
462
|
-
(
|
|
463
|
-
"has_redis",
|
|
464
|
-
lambda p: any(
|
|
465
|
-
"redis" in str(f).lower() for f in p.rglob("*") if f.is_file()
|
|
466
|
-
)
|
|
467
|
-
or (p / "redis.conf").exists(),
|
|
468
|
-
),
|
|
469
|
-
(
|
|
470
|
-
"has_memcached",
|
|
471
|
-
lambda p: any(
|
|
472
|
-
"memcached" in str(f).lower() for f in p.rglob("*") if f.is_file()
|
|
473
|
-
),
|
|
474
|
-
),
|
|
475
|
-
(
|
|
476
|
-
"has_message_queue",
|
|
477
|
-
lambda p: any(
|
|
478
|
-
q in str(f).lower()
|
|
479
|
-
for q in ["rabbitmq", "kafka", "sqs"]
|
|
480
|
-
for f in p.rglob("*")
|
|
481
|
-
if f.is_file()
|
|
482
|
-
),
|
|
483
|
-
),
|
|
484
|
-
]
|
|
485
|
-
|
|
486
|
-
for name, check in department_checks:
|
|
487
|
-
if check(self.project_root):
|
|
488
|
-
scale_score["department"] += 0.2
|
|
489
|
-
indicators.append(name)
|
|
490
|
-
|
|
491
|
-
# Small team indicators (basic infrastructure)
|
|
492
|
-
small_team_checks = [
|
|
493
|
-
(
|
|
494
|
-
"has_docker",
|
|
495
|
-
lambda p: (p / "Dockerfile").exists()
|
|
496
|
-
or (p / "docker-compose.yml").exists(),
|
|
497
|
-
),
|
|
498
|
-
(
|
|
499
|
-
"has_database",
|
|
500
|
-
lambda p: any(
|
|
501
|
-
db in str(f).lower()
|
|
502
|
-
for db in ["postgres", "mysql", "sqlite"]
|
|
503
|
-
for f in p.rglob("*")
|
|
504
|
-
if f.is_file()
|
|
505
|
-
),
|
|
506
|
-
),
|
|
507
|
-
]
|
|
508
|
-
|
|
509
|
-
for name, check in small_team_checks:
|
|
510
|
-
if check(self.project_root):
|
|
511
|
-
scale_score["small-team"] += 0.3
|
|
512
|
-
indicators.append(name)
|
|
513
|
-
|
|
514
|
-
# Determine result
|
|
515
|
-
max_scale = max(scale_score.items(), key=lambda x: x[1])
|
|
516
|
-
max_scale_name, max_scale_score = max_scale
|
|
517
|
-
|
|
518
|
-
if max_scale_score >= 0.6:
|
|
519
|
-
confidence = min(0.8, max_scale_score)
|
|
520
|
-
return (max_scale_name, confidence, indicators)
|
|
521
|
-
elif max_scale_score >= 0.3:
|
|
522
|
-
confidence = min(0.6, max_scale_score)
|
|
523
|
-
return (
|
|
524
|
-
max_scale_name,
|
|
525
|
-
confidence,
|
|
526
|
-
indicators,
|
|
527
|
-
) # Medium confidence, suggest
|
|
528
|
-
else:
|
|
529
|
-
# Default to small-team with low confidence
|
|
530
|
-
return ("small-team", 0.5, indicators + ["default_small_team"])
|
|
531
|
-
|
|
532
|
-
def detect_from_context(
|
|
533
|
-
self,
|
|
534
|
-
user_query: str | None = None,
|
|
535
|
-
file_count: int | None = None,
|
|
536
|
-
scope_description: str | None = None,
|
|
537
|
-
) -> ProjectCharacteristics:
|
|
538
|
-
"""
|
|
539
|
-
Detect project type from user context (for fix-workflow selection).
|
|
540
|
-
|
|
541
|
-
Args:
|
|
542
|
-
user_query: User's query or request
|
|
543
|
-
file_count: Estimated number of files to change
|
|
544
|
-
scope_description: Description of the change scope
|
|
545
|
-
|
|
546
|
-
Returns:
|
|
547
|
-
ProjectCharacteristics with detection results
|
|
548
|
-
"""
|
|
549
|
-
indicators = {}
|
|
550
|
-
confidence = 0.0
|
|
551
|
-
recommendations = []
|
|
552
|
-
|
|
553
|
-
# Check for quick-fix keywords
|
|
554
|
-
quick_fix_score = 0.0
|
|
555
|
-
if user_query:
|
|
556
|
-
query_lower = user_query.lower()
|
|
557
|
-
for keyword in self.quick_fix_keywords:
|
|
558
|
-
if keyword in query_lower:
|
|
559
|
-
quick_fix_score += 0.2
|
|
560
|
-
indicators["quick_fix_keywords"] = quick_fix_score > 0
|
|
561
|
-
|
|
562
|
-
if scope_description:
|
|
563
|
-
desc_lower = scope_description.lower()
|
|
564
|
-
for keyword in self.quick_fix_keywords:
|
|
565
|
-
if keyword in desc_lower:
|
|
566
|
-
quick_fix_score += 0.2
|
|
567
|
-
|
|
568
|
-
# Check file scope
|
|
569
|
-
small_scope = file_count is not None and file_count < 5
|
|
570
|
-
if small_scope:
|
|
571
|
-
quick_fix_score += 0.4
|
|
572
|
-
indicators["small_scope"] = True
|
|
573
|
-
|
|
574
|
-
# Determine if quick-fix
|
|
575
|
-
if quick_fix_score >= 0.6:
|
|
576
|
-
confidence = min(0.9, quick_fix_score)
|
|
577
|
-
recommendations.append("Consider Quick Flow track for fast turnaround")
|
|
578
|
-
return ProjectCharacteristics(
|
|
579
|
-
project_type=ProjectType.QUICK_FIX,
|
|
580
|
-
workflow_track=WorkflowTrack.QUICK_FLOW,
|
|
581
|
-
confidence=confidence,
|
|
582
|
-
indicators=indicators,
|
|
583
|
-
recommendations=recommendations,
|
|
584
|
-
)
|
|
585
|
-
|
|
586
|
-
# Otherwise, use standard detection
|
|
587
|
-
return self.detect()
|
|
588
|
-
|
|
589
|
-
def detect(self) -> ProjectCharacteristics:
|
|
590
|
-
"""
|
|
591
|
-
Detect project type from file system analysis.
|
|
592
|
-
|
|
593
|
-
Returns:
|
|
594
|
-
ProjectCharacteristics with detection results
|
|
595
|
-
"""
|
|
596
|
-
indicators = {}
|
|
597
|
-
greenfield_score = 0.0
|
|
598
|
-
brownfield_score = 0.0
|
|
599
|
-
|
|
600
|
-
# Check greenfield indicators
|
|
601
|
-
for name, check in self.greenfield_indicators:
|
|
602
|
-
if check(self.project_root):
|
|
603
|
-
greenfield_score += 0.25
|
|
604
|
-
indicators[name] = True
|
|
605
|
-
else:
|
|
606
|
-
indicators[name] = False
|
|
607
|
-
|
|
608
|
-
# Check brownfield indicators
|
|
609
|
-
for name, check in self.brownfield_indicators:
|
|
610
|
-
if check(self.project_root):
|
|
611
|
-
brownfield_score += 0.15
|
|
612
|
-
indicators[name] = True
|
|
613
|
-
else:
|
|
614
|
-
indicators[name] = False
|
|
615
|
-
|
|
616
|
-
# Check for enterprise/complexity indicators first (before type determination)
|
|
617
|
-
complexity_score = 0.0
|
|
618
|
-
recommendations = [] # Initialize recommendations list
|
|
619
|
-
|
|
620
|
-
for name, check in self.complexity_indicators:
|
|
621
|
-
if check(self.project_root):
|
|
622
|
-
complexity_score += 0.25
|
|
623
|
-
indicators[name] = True
|
|
624
|
-
if name == "has_compliance":
|
|
625
|
-
recommendations.append(
|
|
626
|
-
"Compliance requirements detected - consider Enterprise track"
|
|
627
|
-
)
|
|
628
|
-
else:
|
|
629
|
-
indicators[name] = False
|
|
630
|
-
|
|
631
|
-
# Determine project type
|
|
632
|
-
# Prioritize brownfield if both greenfield and brownfield indicators present
|
|
633
|
-
if brownfield_score >= 0.45: # Lower threshold to prefer brownfield
|
|
634
|
-
project_type = ProjectType.BROWNFIELD
|
|
635
|
-
confidence = min(0.9, brownfield_score)
|
|
636
|
-
workflow_track = WorkflowTrack.BMAD_METHOD
|
|
637
|
-
if not recommendations:
|
|
638
|
-
recommendations = [
|
|
639
|
-
"Existing project detected - use BMad Method workflow",
|
|
640
|
-
"Leverage existing codebase structure and patterns",
|
|
641
|
-
]
|
|
642
|
-
elif greenfield_score >= 0.5:
|
|
643
|
-
project_type = ProjectType.GREENFIELD
|
|
644
|
-
confidence = min(0.9, greenfield_score)
|
|
645
|
-
workflow_track = WorkflowTrack.BMAD_METHOD
|
|
646
|
-
if not recommendations:
|
|
647
|
-
recommendations = [
|
|
648
|
-
"New project detected - use BMad Method workflow",
|
|
649
|
-
"Start with requirements gathering and architecture design",
|
|
650
|
-
]
|
|
651
|
-
else:
|
|
652
|
-
project_type = ProjectType.HYBRID
|
|
653
|
-
confidence = 0.5
|
|
654
|
-
workflow_track = WorkflowTrack.BMAD_METHOD
|
|
655
|
-
if not recommendations:
|
|
656
|
-
recommendations = [
|
|
657
|
-
"Mixed indicators detected - defaulting to BMad Method workflow",
|
|
658
|
-
"Review workflow steps and customize as needed",
|
|
659
|
-
]
|
|
660
|
-
|
|
661
|
-
# Upgrade to Enterprise track if complexity is high
|
|
662
|
-
if (
|
|
663
|
-
complexity_score >= 0.25
|
|
664
|
-
): # Lower threshold - any compliance/complexity indicator
|
|
665
|
-
workflow_track = WorkflowTrack.ENTERPRISE
|
|
666
|
-
if not any("Complex project detected" in rec for rec in recommendations):
|
|
667
|
-
recommendations.append(
|
|
668
|
-
"Complex project detected - Enterprise workflow recommended"
|
|
669
|
-
)
|
|
670
|
-
confidence = min(0.95, confidence + 0.1)
|
|
671
|
-
|
|
672
|
-
return ProjectCharacteristics(
|
|
673
|
-
project_type=project_type,
|
|
674
|
-
workflow_track=workflow_track,
|
|
675
|
-
confidence=confidence,
|
|
676
|
-
indicators=indicators,
|
|
677
|
-
recommendations=recommendations,
|
|
678
|
-
)
|
|
679
|
-
|
|
680
|
-
def get_recommended_workflow(
|
|
681
|
-
self, characteristics: ProjectCharacteristics
|
|
682
|
-
) -> str | None:
|
|
683
|
-
"""
|
|
684
|
-
Get recommended workflow preset name based on characteristics.
|
|
685
|
-
|
|
686
|
-
Returns canonical preset IDs: full-sdlc, rapid-dev, fix, quality, brownfield-analysis.
|
|
687
|
-
"""
|
|
688
|
-
if characteristics.workflow_track == WorkflowTrack.QUICK_FLOW:
|
|
689
|
-
return "fix"
|
|
690
|
-
elif characteristics.workflow_track == WorkflowTrack.ENTERPRISE:
|
|
691
|
-
return "full-sdlc"
|
|
692
|
-
else: # BMAD_METHOD
|
|
693
|
-
if characteristics.project_type == ProjectType.GREENFIELD:
|
|
694
|
-
return "rapid-dev"
|
|
695
|
-
elif characteristics.project_type == ProjectType.BROWNFIELD:
|
|
696
|
-
return "brownfield-analysis"
|
|
697
|
-
else:
|
|
698
|
-
return "rapid-dev" # Default (was feature-development)
|
|
699
|
-
|
|
700
|
-
def detect_command_suggestions(self, context: dict[str, Any]) -> list[dict[str, Any]]:
|
|
701
|
-
"""
|
|
702
|
-
Detect when to suggest Epic, coverage, microservice, or Docker commands.
|
|
703
|
-
|
|
704
|
-
Args:
|
|
705
|
-
context: User action context (files, actions, errors, etc.)
|
|
706
|
-
|
|
707
|
-
Returns:
|
|
708
|
-
List of command suggestions
|
|
709
|
-
"""
|
|
710
|
-
suggestions = []
|
|
711
|
-
|
|
712
|
-
# Detect Epic document mentions
|
|
713
|
-
if context.get("files"):
|
|
714
|
-
for file_path in context["files"]:
|
|
715
|
-
if "epic" in str(file_path).lower() and file_path.endswith(".md"):
|
|
716
|
-
suggestions.append({
|
|
717
|
-
"command": f"@simple-mode *epic {file_path}",
|
|
718
|
-
"description": "Execute Epic workflow for this document",
|
|
719
|
-
"confidence": 0.9,
|
|
720
|
-
"type": "epic",
|
|
721
|
-
})
|
|
722
|
-
|
|
723
|
-
# Detect test coverage gaps
|
|
724
|
-
if context.get("action") == "checking_coverage" or "coverage.json" in str(context.get("files", [])):
|
|
725
|
-
suggestions.append({
|
|
726
|
-
"command": "@simple-mode *test-coverage <file> --target 80",
|
|
727
|
-
"description": "Generate tests to improve coverage",
|
|
728
|
-
"confidence": 0.85,
|
|
729
|
-
"type": "coverage",
|
|
730
|
-
})
|
|
731
|
-
|
|
732
|
-
# Detect microservice creation
|
|
733
|
-
if context.get("action") == "creating_service" or "services/" in str(context.get("files", [])):
|
|
734
|
-
suggestions.append({
|
|
735
|
-
"command": "@simple-mode *microservice <name> --port <port> --type fastapi",
|
|
736
|
-
"description": "Generate microservice structure automatically",
|
|
737
|
-
"confidence": 0.8,
|
|
738
|
-
"type": "microservice",
|
|
739
|
-
})
|
|
740
|
-
|
|
741
|
-
# Detect Docker errors
|
|
742
|
-
if context.get("error"):
|
|
743
|
-
error_msg = str(context["error"])
|
|
744
|
-
if any(keyword in error_msg.lower() for keyword in ["docker", "container", "module not found", "workdir"]):
|
|
745
|
-
suggestions.append({
|
|
746
|
-
"command": "@simple-mode *docker-fix <service> \"<error>\"",
|
|
747
|
-
"description": "Debug and fix Docker/container issues",
|
|
748
|
-
"confidence": 0.9,
|
|
749
|
-
"type": "docker",
|
|
750
|
-
})
|
|
751
|
-
|
|
1
|
+
"""
|
|
2
|
+
Project Type Detector - Auto-detect project characteristics for workflow selection.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from enum import Enum
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ProjectType(Enum):
|
|
13
|
+
"""Project type classification."""
|
|
14
|
+
|
|
15
|
+
GREENFIELD = "greenfield"
|
|
16
|
+
BROWNFIELD = "brownfield"
|
|
17
|
+
QUICK_FIX = "quick_fix"
|
|
18
|
+
HYBRID = "hybrid"
|
|
19
|
+
UNKNOWN = "unknown"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class WorkflowTrack(Enum):
|
|
23
|
+
"""Recommended workflow track."""
|
|
24
|
+
|
|
25
|
+
QUICK_FLOW = "quick_flow" # Bug fixes, small features (< 5 min)
|
|
26
|
+
BMAD_METHOD = "bmad_method" # Standard development (< 15 min)
|
|
27
|
+
ENTERPRISE = "enterprise" # Complex/compliance (< 30 min)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class ProjectCharacteristics:
|
|
32
|
+
"""Detected project characteristics."""
|
|
33
|
+
|
|
34
|
+
project_type: ProjectType
|
|
35
|
+
workflow_track: WorkflowTrack
|
|
36
|
+
confidence: float
|
|
37
|
+
indicators: dict[str, Any]
|
|
38
|
+
recommendations: list[str]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ProjectDetector:
|
|
42
|
+
"""Detect project type and recommend workflow track."""
|
|
43
|
+
|
|
44
|
+
def __init__(self, project_root: Path | None = None):
|
|
45
|
+
"""
|
|
46
|
+
Initialize project detector.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
project_root: Root directory of the project
|
|
50
|
+
"""
|
|
51
|
+
self.project_root = project_root or Path.cwd()
|
|
52
|
+
|
|
53
|
+
# Detection rules
|
|
54
|
+
self.greenfield_indicators = [
|
|
55
|
+
("no_src", lambda p: not (p / "src").exists() and not (p / "lib").exists()),
|
|
56
|
+
("no_package_files", lambda p: not self._has_package_files(p)),
|
|
57
|
+
("no_git_history", lambda p: not (p / ".git").exists()),
|
|
58
|
+
("minimal_files", lambda p: len(list(p.glob("*"))) < 5),
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
self.brownfield_indicators = [
|
|
62
|
+
("has_src", lambda p: (p / "src").exists() or (p / "lib").exists()),
|
|
63
|
+
("has_package_files", lambda p: self._has_package_files(p)),
|
|
64
|
+
("has_git_history", lambda p: (p / ".git").exists()),
|
|
65
|
+
("has_tests", lambda p: (p / "tests").exists() or (p / "test").exists()),
|
|
66
|
+
("has_docs", lambda p: (p / "docs").exists() or (p / "README.md").exists()),
|
|
67
|
+
("many_files", lambda p: len(list(p.glob("*"))) >= 5),
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
self.quick_fix_keywords = [
|
|
71
|
+
"bug",
|
|
72
|
+
"fix",
|
|
73
|
+
"hotfix",
|
|
74
|
+
"patch",
|
|
75
|
+
"issue",
|
|
76
|
+
"error",
|
|
77
|
+
"bugfix",
|
|
78
|
+
"repair",
|
|
79
|
+
"correct",
|
|
80
|
+
"resolve",
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
self.complexity_indicators = [
|
|
84
|
+
("has_compliance", lambda p: self._has_compliance_files(p)),
|
|
85
|
+
("has_security", lambda p: self._has_security_files(p)),
|
|
86
|
+
("multiple_domains", lambda p: self._has_multiple_domains(p)),
|
|
87
|
+
("large_codebase", lambda p: self._is_large_codebase(p)),
|
|
88
|
+
]
|
|
89
|
+
|
|
90
|
+
def _has_package_files(self, project_root: Path) -> bool:
|
|
91
|
+
"""Check if project has package management files."""
|
|
92
|
+
package_files = [
|
|
93
|
+
"package.json",
|
|
94
|
+
"requirements.txt",
|
|
95
|
+
"Pipfile",
|
|
96
|
+
"pyproject.toml",
|
|
97
|
+
"Cargo.toml",
|
|
98
|
+
"go.mod",
|
|
99
|
+
"pom.xml",
|
|
100
|
+
"build.gradle",
|
|
101
|
+
"composer.json",
|
|
102
|
+
]
|
|
103
|
+
return any((project_root / f).exists() for f in package_files)
|
|
104
|
+
|
|
105
|
+
def _has_compliance_files(self, project_root: Path) -> bool:
|
|
106
|
+
"""Check if project has compliance-related files."""
|
|
107
|
+
compliance_patterns = ["compliance", "hipaa", "pci", "gdpr", "soc2", "audit"]
|
|
108
|
+
paths = [project_root / f for f in compliance_patterns]
|
|
109
|
+
return any(p.exists() for p in paths) or any(
|
|
110
|
+
compliance_pattern in str(p).lower()
|
|
111
|
+
for p in project_root.rglob("*")
|
|
112
|
+
if p.is_file()
|
|
113
|
+
for compliance_pattern in compliance_patterns
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
def _has_security_files(self, project_root: Path) -> bool:
|
|
117
|
+
"""Check if project has security-related files."""
|
|
118
|
+
security_files = [
|
|
119
|
+
".security",
|
|
120
|
+
"security.md",
|
|
121
|
+
"SECURITY.md",
|
|
122
|
+
".bandit",
|
|
123
|
+
".safety",
|
|
124
|
+
]
|
|
125
|
+
return any((project_root / f).exists() for f in security_files)
|
|
126
|
+
|
|
127
|
+
def _has_multiple_domains(self, project_root: Path) -> bool:
|
|
128
|
+
"""Check if project has multiple domain configurations."""
|
|
129
|
+
domains_file = project_root / ".tapps-agents" / "domains.md"
|
|
130
|
+
if domains_file.exists():
|
|
131
|
+
content = domains_file.read_text(encoding="utf-8")
|
|
132
|
+
# Count domain sections
|
|
133
|
+
domain_count = len(re.findall(r"### Domain \d+:", content))
|
|
134
|
+
return domain_count > 1
|
|
135
|
+
return False
|
|
136
|
+
|
|
137
|
+
def _is_large_codebase(self, project_root: Path) -> bool:
|
|
138
|
+
"""Check if codebase is large (heuristic: >1000 files)."""
|
|
139
|
+
code_extensions = {".py", ".js", ".ts", ".java", ".go", ".rs", ".cpp", ".c"}
|
|
140
|
+
count = 0
|
|
141
|
+
for ext in code_extensions:
|
|
142
|
+
count += len(list(project_root.rglob(f"*{ext}")))
|
|
143
|
+
if count > 1000:
|
|
144
|
+
return True
|
|
145
|
+
return False
|
|
146
|
+
|
|
147
|
+
def detect_deployment_type(self) -> tuple[str | None, float, list[str]]:
|
|
148
|
+
"""
|
|
149
|
+
Detect deployment type with confidence score.
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
Tuple of (deployment_type, confidence, indicators)
|
|
153
|
+
deployment_type: "local", "cloud", or "enterprise" (or None)
|
|
154
|
+
confidence: 0.0-1.0
|
|
155
|
+
indicators: List of indicator names that matched
|
|
156
|
+
"""
|
|
157
|
+
indicators = []
|
|
158
|
+
cloud_score = 0.0
|
|
159
|
+
enterprise_score = 0.0
|
|
160
|
+
local_score = 0.0
|
|
161
|
+
|
|
162
|
+
# Enterprise indicators (Kubernetes, Helm, compliance, security)
|
|
163
|
+
enterprise_checks = [
|
|
164
|
+
(
|
|
165
|
+
"has_kubernetes",
|
|
166
|
+
lambda p: (p / "k8s").exists() or (p / "kubernetes").exists(),
|
|
167
|
+
),
|
|
168
|
+
(
|
|
169
|
+
"has_helm",
|
|
170
|
+
lambda p: (p / "helm").exists()
|
|
171
|
+
or any((p / f).exists() for f in ["Chart.yaml", "values.yaml"]),
|
|
172
|
+
),
|
|
173
|
+
(
|
|
174
|
+
"has_compliance",
|
|
175
|
+
lambda p: (p / "compliance").exists()
|
|
176
|
+
or any((p / f).exists() for f in ["HIPAA.md", "GDPR.md", "SOC2.md"]),
|
|
177
|
+
),
|
|
178
|
+
(
|
|
179
|
+
"has_security",
|
|
180
|
+
lambda p: (p / "security").exists()
|
|
181
|
+
or (p / ".security").exists()
|
|
182
|
+
or (p / "security.md").exists(),
|
|
183
|
+
),
|
|
184
|
+
]
|
|
185
|
+
|
|
186
|
+
for name, check in enterprise_checks:
|
|
187
|
+
if check(self.project_root):
|
|
188
|
+
enterprise_score += 0.25
|
|
189
|
+
indicators.append(name)
|
|
190
|
+
|
|
191
|
+
# Cloud indicators (Docker, serverless, terraform)
|
|
192
|
+
cloud_checks = [
|
|
193
|
+
("has_dockerfile", lambda p: (p / "Dockerfile").exists()),
|
|
194
|
+
(
|
|
195
|
+
"has_docker_compose",
|
|
196
|
+
lambda p: (p / "docker-compose.yml").exists()
|
|
197
|
+
or (p / "docker-compose.yaml").exists(),
|
|
198
|
+
),
|
|
199
|
+
(
|
|
200
|
+
"has_serverless",
|
|
201
|
+
lambda p: (p / "serverless.yml").exists()
|
|
202
|
+
or (p / "serverless.yaml").exists(),
|
|
203
|
+
),
|
|
204
|
+
(
|
|
205
|
+
"has_terraform",
|
|
206
|
+
lambda p: (p / "terraform").exists()
|
|
207
|
+
or any(
|
|
208
|
+
(p / f).exists()
|
|
209
|
+
for f in ["main.tf", "variables.tf", "terraform.tf"]
|
|
210
|
+
),
|
|
211
|
+
),
|
|
212
|
+
]
|
|
213
|
+
|
|
214
|
+
for name, check in cloud_checks:
|
|
215
|
+
if check(self.project_root):
|
|
216
|
+
cloud_score += 0.2
|
|
217
|
+
indicators.append(name)
|
|
218
|
+
|
|
219
|
+
# Local indicators (conservative - default to local)
|
|
220
|
+
if cloud_score < 0.3 and enterprise_score < 0.3:
|
|
221
|
+
local_score = 0.5 # Conservative default
|
|
222
|
+
indicators.append("no_cloud_infrastructure")
|
|
223
|
+
|
|
224
|
+
# Determine result (enterprise takes precedence)
|
|
225
|
+
if enterprise_score >= 0.5:
|
|
226
|
+
return ("enterprise", min(0.95, enterprise_score), indicators)
|
|
227
|
+
elif cloud_score >= 0.6:
|
|
228
|
+
return ("cloud", min(0.9, cloud_score), indicators)
|
|
229
|
+
elif cloud_score >= 0.3:
|
|
230
|
+
return ("cloud", min(0.7, cloud_score), indicators)
|
|
231
|
+
else:
|
|
232
|
+
return ("local", min(0.8, local_score), indicators)
|
|
233
|
+
|
|
234
|
+
def detect_compliance_requirements(self) -> list[tuple[str, float, list[str]]]:
|
|
235
|
+
"""
|
|
236
|
+
Detect compliance requirements from files.
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
List of tuples: (compliance_name, confidence, indicators)
|
|
240
|
+
"""
|
|
241
|
+
compliance_patterns = {
|
|
242
|
+
"GDPR": ["gdpr", "general data protection regulation"],
|
|
243
|
+
"HIPAA": ["hipaa", "health insurance portability"],
|
|
244
|
+
"PCI": ["pci", "payment card industry"],
|
|
245
|
+
"SOC2": ["soc2", "soc 2", "service organization control"],
|
|
246
|
+
"ISO27001": ["iso27001", "iso 27001"],
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
requirements = []
|
|
250
|
+
project_root = self.project_root
|
|
251
|
+
|
|
252
|
+
# Check for compliance files/directories
|
|
253
|
+
for compliance_name, patterns in compliance_patterns.items():
|
|
254
|
+
indicators = []
|
|
255
|
+
confidence = 0.0
|
|
256
|
+
|
|
257
|
+
# Check file/directory names
|
|
258
|
+
for pattern in patterns:
|
|
259
|
+
# Check exact file/directory names
|
|
260
|
+
if (project_root / pattern).exists():
|
|
261
|
+
confidence += 0.4
|
|
262
|
+
indicators.append(f"{pattern}_file_found")
|
|
263
|
+
|
|
264
|
+
# Check in file paths
|
|
265
|
+
matching_files = list(project_root.rglob(f"*{pattern}*"))
|
|
266
|
+
if matching_files:
|
|
267
|
+
confidence += 0.3
|
|
268
|
+
indicators.append(f"{pattern}_pattern_in_paths")
|
|
269
|
+
|
|
270
|
+
# Check in compliance directory
|
|
271
|
+
compliance_dir = project_root / "compliance"
|
|
272
|
+
if compliance_dir.exists():
|
|
273
|
+
# Check if compliance name appears in compliance directory
|
|
274
|
+
for pattern in patterns:
|
|
275
|
+
if any(
|
|
276
|
+
pattern in str(p).lower() for p in compliance_dir.rglob("*")
|
|
277
|
+
):
|
|
278
|
+
confidence += 0.3
|
|
279
|
+
indicators.append(f"{compliance_name}_in_compliance_dir")
|
|
280
|
+
break
|
|
281
|
+
|
|
282
|
+
# If we found indicators, add requirement
|
|
283
|
+
if confidence > 0.0:
|
|
284
|
+
requirements.append((compliance_name, min(0.9, confidence), indicators))
|
|
285
|
+
|
|
286
|
+
return requirements
|
|
287
|
+
|
|
288
|
+
def detect_security_level(self) -> tuple[str | None, float, list[str]]:
|
|
289
|
+
"""
|
|
290
|
+
Detect security level with confidence score.
|
|
291
|
+
|
|
292
|
+
Returns:
|
|
293
|
+
Tuple of (security_level, confidence, indicators)
|
|
294
|
+
security_level: "basic", "standard", "high", or "critical" (or None)
|
|
295
|
+
confidence: 0.0-1.0
|
|
296
|
+
indicators: List of indicator names that matched
|
|
297
|
+
"""
|
|
298
|
+
security_files = [
|
|
299
|
+
".security",
|
|
300
|
+
"security.md",
|
|
301
|
+
"SECURITY.md",
|
|
302
|
+
".bandit",
|
|
303
|
+
".safety",
|
|
304
|
+
".snyk",
|
|
305
|
+
"snyk.yml",
|
|
306
|
+
".dependabot",
|
|
307
|
+
"dependabot.yml",
|
|
308
|
+
]
|
|
309
|
+
|
|
310
|
+
indicators = []
|
|
311
|
+
found_files = []
|
|
312
|
+
|
|
313
|
+
for security_file in security_files:
|
|
314
|
+
if (self.project_root / security_file).exists():
|
|
315
|
+
found_files.append(security_file)
|
|
316
|
+
indicators.append(
|
|
317
|
+
f"has_{security_file.replace('.', '').replace('-', '_')}"
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
# Determine security level based on number of files
|
|
321
|
+
num_files = len(found_files)
|
|
322
|
+
|
|
323
|
+
if num_files >= 3:
|
|
324
|
+
return ("high", 0.8, indicators)
|
|
325
|
+
elif num_files == 2:
|
|
326
|
+
return ("standard", 0.7, indicators)
|
|
327
|
+
elif num_files == 1:
|
|
328
|
+
return ("standard", 0.6, indicators)
|
|
329
|
+
else:
|
|
330
|
+
return ("basic", 0.5, ["no_security_files"])
|
|
331
|
+
|
|
332
|
+
def detect_tenancy(self) -> tuple[str | None, float, list[str]]:
|
|
333
|
+
"""
|
|
334
|
+
Detect tenancy model (single-tenant vs multi-tenant) by grepping code.
|
|
335
|
+
|
|
336
|
+
Returns:
|
|
337
|
+
Tuple of (tenancy, confidence, indicators)
|
|
338
|
+
tenancy: "single-tenant" or "multi-tenant" (or None)
|
|
339
|
+
confidence: 0.0-1.0
|
|
340
|
+
indicators: List of indicator names that matched
|
|
341
|
+
"""
|
|
342
|
+
import re
|
|
343
|
+
|
|
344
|
+
indicators = []
|
|
345
|
+
tenant_patterns = [
|
|
346
|
+
r"\btenant_id\b",
|
|
347
|
+
r"\btenantId\b",
|
|
348
|
+
r"\btenant-id\b",
|
|
349
|
+
r"\btenant_uuid\b",
|
|
350
|
+
r"\btenant_context\b",
|
|
351
|
+
r"\bmulti_tenant\b",
|
|
352
|
+
r"\bmultiTenant\b",
|
|
353
|
+
]
|
|
354
|
+
|
|
355
|
+
# Search in common code files
|
|
356
|
+
code_extensions = {
|
|
357
|
+
".py",
|
|
358
|
+
".js",
|
|
359
|
+
".ts",
|
|
360
|
+
".java",
|
|
361
|
+
".go",
|
|
362
|
+
".rs",
|
|
363
|
+
".cpp",
|
|
364
|
+
".c",
|
|
365
|
+
".cs",
|
|
366
|
+
}
|
|
367
|
+
matching_files = set()
|
|
368
|
+
|
|
369
|
+
for ext in code_extensions:
|
|
370
|
+
for code_file in self.project_root.rglob(f"*{ext}"):
|
|
371
|
+
try:
|
|
372
|
+
# Skip very large files and binary-like files
|
|
373
|
+
if code_file.stat().st_size > 1_000_000: # 1MB limit
|
|
374
|
+
continue
|
|
375
|
+
|
|
376
|
+
content = code_file.read_text(encoding="utf-8", errors="ignore")
|
|
377
|
+
|
|
378
|
+
# Check for tenant patterns
|
|
379
|
+
for pattern in tenant_patterns:
|
|
380
|
+
if re.search(pattern, content, re.IGNORECASE):
|
|
381
|
+
matching_files.add(code_file)
|
|
382
|
+
indicators.append(f"tenant_pattern_in_{code_file.name}")
|
|
383
|
+
break # Count file once even if multiple patterns match
|
|
384
|
+
except (UnicodeDecodeError, PermissionError, OSError):
|
|
385
|
+
# Skip files that can't be read
|
|
386
|
+
continue
|
|
387
|
+
|
|
388
|
+
num_files = len(matching_files)
|
|
389
|
+
|
|
390
|
+
# Determine tenancy based on number of files with tenant patterns
|
|
391
|
+
if num_files > 3:
|
|
392
|
+
return ("multi-tenant", 0.8, indicators)
|
|
393
|
+
elif num_files >= 1:
|
|
394
|
+
return ("multi-tenant", 0.6, indicators) # Medium confidence, suggest
|
|
395
|
+
else:
|
|
396
|
+
# Conservative: default to single-tenant if no patterns found
|
|
397
|
+
return ("single-tenant", 0.7, ["no_tenant_patterns_found"])
|
|
398
|
+
|
|
399
|
+
def detect_user_scale(self) -> tuple[str | None, float, list[str]]:
|
|
400
|
+
"""
|
|
401
|
+
Detect expected user scale from infrastructure patterns.
|
|
402
|
+
|
|
403
|
+
Returns:
|
|
404
|
+
Tuple of (user_scale, confidence, indicators)
|
|
405
|
+
user_scale: "single-user", "small-team", "department", "enterprise" (or None)
|
|
406
|
+
confidence: 0.0-1.0
|
|
407
|
+
indicators: List of indicator names that matched
|
|
408
|
+
"""
|
|
409
|
+
indicators = []
|
|
410
|
+
scale_score = {
|
|
411
|
+
"single-user": 0.0,
|
|
412
|
+
"small-team": 0.0,
|
|
413
|
+
"department": 0.0,
|
|
414
|
+
"enterprise": 0.0,
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
# Enterprise indicators (high scale)
|
|
418
|
+
enterprise_checks = [
|
|
419
|
+
(
|
|
420
|
+
"has_load_balancer",
|
|
421
|
+
lambda p: any(
|
|
422
|
+
(p / f).exists()
|
|
423
|
+
for f in ["nginx.conf", "haproxy.cfg", "traefik.yml"]
|
|
424
|
+
),
|
|
425
|
+
),
|
|
426
|
+
(
|
|
427
|
+
"has_oauth",
|
|
428
|
+
lambda p: any(
|
|
429
|
+
"oauth" in str(f).lower() for f in p.rglob("*") if f.is_file()
|
|
430
|
+
),
|
|
431
|
+
),
|
|
432
|
+
(
|
|
433
|
+
"has_saml",
|
|
434
|
+
lambda p: any(
|
|
435
|
+
"saml" in str(f).lower() for f in p.rglob("*") if f.is_file()
|
|
436
|
+
),
|
|
437
|
+
),
|
|
438
|
+
(
|
|
439
|
+
"has_ldap",
|
|
440
|
+
lambda p: any(
|
|
441
|
+
"ldap" in str(f).lower() for f in p.rglob("*") if f.is_file()
|
|
442
|
+
),
|
|
443
|
+
),
|
|
444
|
+
(
|
|
445
|
+
"has_kubernetes",
|
|
446
|
+
lambda p: (p / "k8s").exists() or (p / "kubernetes").exists(),
|
|
447
|
+
),
|
|
448
|
+
(
|
|
449
|
+
"has_helm",
|
|
450
|
+
lambda p: (p / "helm").exists()
|
|
451
|
+
or any((p / f).exists() for f in ["Chart.yaml", "values.yaml"]),
|
|
452
|
+
),
|
|
453
|
+
]
|
|
454
|
+
|
|
455
|
+
for name, check in enterprise_checks:
|
|
456
|
+
if check(self.project_root):
|
|
457
|
+
scale_score["enterprise"] += 0.15
|
|
458
|
+
indicators.append(name)
|
|
459
|
+
|
|
460
|
+
# Department indicators (medium scale - caching, queues)
|
|
461
|
+
department_checks = [
|
|
462
|
+
(
|
|
463
|
+
"has_redis",
|
|
464
|
+
lambda p: any(
|
|
465
|
+
"redis" in str(f).lower() for f in p.rglob("*") if f.is_file()
|
|
466
|
+
)
|
|
467
|
+
or (p / "redis.conf").exists(),
|
|
468
|
+
),
|
|
469
|
+
(
|
|
470
|
+
"has_memcached",
|
|
471
|
+
lambda p: any(
|
|
472
|
+
"memcached" in str(f).lower() for f in p.rglob("*") if f.is_file()
|
|
473
|
+
),
|
|
474
|
+
),
|
|
475
|
+
(
|
|
476
|
+
"has_message_queue",
|
|
477
|
+
lambda p: any(
|
|
478
|
+
q in str(f).lower()
|
|
479
|
+
for q in ["rabbitmq", "kafka", "sqs"]
|
|
480
|
+
for f in p.rglob("*")
|
|
481
|
+
if f.is_file()
|
|
482
|
+
),
|
|
483
|
+
),
|
|
484
|
+
]
|
|
485
|
+
|
|
486
|
+
for name, check in department_checks:
|
|
487
|
+
if check(self.project_root):
|
|
488
|
+
scale_score["department"] += 0.2
|
|
489
|
+
indicators.append(name)
|
|
490
|
+
|
|
491
|
+
# Small team indicators (basic infrastructure)
|
|
492
|
+
small_team_checks = [
|
|
493
|
+
(
|
|
494
|
+
"has_docker",
|
|
495
|
+
lambda p: (p / "Dockerfile").exists()
|
|
496
|
+
or (p / "docker-compose.yml").exists(),
|
|
497
|
+
),
|
|
498
|
+
(
|
|
499
|
+
"has_database",
|
|
500
|
+
lambda p: any(
|
|
501
|
+
db in str(f).lower()
|
|
502
|
+
for db in ["postgres", "mysql", "sqlite"]
|
|
503
|
+
for f in p.rglob("*")
|
|
504
|
+
if f.is_file()
|
|
505
|
+
),
|
|
506
|
+
),
|
|
507
|
+
]
|
|
508
|
+
|
|
509
|
+
for name, check in small_team_checks:
|
|
510
|
+
if check(self.project_root):
|
|
511
|
+
scale_score["small-team"] += 0.3
|
|
512
|
+
indicators.append(name)
|
|
513
|
+
|
|
514
|
+
# Determine result
|
|
515
|
+
max_scale = max(scale_score.items(), key=lambda x: x[1])
|
|
516
|
+
max_scale_name, max_scale_score = max_scale
|
|
517
|
+
|
|
518
|
+
if max_scale_score >= 0.6:
|
|
519
|
+
confidence = min(0.8, max_scale_score)
|
|
520
|
+
return (max_scale_name, confidence, indicators)
|
|
521
|
+
elif max_scale_score >= 0.3:
|
|
522
|
+
confidence = min(0.6, max_scale_score)
|
|
523
|
+
return (
|
|
524
|
+
max_scale_name,
|
|
525
|
+
confidence,
|
|
526
|
+
indicators,
|
|
527
|
+
) # Medium confidence, suggest
|
|
528
|
+
else:
|
|
529
|
+
# Default to small-team with low confidence
|
|
530
|
+
return ("small-team", 0.5, indicators + ["default_small_team"])
|
|
531
|
+
|
|
532
|
+
def detect_from_context(
|
|
533
|
+
self,
|
|
534
|
+
user_query: str | None = None,
|
|
535
|
+
file_count: int | None = None,
|
|
536
|
+
scope_description: str | None = None,
|
|
537
|
+
) -> ProjectCharacteristics:
|
|
538
|
+
"""
|
|
539
|
+
Detect project type from user context (for fix-workflow selection).
|
|
540
|
+
|
|
541
|
+
Args:
|
|
542
|
+
user_query: User's query or request
|
|
543
|
+
file_count: Estimated number of files to change
|
|
544
|
+
scope_description: Description of the change scope
|
|
545
|
+
|
|
546
|
+
Returns:
|
|
547
|
+
ProjectCharacteristics with detection results
|
|
548
|
+
"""
|
|
549
|
+
indicators = {}
|
|
550
|
+
confidence = 0.0
|
|
551
|
+
recommendations = []
|
|
552
|
+
|
|
553
|
+
# Check for quick-fix keywords
|
|
554
|
+
quick_fix_score = 0.0
|
|
555
|
+
if user_query:
|
|
556
|
+
query_lower = user_query.lower()
|
|
557
|
+
for keyword in self.quick_fix_keywords:
|
|
558
|
+
if keyword in query_lower:
|
|
559
|
+
quick_fix_score += 0.2
|
|
560
|
+
indicators["quick_fix_keywords"] = quick_fix_score > 0
|
|
561
|
+
|
|
562
|
+
if scope_description:
|
|
563
|
+
desc_lower = scope_description.lower()
|
|
564
|
+
for keyword in self.quick_fix_keywords:
|
|
565
|
+
if keyword in desc_lower:
|
|
566
|
+
quick_fix_score += 0.2
|
|
567
|
+
|
|
568
|
+
# Check file scope
|
|
569
|
+
small_scope = file_count is not None and file_count < 5
|
|
570
|
+
if small_scope:
|
|
571
|
+
quick_fix_score += 0.4
|
|
572
|
+
indicators["small_scope"] = True
|
|
573
|
+
|
|
574
|
+
# Determine if quick-fix
|
|
575
|
+
if quick_fix_score >= 0.6:
|
|
576
|
+
confidence = min(0.9, quick_fix_score)
|
|
577
|
+
recommendations.append("Consider Quick Flow track for fast turnaround")
|
|
578
|
+
return ProjectCharacteristics(
|
|
579
|
+
project_type=ProjectType.QUICK_FIX,
|
|
580
|
+
workflow_track=WorkflowTrack.QUICK_FLOW,
|
|
581
|
+
confidence=confidence,
|
|
582
|
+
indicators=indicators,
|
|
583
|
+
recommendations=recommendations,
|
|
584
|
+
)
|
|
585
|
+
|
|
586
|
+
# Otherwise, use standard detection
|
|
587
|
+
return self.detect()
|
|
588
|
+
|
|
589
|
+
def detect(self) -> ProjectCharacteristics:
|
|
590
|
+
"""
|
|
591
|
+
Detect project type from file system analysis.
|
|
592
|
+
|
|
593
|
+
Returns:
|
|
594
|
+
ProjectCharacteristics with detection results
|
|
595
|
+
"""
|
|
596
|
+
indicators = {}
|
|
597
|
+
greenfield_score = 0.0
|
|
598
|
+
brownfield_score = 0.0
|
|
599
|
+
|
|
600
|
+
# Check greenfield indicators
|
|
601
|
+
for name, check in self.greenfield_indicators:
|
|
602
|
+
if check(self.project_root):
|
|
603
|
+
greenfield_score += 0.25
|
|
604
|
+
indicators[name] = True
|
|
605
|
+
else:
|
|
606
|
+
indicators[name] = False
|
|
607
|
+
|
|
608
|
+
# Check brownfield indicators
|
|
609
|
+
for name, check in self.brownfield_indicators:
|
|
610
|
+
if check(self.project_root):
|
|
611
|
+
brownfield_score += 0.15
|
|
612
|
+
indicators[name] = True
|
|
613
|
+
else:
|
|
614
|
+
indicators[name] = False
|
|
615
|
+
|
|
616
|
+
# Check for enterprise/complexity indicators first (before type determination)
|
|
617
|
+
complexity_score = 0.0
|
|
618
|
+
recommendations = [] # Initialize recommendations list
|
|
619
|
+
|
|
620
|
+
for name, check in self.complexity_indicators:
|
|
621
|
+
if check(self.project_root):
|
|
622
|
+
complexity_score += 0.25
|
|
623
|
+
indicators[name] = True
|
|
624
|
+
if name == "has_compliance":
|
|
625
|
+
recommendations.append(
|
|
626
|
+
"Compliance requirements detected - consider Enterprise track"
|
|
627
|
+
)
|
|
628
|
+
else:
|
|
629
|
+
indicators[name] = False
|
|
630
|
+
|
|
631
|
+
# Determine project type
|
|
632
|
+
# Prioritize brownfield if both greenfield and brownfield indicators present
|
|
633
|
+
if brownfield_score >= 0.45: # Lower threshold to prefer brownfield
|
|
634
|
+
project_type = ProjectType.BROWNFIELD
|
|
635
|
+
confidence = min(0.9, brownfield_score)
|
|
636
|
+
workflow_track = WorkflowTrack.BMAD_METHOD
|
|
637
|
+
if not recommendations:
|
|
638
|
+
recommendations = [
|
|
639
|
+
"Existing project detected - use BMad Method workflow",
|
|
640
|
+
"Leverage existing codebase structure and patterns",
|
|
641
|
+
]
|
|
642
|
+
elif greenfield_score >= 0.5:
|
|
643
|
+
project_type = ProjectType.GREENFIELD
|
|
644
|
+
confidence = min(0.9, greenfield_score)
|
|
645
|
+
workflow_track = WorkflowTrack.BMAD_METHOD
|
|
646
|
+
if not recommendations:
|
|
647
|
+
recommendations = [
|
|
648
|
+
"New project detected - use BMad Method workflow",
|
|
649
|
+
"Start with requirements gathering and architecture design",
|
|
650
|
+
]
|
|
651
|
+
else:
|
|
652
|
+
project_type = ProjectType.HYBRID
|
|
653
|
+
confidence = 0.5
|
|
654
|
+
workflow_track = WorkflowTrack.BMAD_METHOD
|
|
655
|
+
if not recommendations:
|
|
656
|
+
recommendations = [
|
|
657
|
+
"Mixed indicators detected - defaulting to BMad Method workflow",
|
|
658
|
+
"Review workflow steps and customize as needed",
|
|
659
|
+
]
|
|
660
|
+
|
|
661
|
+
# Upgrade to Enterprise track if complexity is high
|
|
662
|
+
if (
|
|
663
|
+
complexity_score >= 0.25
|
|
664
|
+
): # Lower threshold - any compliance/complexity indicator
|
|
665
|
+
workflow_track = WorkflowTrack.ENTERPRISE
|
|
666
|
+
if not any("Complex project detected" in rec for rec in recommendations):
|
|
667
|
+
recommendations.append(
|
|
668
|
+
"Complex project detected - Enterprise workflow recommended"
|
|
669
|
+
)
|
|
670
|
+
confidence = min(0.95, confidence + 0.1)
|
|
671
|
+
|
|
672
|
+
return ProjectCharacteristics(
|
|
673
|
+
project_type=project_type,
|
|
674
|
+
workflow_track=workflow_track,
|
|
675
|
+
confidence=confidence,
|
|
676
|
+
indicators=indicators,
|
|
677
|
+
recommendations=recommendations,
|
|
678
|
+
)
|
|
679
|
+
|
|
680
|
+
def get_recommended_workflow(
|
|
681
|
+
self, characteristics: ProjectCharacteristics
|
|
682
|
+
) -> str | None:
|
|
683
|
+
"""
|
|
684
|
+
Get recommended workflow preset name based on characteristics.
|
|
685
|
+
|
|
686
|
+
Returns canonical preset IDs: full-sdlc, rapid-dev, fix, quality, brownfield-analysis.
|
|
687
|
+
"""
|
|
688
|
+
if characteristics.workflow_track == WorkflowTrack.QUICK_FLOW:
|
|
689
|
+
return "fix"
|
|
690
|
+
elif characteristics.workflow_track == WorkflowTrack.ENTERPRISE:
|
|
691
|
+
return "full-sdlc"
|
|
692
|
+
else: # BMAD_METHOD
|
|
693
|
+
if characteristics.project_type == ProjectType.GREENFIELD:
|
|
694
|
+
return "rapid-dev"
|
|
695
|
+
elif characteristics.project_type == ProjectType.BROWNFIELD:
|
|
696
|
+
return "brownfield-analysis"
|
|
697
|
+
else:
|
|
698
|
+
return "rapid-dev" # Default (was feature-development)
|
|
699
|
+
|
|
700
|
+
def detect_command_suggestions(self, context: dict[str, Any]) -> list[dict[str, Any]]:
|
|
701
|
+
"""
|
|
702
|
+
Detect when to suggest Epic, coverage, microservice, or Docker commands.
|
|
703
|
+
|
|
704
|
+
Args:
|
|
705
|
+
context: User action context (files, actions, errors, etc.)
|
|
706
|
+
|
|
707
|
+
Returns:
|
|
708
|
+
List of command suggestions
|
|
709
|
+
"""
|
|
710
|
+
suggestions = []
|
|
711
|
+
|
|
712
|
+
# Detect Epic document mentions
|
|
713
|
+
if context.get("files"):
|
|
714
|
+
for file_path in context["files"]:
|
|
715
|
+
if "epic" in str(file_path).lower() and file_path.endswith(".md"):
|
|
716
|
+
suggestions.append({
|
|
717
|
+
"command": f"@simple-mode *epic {file_path}",
|
|
718
|
+
"description": "Execute Epic workflow for this document",
|
|
719
|
+
"confidence": 0.9,
|
|
720
|
+
"type": "epic",
|
|
721
|
+
})
|
|
722
|
+
|
|
723
|
+
# Detect test coverage gaps
|
|
724
|
+
if context.get("action") == "checking_coverage" or "coverage.json" in str(context.get("files", [])):
|
|
725
|
+
suggestions.append({
|
|
726
|
+
"command": "@simple-mode *test-coverage <file> --target 80",
|
|
727
|
+
"description": "Generate tests to improve coverage",
|
|
728
|
+
"confidence": 0.85,
|
|
729
|
+
"type": "coverage",
|
|
730
|
+
})
|
|
731
|
+
|
|
732
|
+
# Detect microservice creation
|
|
733
|
+
if context.get("action") == "creating_service" or "services/" in str(context.get("files", [])):
|
|
734
|
+
suggestions.append({
|
|
735
|
+
"command": "@simple-mode *microservice <name> --port <port> --type fastapi",
|
|
736
|
+
"description": "Generate microservice structure automatically",
|
|
737
|
+
"confidence": 0.8,
|
|
738
|
+
"type": "microservice",
|
|
739
|
+
})
|
|
740
|
+
|
|
741
|
+
# Detect Docker errors
|
|
742
|
+
if context.get("error"):
|
|
743
|
+
error_msg = str(context["error"])
|
|
744
|
+
if any(keyword in error_msg.lower() for keyword in ["docker", "container", "module not found", "workdir"]):
|
|
745
|
+
suggestions.append({
|
|
746
|
+
"command": "@simple-mode *docker-fix <service> \"<error>\"",
|
|
747
|
+
"description": "Debug and fix Docker/container issues",
|
|
748
|
+
"confidence": 0.9,
|
|
749
|
+
"type": "docker",
|
|
750
|
+
})
|
|
751
|
+
|
|
752
752
|
return suggestions
|