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,410 +1,410 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Story Evaluator - Quality scoring and validation for user stories.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import logging
|
|
6
|
-
import re
|
|
7
|
-
from dataclasses import dataclass, field
|
|
8
|
-
from typing import Any
|
|
9
|
-
|
|
10
|
-
logger = logging.getLogger(__name__)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@dataclass
|
|
14
|
-
class StoryQualityScore:
|
|
15
|
-
"""User story quality score breakdown (INVEST criteria)."""
|
|
16
|
-
|
|
17
|
-
independent: float = 0.0 # 0-100: Can story be developed independently?
|
|
18
|
-
negotiable: float = 0.0 # 0-100: Is story open to discussion?
|
|
19
|
-
valuable: float = 0.0 # 0-100: Does story deliver value?
|
|
20
|
-
estimable: float = 0.0 # 0-100: Can story be estimated?
|
|
21
|
-
small: float = 0.0 # 0-100: Is story appropriately sized?
|
|
22
|
-
testable: float = 0.0 # 0-100: Can story be tested?
|
|
23
|
-
overall: float = 0.0 # Weighted average
|
|
24
|
-
|
|
25
|
-
issues: list[str] = field(default_factory=list)
|
|
26
|
-
strengths: list[str] = field(default_factory=list)
|
|
27
|
-
recommendations: list[str] = field(default_factory=list)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
@dataclass
|
|
31
|
-
class StoryValidationResult:
|
|
32
|
-
"""Result of story validation."""
|
|
33
|
-
|
|
34
|
-
is_valid: bool
|
|
35
|
-
score: StoryQualityScore
|
|
36
|
-
missing_elements: list[str] = field(default_factory=list)
|
|
37
|
-
weak_acceptance_criteria: list[str] = field(default_factory=list)
|
|
38
|
-
dependency_issues: list[str] = field(default_factory=list)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
class StoryEvaluator:
|
|
42
|
-
"""Evaluates user story quality using INVEST criteria."""
|
|
43
|
-
|
|
44
|
-
# INVEST weights (equal weighting)
|
|
45
|
-
INDEPENDENT_WEIGHT = 1.0 / 6.0
|
|
46
|
-
NEGOTIABLE_WEIGHT = 1.0 / 6.0
|
|
47
|
-
VALUABLE_WEIGHT = 1.0 / 6.0
|
|
48
|
-
ESTIMABLE_WEIGHT = 1.0 / 6.0
|
|
49
|
-
SMALL_WEIGHT = 1.0 / 6.0
|
|
50
|
-
TESTABLE_WEIGHT = 1.0 / 6.0
|
|
51
|
-
|
|
52
|
-
EXCELLENT_THRESHOLD = 80.0
|
|
53
|
-
GOOD_THRESHOLD = 70.0
|
|
54
|
-
ACCEPTABLE_THRESHOLD = 60.0
|
|
55
|
-
|
|
56
|
-
def evaluate(self, story: dict[str, Any]) -> StoryQualityScore:
|
|
57
|
-
"""
|
|
58
|
-
Evaluate story quality using INVEST criteria.
|
|
59
|
-
|
|
60
|
-
Args:
|
|
61
|
-
story: Story dict with structure:
|
|
62
|
-
- title: str
|
|
63
|
-
- description: str (As a... I want... So that...)
|
|
64
|
-
- acceptance_criteria: list[str]
|
|
65
|
-
- story_points: int (optional)
|
|
66
|
-
- dependencies: list[str] (optional)
|
|
67
|
-
- priority: str (optional)
|
|
68
|
-
|
|
69
|
-
Returns:
|
|
70
|
-
StoryQualityScore with detailed breakdown
|
|
71
|
-
"""
|
|
72
|
-
score = StoryQualityScore()
|
|
73
|
-
|
|
74
|
-
score.independent = self._evaluate_independent(story)
|
|
75
|
-
score.negotiable = self._evaluate_negotiable(story)
|
|
76
|
-
score.valuable = self._evaluate_valuable(story)
|
|
77
|
-
score.estimable = self._evaluate_estimable(story)
|
|
78
|
-
score.small = self._evaluate_small(story)
|
|
79
|
-
score.testable = self._evaluate_testable(story)
|
|
80
|
-
|
|
81
|
-
# Calculate weighted overall score
|
|
82
|
-
score.overall = (
|
|
83
|
-
score.independent * self.INDEPENDENT_WEIGHT
|
|
84
|
-
+ score.negotiable * self.NEGOTIABLE_WEIGHT
|
|
85
|
-
+ score.valuable * self.VALUABLE_WEIGHT
|
|
86
|
-
+ score.estimable * self.ESTIMABLE_WEIGHT
|
|
87
|
-
+ score.small * self.SMALL_WEIGHT
|
|
88
|
-
+ score.testable * self.TESTABLE_WEIGHT
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
# Generate feedback
|
|
92
|
-
score.issues = self._identify_issues(story, score)
|
|
93
|
-
score.strengths = self._identify_strengths(story, score)
|
|
94
|
-
score.recommendations = self._generate_recommendations(score)
|
|
95
|
-
|
|
96
|
-
return score
|
|
97
|
-
|
|
98
|
-
def validate(self, story: dict[str, Any]) -> StoryValidationResult:
|
|
99
|
-
"""
|
|
100
|
-
Validate story for completeness and quality.
|
|
101
|
-
|
|
102
|
-
Args:
|
|
103
|
-
story: Story dict
|
|
104
|
-
|
|
105
|
-
Returns:
|
|
106
|
-
StoryValidationResult with validation status
|
|
107
|
-
"""
|
|
108
|
-
score = self.evaluate(story)
|
|
109
|
-
|
|
110
|
-
missing_elements = []
|
|
111
|
-
weak_acceptance = []
|
|
112
|
-
dependency_issues = []
|
|
113
|
-
|
|
114
|
-
# Check for required elements
|
|
115
|
-
if not story.get("title"):
|
|
116
|
-
missing_elements.append("Title")
|
|
117
|
-
if not story.get("description"):
|
|
118
|
-
missing_elements.append("Description")
|
|
119
|
-
if not story.get("acceptance_criteria"):
|
|
120
|
-
missing_elements.append("Acceptance criteria")
|
|
121
|
-
|
|
122
|
-
# Check acceptance criteria quality
|
|
123
|
-
acceptance = story.get("acceptance_criteria", [])
|
|
124
|
-
for criterion in acceptance:
|
|
125
|
-
if isinstance(criterion, str):
|
|
126
|
-
if len(criterion) < 20: # Too short
|
|
127
|
-
weak_acceptance.append(criterion[:50])
|
|
128
|
-
if not self._is_testable_criterion(criterion):
|
|
129
|
-
weak_acceptance.append(criterion[:50])
|
|
130
|
-
|
|
131
|
-
# Check for dependency issues
|
|
132
|
-
dependencies = story.get("dependencies", [])
|
|
133
|
-
if len(dependencies) > 3:
|
|
134
|
-
dependency_issues.append(f"Too many dependencies ({len(dependencies)}) - may not be independent")
|
|
135
|
-
|
|
136
|
-
is_valid = (
|
|
137
|
-
score.overall >= self.ACCEPTABLE_THRESHOLD
|
|
138
|
-
and len(missing_elements) == 0
|
|
139
|
-
and score.testable >= 60.0
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
return StoryValidationResult(
|
|
143
|
-
is_valid=is_valid,
|
|
144
|
-
score=score,
|
|
145
|
-
missing_elements=missing_elements,
|
|
146
|
-
weak_acceptance_criteria=weak_acceptance,
|
|
147
|
-
dependency_issues=dependency_issues,
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
def _evaluate_independent(self, story: dict[str, Any]) -> float:
|
|
151
|
-
"""Evaluate if story is independent (0-100)."""
|
|
152
|
-
score = 100.0
|
|
153
|
-
|
|
154
|
-
# Check for dependencies
|
|
155
|
-
dependencies = story.get("dependencies", [])
|
|
156
|
-
if dependencies:
|
|
157
|
-
# Few dependencies = minor deduction
|
|
158
|
-
if len(dependencies) <= 2:
|
|
159
|
-
score -= 20.0
|
|
160
|
-
# Many dependencies = major deduction
|
|
161
|
-
else:
|
|
162
|
-
score -= 50.0
|
|
163
|
-
|
|
164
|
-
# Check if story description mentions other stories
|
|
165
|
-
description = story.get("description", "").lower()
|
|
166
|
-
if "after story" in description or "depends on" in description:
|
|
167
|
-
score -= 30.0
|
|
168
|
-
|
|
169
|
-
return max(0.0, score)
|
|
170
|
-
|
|
171
|
-
def _evaluate_negotiable(self, story: dict[str, Any]) -> float:
|
|
172
|
-
"""Evaluate if story is negotiable (0-100)."""
|
|
173
|
-
score = 80.0 # Default: stories are generally negotiable
|
|
174
|
-
|
|
175
|
-
description = story.get("description", "").lower()
|
|
176
|
-
title = story.get("title", "").lower()
|
|
177
|
-
|
|
178
|
-
# Check for overly prescriptive language
|
|
179
|
-
prescriptive = ["must", "shall", "exactly", "precisely", "only"]
|
|
180
|
-
prescriptive_count = sum(1 for word in prescriptive if word in description or word in title)
|
|
181
|
-
|
|
182
|
-
if prescriptive_count > 3:
|
|
183
|
-
score -= 30.0
|
|
184
|
-
elif prescriptive_count > 1:
|
|
185
|
-
score -= 15.0
|
|
186
|
-
|
|
187
|
-
# Check for implementation details (should be negotiable)
|
|
188
|
-
tech_details = ["using", "with", "via", "through"]
|
|
189
|
-
if any(word in description for word in tech_details):
|
|
190
|
-
# Some tech details OK, but too many reduce negotiability
|
|
191
|
-
tech_count = sum(1 for word in tech_details if word in description)
|
|
192
|
-
if tech_count > 2:
|
|
193
|
-
score -= 20.0
|
|
194
|
-
|
|
195
|
-
return max(0.0, score)
|
|
196
|
-
|
|
197
|
-
def _evaluate_valuable(self, story: dict[str, Any]) -> float:
|
|
198
|
-
"""Evaluate if story delivers value (0-100)."""
|
|
199
|
-
score = 0.0
|
|
200
|
-
|
|
201
|
-
description = story.get("description", "")
|
|
202
|
-
if not description:
|
|
203
|
-
return 0.0
|
|
204
|
-
|
|
205
|
-
# Check for "So that..." clause (value statement)
|
|
206
|
-
if "so that" in description.lower():
|
|
207
|
-
score += 50.0
|
|
208
|
-
# Check if value is clear
|
|
209
|
-
so_that_part = description.lower().split("so that")[-1] if "so that" in description.lower() else ""
|
|
210
|
-
if len(so_that_part.strip()) > 20:
|
|
211
|
-
score += 30.0
|
|
212
|
-
|
|
213
|
-
# Check for user role (As a...)
|
|
214
|
-
if re.search(r"as a\s+\w+", description.lower()):
|
|
215
|
-
score += 20.0
|
|
216
|
-
|
|
217
|
-
# Check for business value indicators
|
|
218
|
-
value_words = ["improve", "enable", "allow", "provide", "increase", "reduce", "save"]
|
|
219
|
-
if any(word in description.lower() for word in value_words):
|
|
220
|
-
score += 10.0
|
|
221
|
-
|
|
222
|
-
return min(100.0, score)
|
|
223
|
-
|
|
224
|
-
def _evaluate_estimable(self, story: dict[str, Any]) -> float:
|
|
225
|
-
"""Evaluate if story can be estimated (0-100)."""
|
|
226
|
-
score = 0.0
|
|
227
|
-
|
|
228
|
-
# Has story points = estimable
|
|
229
|
-
if story.get("story_points"):
|
|
230
|
-
score += 60.0
|
|
231
|
-
# Story points in reasonable range (1-13)
|
|
232
|
-
points = story.get("story_points", 0)
|
|
233
|
-
if 1 <= points <= 13:
|
|
234
|
-
score += 20.0
|
|
235
|
-
elif points > 13:
|
|
236
|
-
score -= 20.0 # Too large to estimate accurately
|
|
237
|
-
|
|
238
|
-
# Has acceptance criteria = more estimable
|
|
239
|
-
acceptance = story.get("acceptance_criteria", [])
|
|
240
|
-
if acceptance:
|
|
241
|
-
score += 20.0
|
|
242
|
-
if len(acceptance) >= 3:
|
|
243
|
-
score += 10.0
|
|
244
|
-
|
|
245
|
-
# Clear description helps estimation
|
|
246
|
-
description = story.get("description", "")
|
|
247
|
-
if description and len(description) > 50:
|
|
248
|
-
score += 10.0
|
|
249
|
-
|
|
250
|
-
return min(100.0, score)
|
|
251
|
-
|
|
252
|
-
def _evaluate_small(self, story: dict[str, Any]) -> float:
|
|
253
|
-
"""Evaluate if story is appropriately sized (0-100)."""
|
|
254
|
-
score = 100.0
|
|
255
|
-
|
|
256
|
-
# Check story points
|
|
257
|
-
points = story.get("story_points", 0)
|
|
258
|
-
if points > 8:
|
|
259
|
-
score -= 40.0 # Too large
|
|
260
|
-
elif points > 5:
|
|
261
|
-
score -= 20.0 # Large but acceptable
|
|
262
|
-
|
|
263
|
-
# Check acceptance criteria count
|
|
264
|
-
acceptance = story.get("acceptance_criteria", [])
|
|
265
|
-
if len(acceptance) > 7:
|
|
266
|
-
score -= 30.0 # Too many acceptance criteria = too large
|
|
267
|
-
elif len(acceptance) > 5:
|
|
268
|
-
score -= 15.0
|
|
269
|
-
|
|
270
|
-
# Check description length (very long = might be too large)
|
|
271
|
-
description = story.get("description", "")
|
|
272
|
-
if len(description) > 500:
|
|
273
|
-
score -= 20.0
|
|
274
|
-
|
|
275
|
-
return max(0.0, score)
|
|
276
|
-
|
|
277
|
-
def _evaluate_testable(self, story: dict[str, Any]) -> float:
|
|
278
|
-
"""Evaluate if story is testable (0-100)."""
|
|
279
|
-
score = 0.0
|
|
280
|
-
|
|
281
|
-
# Has acceptance criteria = testable
|
|
282
|
-
acceptance = story.get("acceptance_criteria", [])
|
|
283
|
-
if acceptance:
|
|
284
|
-
score += 50.0
|
|
285
|
-
|
|
286
|
-
# Check quality of acceptance criteria
|
|
287
|
-
testable_count = 0
|
|
288
|
-
for criterion in acceptance:
|
|
289
|
-
if isinstance(criterion, str):
|
|
290
|
-
if self._is_testable_criterion(criterion):
|
|
291
|
-
testable_count += 1
|
|
292
|
-
|
|
293
|
-
if testable_count > 0:
|
|
294
|
-
testable_ratio = testable_count / len(acceptance)
|
|
295
|
-
score += testable_ratio * 50.0
|
|
296
|
-
else:
|
|
297
|
-
# No acceptance criteria = not testable
|
|
298
|
-
return 0.0
|
|
299
|
-
|
|
300
|
-
# Clear description helps testability
|
|
301
|
-
description = story.get("description", "")
|
|
302
|
-
if description and "as a" in description.lower() and "i want" in description.lower():
|
|
303
|
-
score += 20.0
|
|
304
|
-
|
|
305
|
-
return min(100.0, score)
|
|
306
|
-
|
|
307
|
-
def _is_testable_criterion(self, criterion: str) -> bool:
|
|
308
|
-
"""Check if acceptance criterion is testable."""
|
|
309
|
-
criterion_lower = criterion.lower()
|
|
310
|
-
|
|
311
|
-
# Testable criteria have:
|
|
312
|
-
# - Specific conditions
|
|
313
|
-
# - Observable outcomes
|
|
314
|
-
# - Measurable results
|
|
315
|
-
|
|
316
|
-
testable_indicators = [
|
|
317
|
-
"when",
|
|
318
|
-
"then",
|
|
319
|
-
"should",
|
|
320
|
-
"must",
|
|
321
|
-
"will",
|
|
322
|
-
"displays",
|
|
323
|
-
"shows",
|
|
324
|
-
"returns",
|
|
325
|
-
"validates",
|
|
326
|
-
"verifies",
|
|
327
|
-
"checks",
|
|
328
|
-
]
|
|
329
|
-
|
|
330
|
-
has_indicator = any(indicator in criterion_lower for indicator in testable_indicators)
|
|
331
|
-
|
|
332
|
-
# Check for measurable outcomes
|
|
333
|
-
measurable = any(
|
|
334
|
-
word in criterion_lower
|
|
335
|
-
for word in ["seconds", "milliseconds", "users", "requests", "percentage", "%", "times"]
|
|
336
|
-
)
|
|
337
|
-
|
|
338
|
-
return has_indicator or measurable or len(criterion) > 30 # Longer = more likely testable
|
|
339
|
-
|
|
340
|
-
def _identify_issues(self, story: dict[str, Any], score: StoryQualityScore) -> list[str]:
|
|
341
|
-
"""Identify issues in story."""
|
|
342
|
-
issues = []
|
|
343
|
-
|
|
344
|
-
if score.independent < 60.0:
|
|
345
|
-
issues.append("Story has too many dependencies - not independent")
|
|
346
|
-
|
|
347
|
-
if score.valuable < 60.0:
|
|
348
|
-
issues.append("Story value is unclear - missing 'So that...' clause")
|
|
349
|
-
|
|
350
|
-
if score.estimable < 60.0:
|
|
351
|
-
issues.append("Story cannot be estimated - missing story points or details")
|
|
352
|
-
|
|
353
|
-
if score.small < 60.0:
|
|
354
|
-
issues.append("Story is too large - consider breaking down")
|
|
355
|
-
|
|
356
|
-
if score.testable < 60.0:
|
|
357
|
-
issues.append("Story is not testable - missing or weak acceptance criteria")
|
|
358
|
-
|
|
359
|
-
acceptance = story.get("acceptance_criteria", [])
|
|
360
|
-
if len(acceptance) < 2:
|
|
361
|
-
issues.append("Story has insufficient acceptance criteria")
|
|
362
|
-
|
|
363
|
-
return issues
|
|
364
|
-
|
|
365
|
-
def _identify_strengths(self, story: dict[str, Any], score: StoryQualityScore) -> list[str]:
|
|
366
|
-
"""Identify strengths in story."""
|
|
367
|
-
strengths = []
|
|
368
|
-
|
|
369
|
-
if score.independent >= 80.0:
|
|
370
|
-
strengths.append("Story is independent - can be developed standalone")
|
|
371
|
-
|
|
372
|
-
if score.valuable >= 80.0:
|
|
373
|
-
strengths.append("Clear value proposition")
|
|
374
|
-
|
|
375
|
-
if score.estimable >= 80.0:
|
|
376
|
-
strengths.append("Well-estimated with story points")
|
|
377
|
-
|
|
378
|
-
if score.small >= 80.0:
|
|
379
|
-
strengths.append("Appropriately sized")
|
|
380
|
-
|
|
381
|
-
if score.testable >= 80.0:
|
|
382
|
-
strengths.append("Well-defined acceptance criteria")
|
|
383
|
-
|
|
384
|
-
acceptance = story.get("acceptance_criteria", [])
|
|
385
|
-
if len(acceptance) >= 3:
|
|
386
|
-
strengths.append("Comprehensive acceptance criteria")
|
|
387
|
-
|
|
388
|
-
return strengths
|
|
389
|
-
|
|
390
|
-
def _generate_recommendations(self, score: StoryQualityScore) -> list[str]:
|
|
391
|
-
"""Generate improvement recommendations."""
|
|
392
|
-
recommendations = []
|
|
393
|
-
|
|
394
|
-
if score.independent < 70.0:
|
|
395
|
-
recommendations.append("Reduce dependencies or split into multiple stories")
|
|
396
|
-
|
|
397
|
-
if score.valuable < 70.0:
|
|
398
|
-
recommendations.append("Add 'So that...' clause to clarify value")
|
|
399
|
-
|
|
400
|
-
if score.estimable < 70.0:
|
|
401
|
-
recommendations.append("Add story points and more detailed description")
|
|
402
|
-
|
|
403
|
-
if score.small < 70.0:
|
|
404
|
-
recommendations.append("Break story into smaller stories")
|
|
405
|
-
|
|
406
|
-
if score.testable < 70.0:
|
|
407
|
-
recommendations.append("Add more detailed, testable acceptance criteria")
|
|
408
|
-
recommendations.append("Use Given-When-Then format for acceptance criteria")
|
|
409
|
-
|
|
410
|
-
return recommendations
|
|
1
|
+
"""
|
|
2
|
+
Story Evaluator - Quality scoring and validation for user stories.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import re
|
|
7
|
+
from dataclasses import dataclass, field
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class StoryQualityScore:
|
|
15
|
+
"""User story quality score breakdown (INVEST criteria)."""
|
|
16
|
+
|
|
17
|
+
independent: float = 0.0 # 0-100: Can story be developed independently?
|
|
18
|
+
negotiable: float = 0.0 # 0-100: Is story open to discussion?
|
|
19
|
+
valuable: float = 0.0 # 0-100: Does story deliver value?
|
|
20
|
+
estimable: float = 0.0 # 0-100: Can story be estimated?
|
|
21
|
+
small: float = 0.0 # 0-100: Is story appropriately sized?
|
|
22
|
+
testable: float = 0.0 # 0-100: Can story be tested?
|
|
23
|
+
overall: float = 0.0 # Weighted average
|
|
24
|
+
|
|
25
|
+
issues: list[str] = field(default_factory=list)
|
|
26
|
+
strengths: list[str] = field(default_factory=list)
|
|
27
|
+
recommendations: list[str] = field(default_factory=list)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class StoryValidationResult:
|
|
32
|
+
"""Result of story validation."""
|
|
33
|
+
|
|
34
|
+
is_valid: bool
|
|
35
|
+
score: StoryQualityScore
|
|
36
|
+
missing_elements: list[str] = field(default_factory=list)
|
|
37
|
+
weak_acceptance_criteria: list[str] = field(default_factory=list)
|
|
38
|
+
dependency_issues: list[str] = field(default_factory=list)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class StoryEvaluator:
|
|
42
|
+
"""Evaluates user story quality using INVEST criteria."""
|
|
43
|
+
|
|
44
|
+
# INVEST weights (equal weighting)
|
|
45
|
+
INDEPENDENT_WEIGHT = 1.0 / 6.0
|
|
46
|
+
NEGOTIABLE_WEIGHT = 1.0 / 6.0
|
|
47
|
+
VALUABLE_WEIGHT = 1.0 / 6.0
|
|
48
|
+
ESTIMABLE_WEIGHT = 1.0 / 6.0
|
|
49
|
+
SMALL_WEIGHT = 1.0 / 6.0
|
|
50
|
+
TESTABLE_WEIGHT = 1.0 / 6.0
|
|
51
|
+
|
|
52
|
+
EXCELLENT_THRESHOLD = 80.0
|
|
53
|
+
GOOD_THRESHOLD = 70.0
|
|
54
|
+
ACCEPTABLE_THRESHOLD = 60.0
|
|
55
|
+
|
|
56
|
+
def evaluate(self, story: dict[str, Any]) -> StoryQualityScore:
|
|
57
|
+
"""
|
|
58
|
+
Evaluate story quality using INVEST criteria.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
story: Story dict with structure:
|
|
62
|
+
- title: str
|
|
63
|
+
- description: str (As a... I want... So that...)
|
|
64
|
+
- acceptance_criteria: list[str]
|
|
65
|
+
- story_points: int (optional)
|
|
66
|
+
- dependencies: list[str] (optional)
|
|
67
|
+
- priority: str (optional)
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
StoryQualityScore with detailed breakdown
|
|
71
|
+
"""
|
|
72
|
+
score = StoryQualityScore()
|
|
73
|
+
|
|
74
|
+
score.independent = self._evaluate_independent(story)
|
|
75
|
+
score.negotiable = self._evaluate_negotiable(story)
|
|
76
|
+
score.valuable = self._evaluate_valuable(story)
|
|
77
|
+
score.estimable = self._evaluate_estimable(story)
|
|
78
|
+
score.small = self._evaluate_small(story)
|
|
79
|
+
score.testable = self._evaluate_testable(story)
|
|
80
|
+
|
|
81
|
+
# Calculate weighted overall score
|
|
82
|
+
score.overall = (
|
|
83
|
+
score.independent * self.INDEPENDENT_WEIGHT
|
|
84
|
+
+ score.negotiable * self.NEGOTIABLE_WEIGHT
|
|
85
|
+
+ score.valuable * self.VALUABLE_WEIGHT
|
|
86
|
+
+ score.estimable * self.ESTIMABLE_WEIGHT
|
|
87
|
+
+ score.small * self.SMALL_WEIGHT
|
|
88
|
+
+ score.testable * self.TESTABLE_WEIGHT
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# Generate feedback
|
|
92
|
+
score.issues = self._identify_issues(story, score)
|
|
93
|
+
score.strengths = self._identify_strengths(story, score)
|
|
94
|
+
score.recommendations = self._generate_recommendations(score)
|
|
95
|
+
|
|
96
|
+
return score
|
|
97
|
+
|
|
98
|
+
def validate(self, story: dict[str, Any]) -> StoryValidationResult:
|
|
99
|
+
"""
|
|
100
|
+
Validate story for completeness and quality.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
story: Story dict
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
StoryValidationResult with validation status
|
|
107
|
+
"""
|
|
108
|
+
score = self.evaluate(story)
|
|
109
|
+
|
|
110
|
+
missing_elements = []
|
|
111
|
+
weak_acceptance = []
|
|
112
|
+
dependency_issues = []
|
|
113
|
+
|
|
114
|
+
# Check for required elements
|
|
115
|
+
if not story.get("title"):
|
|
116
|
+
missing_elements.append("Title")
|
|
117
|
+
if not story.get("description"):
|
|
118
|
+
missing_elements.append("Description")
|
|
119
|
+
if not story.get("acceptance_criteria"):
|
|
120
|
+
missing_elements.append("Acceptance criteria")
|
|
121
|
+
|
|
122
|
+
# Check acceptance criteria quality
|
|
123
|
+
acceptance = story.get("acceptance_criteria", [])
|
|
124
|
+
for criterion in acceptance:
|
|
125
|
+
if isinstance(criterion, str):
|
|
126
|
+
if len(criterion) < 20: # Too short
|
|
127
|
+
weak_acceptance.append(criterion[:50])
|
|
128
|
+
if not self._is_testable_criterion(criterion):
|
|
129
|
+
weak_acceptance.append(criterion[:50])
|
|
130
|
+
|
|
131
|
+
# Check for dependency issues
|
|
132
|
+
dependencies = story.get("dependencies", [])
|
|
133
|
+
if len(dependencies) > 3:
|
|
134
|
+
dependency_issues.append(f"Too many dependencies ({len(dependencies)}) - may not be independent")
|
|
135
|
+
|
|
136
|
+
is_valid = (
|
|
137
|
+
score.overall >= self.ACCEPTABLE_THRESHOLD
|
|
138
|
+
and len(missing_elements) == 0
|
|
139
|
+
and score.testable >= 60.0
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
return StoryValidationResult(
|
|
143
|
+
is_valid=is_valid,
|
|
144
|
+
score=score,
|
|
145
|
+
missing_elements=missing_elements,
|
|
146
|
+
weak_acceptance_criteria=weak_acceptance,
|
|
147
|
+
dependency_issues=dependency_issues,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
def _evaluate_independent(self, story: dict[str, Any]) -> float:
|
|
151
|
+
"""Evaluate if story is independent (0-100)."""
|
|
152
|
+
score = 100.0
|
|
153
|
+
|
|
154
|
+
# Check for dependencies
|
|
155
|
+
dependencies = story.get("dependencies", [])
|
|
156
|
+
if dependencies:
|
|
157
|
+
# Few dependencies = minor deduction
|
|
158
|
+
if len(dependencies) <= 2:
|
|
159
|
+
score -= 20.0
|
|
160
|
+
# Many dependencies = major deduction
|
|
161
|
+
else:
|
|
162
|
+
score -= 50.0
|
|
163
|
+
|
|
164
|
+
# Check if story description mentions other stories
|
|
165
|
+
description = story.get("description", "").lower()
|
|
166
|
+
if "after story" in description or "depends on" in description:
|
|
167
|
+
score -= 30.0
|
|
168
|
+
|
|
169
|
+
return max(0.0, score)
|
|
170
|
+
|
|
171
|
+
def _evaluate_negotiable(self, story: dict[str, Any]) -> float:
|
|
172
|
+
"""Evaluate if story is negotiable (0-100)."""
|
|
173
|
+
score = 80.0 # Default: stories are generally negotiable
|
|
174
|
+
|
|
175
|
+
description = story.get("description", "").lower()
|
|
176
|
+
title = story.get("title", "").lower()
|
|
177
|
+
|
|
178
|
+
# Check for overly prescriptive language
|
|
179
|
+
prescriptive = ["must", "shall", "exactly", "precisely", "only"]
|
|
180
|
+
prescriptive_count = sum(1 for word in prescriptive if word in description or word in title)
|
|
181
|
+
|
|
182
|
+
if prescriptive_count > 3:
|
|
183
|
+
score -= 30.0
|
|
184
|
+
elif prescriptive_count > 1:
|
|
185
|
+
score -= 15.0
|
|
186
|
+
|
|
187
|
+
# Check for implementation details (should be negotiable)
|
|
188
|
+
tech_details = ["using", "with", "via", "through"]
|
|
189
|
+
if any(word in description for word in tech_details):
|
|
190
|
+
# Some tech details OK, but too many reduce negotiability
|
|
191
|
+
tech_count = sum(1 for word in tech_details if word in description)
|
|
192
|
+
if tech_count > 2:
|
|
193
|
+
score -= 20.0
|
|
194
|
+
|
|
195
|
+
return max(0.0, score)
|
|
196
|
+
|
|
197
|
+
def _evaluate_valuable(self, story: dict[str, Any]) -> float:
|
|
198
|
+
"""Evaluate if story delivers value (0-100)."""
|
|
199
|
+
score = 0.0
|
|
200
|
+
|
|
201
|
+
description = story.get("description", "")
|
|
202
|
+
if not description:
|
|
203
|
+
return 0.0
|
|
204
|
+
|
|
205
|
+
# Check for "So that..." clause (value statement)
|
|
206
|
+
if "so that" in description.lower():
|
|
207
|
+
score += 50.0
|
|
208
|
+
# Check if value is clear
|
|
209
|
+
so_that_part = description.lower().split("so that")[-1] if "so that" in description.lower() else ""
|
|
210
|
+
if len(so_that_part.strip()) > 20:
|
|
211
|
+
score += 30.0
|
|
212
|
+
|
|
213
|
+
# Check for user role (As a...)
|
|
214
|
+
if re.search(r"as a\s+\w+", description.lower()):
|
|
215
|
+
score += 20.0
|
|
216
|
+
|
|
217
|
+
# Check for business value indicators
|
|
218
|
+
value_words = ["improve", "enable", "allow", "provide", "increase", "reduce", "save"]
|
|
219
|
+
if any(word in description.lower() for word in value_words):
|
|
220
|
+
score += 10.0
|
|
221
|
+
|
|
222
|
+
return min(100.0, score)
|
|
223
|
+
|
|
224
|
+
def _evaluate_estimable(self, story: dict[str, Any]) -> float:
|
|
225
|
+
"""Evaluate if story can be estimated (0-100)."""
|
|
226
|
+
score = 0.0
|
|
227
|
+
|
|
228
|
+
# Has story points = estimable
|
|
229
|
+
if story.get("story_points"):
|
|
230
|
+
score += 60.0
|
|
231
|
+
# Story points in reasonable range (1-13)
|
|
232
|
+
points = story.get("story_points", 0)
|
|
233
|
+
if 1 <= points <= 13:
|
|
234
|
+
score += 20.0
|
|
235
|
+
elif points > 13:
|
|
236
|
+
score -= 20.0 # Too large to estimate accurately
|
|
237
|
+
|
|
238
|
+
# Has acceptance criteria = more estimable
|
|
239
|
+
acceptance = story.get("acceptance_criteria", [])
|
|
240
|
+
if acceptance:
|
|
241
|
+
score += 20.0
|
|
242
|
+
if len(acceptance) >= 3:
|
|
243
|
+
score += 10.0
|
|
244
|
+
|
|
245
|
+
# Clear description helps estimation
|
|
246
|
+
description = story.get("description", "")
|
|
247
|
+
if description and len(description) > 50:
|
|
248
|
+
score += 10.0
|
|
249
|
+
|
|
250
|
+
return min(100.0, score)
|
|
251
|
+
|
|
252
|
+
def _evaluate_small(self, story: dict[str, Any]) -> float:
|
|
253
|
+
"""Evaluate if story is appropriately sized (0-100)."""
|
|
254
|
+
score = 100.0
|
|
255
|
+
|
|
256
|
+
# Check story points
|
|
257
|
+
points = story.get("story_points", 0)
|
|
258
|
+
if points > 8:
|
|
259
|
+
score -= 40.0 # Too large
|
|
260
|
+
elif points > 5:
|
|
261
|
+
score -= 20.0 # Large but acceptable
|
|
262
|
+
|
|
263
|
+
# Check acceptance criteria count
|
|
264
|
+
acceptance = story.get("acceptance_criteria", [])
|
|
265
|
+
if len(acceptance) > 7:
|
|
266
|
+
score -= 30.0 # Too many acceptance criteria = too large
|
|
267
|
+
elif len(acceptance) > 5:
|
|
268
|
+
score -= 15.0
|
|
269
|
+
|
|
270
|
+
# Check description length (very long = might be too large)
|
|
271
|
+
description = story.get("description", "")
|
|
272
|
+
if len(description) > 500:
|
|
273
|
+
score -= 20.0
|
|
274
|
+
|
|
275
|
+
return max(0.0, score)
|
|
276
|
+
|
|
277
|
+
def _evaluate_testable(self, story: dict[str, Any]) -> float:
|
|
278
|
+
"""Evaluate if story is testable (0-100)."""
|
|
279
|
+
score = 0.0
|
|
280
|
+
|
|
281
|
+
# Has acceptance criteria = testable
|
|
282
|
+
acceptance = story.get("acceptance_criteria", [])
|
|
283
|
+
if acceptance:
|
|
284
|
+
score += 50.0
|
|
285
|
+
|
|
286
|
+
# Check quality of acceptance criteria
|
|
287
|
+
testable_count = 0
|
|
288
|
+
for criterion in acceptance:
|
|
289
|
+
if isinstance(criterion, str):
|
|
290
|
+
if self._is_testable_criterion(criterion):
|
|
291
|
+
testable_count += 1
|
|
292
|
+
|
|
293
|
+
if testable_count > 0:
|
|
294
|
+
testable_ratio = testable_count / len(acceptance)
|
|
295
|
+
score += testable_ratio * 50.0
|
|
296
|
+
else:
|
|
297
|
+
# No acceptance criteria = not testable
|
|
298
|
+
return 0.0
|
|
299
|
+
|
|
300
|
+
# Clear description helps testability
|
|
301
|
+
description = story.get("description", "")
|
|
302
|
+
if description and "as a" in description.lower() and "i want" in description.lower():
|
|
303
|
+
score += 20.0
|
|
304
|
+
|
|
305
|
+
return min(100.0, score)
|
|
306
|
+
|
|
307
|
+
def _is_testable_criterion(self, criterion: str) -> bool:
|
|
308
|
+
"""Check if acceptance criterion is testable."""
|
|
309
|
+
criterion_lower = criterion.lower()
|
|
310
|
+
|
|
311
|
+
# Testable criteria have:
|
|
312
|
+
# - Specific conditions
|
|
313
|
+
# - Observable outcomes
|
|
314
|
+
# - Measurable results
|
|
315
|
+
|
|
316
|
+
testable_indicators = [
|
|
317
|
+
"when",
|
|
318
|
+
"then",
|
|
319
|
+
"should",
|
|
320
|
+
"must",
|
|
321
|
+
"will",
|
|
322
|
+
"displays",
|
|
323
|
+
"shows",
|
|
324
|
+
"returns",
|
|
325
|
+
"validates",
|
|
326
|
+
"verifies",
|
|
327
|
+
"checks",
|
|
328
|
+
]
|
|
329
|
+
|
|
330
|
+
has_indicator = any(indicator in criterion_lower for indicator in testable_indicators)
|
|
331
|
+
|
|
332
|
+
# Check for measurable outcomes
|
|
333
|
+
measurable = any(
|
|
334
|
+
word in criterion_lower
|
|
335
|
+
for word in ["seconds", "milliseconds", "users", "requests", "percentage", "%", "times"]
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
return has_indicator or measurable or len(criterion) > 30 # Longer = more likely testable
|
|
339
|
+
|
|
340
|
+
def _identify_issues(self, story: dict[str, Any], score: StoryQualityScore) -> list[str]:
|
|
341
|
+
"""Identify issues in story."""
|
|
342
|
+
issues = []
|
|
343
|
+
|
|
344
|
+
if score.independent < 60.0:
|
|
345
|
+
issues.append("Story has too many dependencies - not independent")
|
|
346
|
+
|
|
347
|
+
if score.valuable < 60.0:
|
|
348
|
+
issues.append("Story value is unclear - missing 'So that...' clause")
|
|
349
|
+
|
|
350
|
+
if score.estimable < 60.0:
|
|
351
|
+
issues.append("Story cannot be estimated - missing story points or details")
|
|
352
|
+
|
|
353
|
+
if score.small < 60.0:
|
|
354
|
+
issues.append("Story is too large - consider breaking down")
|
|
355
|
+
|
|
356
|
+
if score.testable < 60.0:
|
|
357
|
+
issues.append("Story is not testable - missing or weak acceptance criteria")
|
|
358
|
+
|
|
359
|
+
acceptance = story.get("acceptance_criteria", [])
|
|
360
|
+
if len(acceptance) < 2:
|
|
361
|
+
issues.append("Story has insufficient acceptance criteria")
|
|
362
|
+
|
|
363
|
+
return issues
|
|
364
|
+
|
|
365
|
+
def _identify_strengths(self, story: dict[str, Any], score: StoryQualityScore) -> list[str]:
|
|
366
|
+
"""Identify strengths in story."""
|
|
367
|
+
strengths = []
|
|
368
|
+
|
|
369
|
+
if score.independent >= 80.0:
|
|
370
|
+
strengths.append("Story is independent - can be developed standalone")
|
|
371
|
+
|
|
372
|
+
if score.valuable >= 80.0:
|
|
373
|
+
strengths.append("Clear value proposition")
|
|
374
|
+
|
|
375
|
+
if score.estimable >= 80.0:
|
|
376
|
+
strengths.append("Well-estimated with story points")
|
|
377
|
+
|
|
378
|
+
if score.small >= 80.0:
|
|
379
|
+
strengths.append("Appropriately sized")
|
|
380
|
+
|
|
381
|
+
if score.testable >= 80.0:
|
|
382
|
+
strengths.append("Well-defined acceptance criteria")
|
|
383
|
+
|
|
384
|
+
acceptance = story.get("acceptance_criteria", [])
|
|
385
|
+
if len(acceptance) >= 3:
|
|
386
|
+
strengths.append("Comprehensive acceptance criteria")
|
|
387
|
+
|
|
388
|
+
return strengths
|
|
389
|
+
|
|
390
|
+
def _generate_recommendations(self, score: StoryQualityScore) -> list[str]:
|
|
391
|
+
"""Generate improvement recommendations."""
|
|
392
|
+
recommendations = []
|
|
393
|
+
|
|
394
|
+
if score.independent < 70.0:
|
|
395
|
+
recommendations.append("Reduce dependencies or split into multiple stories")
|
|
396
|
+
|
|
397
|
+
if score.valuable < 70.0:
|
|
398
|
+
recommendations.append("Add 'So that...' clause to clarify value")
|
|
399
|
+
|
|
400
|
+
if score.estimable < 70.0:
|
|
401
|
+
recommendations.append("Add story points and more detailed description")
|
|
402
|
+
|
|
403
|
+
if score.small < 70.0:
|
|
404
|
+
recommendations.append("Break story into smaller stories")
|
|
405
|
+
|
|
406
|
+
if score.testable < 70.0:
|
|
407
|
+
recommendations.append("Add more detailed, testable acceptance criteria")
|
|
408
|
+
recommendations.append("Use Given-When-Then format for acceptance criteria")
|
|
409
|
+
|
|
410
|
+
return recommendations
|