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,798 +1,798 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Implementer Agent - Generates and writes production code
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import logging
|
|
6
|
-
import shutil
|
|
7
|
-
from datetime import datetime
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
|
|
10
|
-
# Import ReviewerAgent (circular import handled lazily)
|
|
11
|
-
from typing import TYPE_CHECKING, Any
|
|
12
|
-
|
|
13
|
-
from ...context7.agent_integration import Context7AgentHelper, get_context7_helper
|
|
14
|
-
from ...core.agent_base import BaseAgent
|
|
15
|
-
from ...core.config import ProjectConfig, load_config
|
|
16
|
-
from ...core.instructions import CodeGenerationInstruction
|
|
17
|
-
from ...experts.agent_integration import ExpertSupportMixin
|
|
18
|
-
from .code_generator import CodeGenerator
|
|
19
|
-
|
|
20
|
-
if TYPE_CHECKING:
|
|
21
|
-
from ..reviewer.agent import ReviewerAgent
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
logger = logging.getLogger(__name__)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class ImplementerAgent(BaseAgent, ExpertSupportMixin):
|
|
28
|
-
"""
|
|
29
|
-
Implementer Agent - Code generation and file writing.
|
|
30
|
-
|
|
31
|
-
Permissions: Read, Write, Edit, Grep, Glob, Bash
|
|
32
|
-
|
|
33
|
-
⚠️ CRITICAL ACCURACY REQUIREMENT:
|
|
34
|
-
- NEVER make up, invent, or fabricate information - Only report verified facts
|
|
35
|
-
- ALWAYS verify claims by checking actual results, not just test pass/fail
|
|
36
|
-
- Verify API calls succeed - inspect response data, status codes, error messages
|
|
37
|
-
- Distinguish between code paths executing and actual functionality working
|
|
38
|
-
- Admit uncertainty explicitly when you cannot verify
|
|
39
|
-
"""
|
|
40
|
-
|
|
41
|
-
def __init__(
|
|
42
|
-
self,
|
|
43
|
-
config: ProjectConfig | None = None,
|
|
44
|
-
expert_registry: Any | None = None,
|
|
45
|
-
):
|
|
46
|
-
super().__init__(
|
|
47
|
-
agent_id="implementer", agent_name="Implementer Agent", config=config
|
|
48
|
-
)
|
|
49
|
-
# Use config if provided, otherwise load defaults
|
|
50
|
-
if config is None:
|
|
51
|
-
config = load_config()
|
|
52
|
-
self.config = config
|
|
53
|
-
|
|
54
|
-
# Initialize code generator
|
|
55
|
-
self.code_generator = CodeGenerator()
|
|
56
|
-
|
|
57
|
-
# Get implementer config
|
|
58
|
-
implementer_config = (
|
|
59
|
-
config.agents.implementer if config and config.agents else None
|
|
60
|
-
)
|
|
61
|
-
self.require_review = (
|
|
62
|
-
implementer_config.require_review if implementer_config else True
|
|
63
|
-
)
|
|
64
|
-
self.auto_approve_threshold = (
|
|
65
|
-
implementer_config.auto_approve_threshold if implementer_config else 80.0
|
|
66
|
-
)
|
|
67
|
-
self.backup_files = (
|
|
68
|
-
implementer_config.backup_files if implementer_config else True
|
|
69
|
-
)
|
|
70
|
-
self.max_file_size = (
|
|
71
|
-
implementer_config.max_file_size if implementer_config else 10 * 1024 * 1024
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
# Initialize Context7 helper
|
|
75
|
-
self.context7: Context7AgentHelper | None = None
|
|
76
|
-
if config:
|
|
77
|
-
self.context7 = get_context7_helper(self, config)
|
|
78
|
-
|
|
79
|
-
# Expert registry initialization (required due to multiple inheritance MRO issue)
|
|
80
|
-
# BaseAgent.__init__() doesn't call super().__init__(), so ExpertSupportMixin.__init__()
|
|
81
|
-
# is never called via MRO. We must manually initialize to avoid AttributeError.
|
|
82
|
-
# The registry will be properly initialized in activate() via _initialize_expert_support()
|
|
83
|
-
self.expert_registry: Any | None = None
|
|
84
|
-
# Allow manual override if provided (for testing or special cases)
|
|
85
|
-
if expert_registry:
|
|
86
|
-
self.expert_registry = expert_registry
|
|
87
|
-
|
|
88
|
-
# Reviewer agent for code review
|
|
89
|
-
self.reviewer: ReviewerAgent | None = None
|
|
90
|
-
|
|
91
|
-
async def activate(self, project_root: Path | None = None, offline_mode: bool = False):
|
|
92
|
-
"""Activate the implementer agent with expert support."""
|
|
93
|
-
# Validate that expert_registry attribute exists (safety check)
|
|
94
|
-
if not hasattr(self, 'expert_registry'):
|
|
95
|
-
raise AttributeError(
|
|
96
|
-
f"{self.__class__.__name__}.expert_registry not initialized. "
|
|
97
|
-
"This should not happen if __init__() properly initializes the attribute."
|
|
98
|
-
)
|
|
99
|
-
await super().activate(project_root, offline_mode=offline_mode)
|
|
100
|
-
# Initialize expert support via mixin
|
|
101
|
-
await self._initialize_expert_support(project_root, offline_mode=offline_mode)
|
|
102
|
-
|
|
103
|
-
def get_commands(self) -> list[dict[str, str]]:
|
|
104
|
-
"""Return available commands for implementer agent"""
|
|
105
|
-
base_commands = super().get_commands()
|
|
106
|
-
return base_commands + [
|
|
107
|
-
{
|
|
108
|
-
"command": "*implement",
|
|
109
|
-
"description": "Generate and write code to file (with review)",
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
"command": "*generate-code",
|
|
113
|
-
"description": "Generate code from specification (no file write)",
|
|
114
|
-
},
|
|
115
|
-
{"command": "*refactor", "description": "Refactor existing code file"},
|
|
116
|
-
]
|
|
117
|
-
|
|
118
|
-
async def run(self, command: str, **kwargs) -> dict[str, Any]:
|
|
119
|
-
"""
|
|
120
|
-
Execute implementer agent command.
|
|
121
|
-
|
|
122
|
-
Commands:
|
|
123
|
-
- *implement <specification> <file_path>: Generate and write code (with review)
|
|
124
|
-
- *generate-code <specification> [--file=<file_path>]: Generate code only
|
|
125
|
-
- *refactor <file_path> <instruction>: Refactor existing code
|
|
126
|
-
"""
|
|
127
|
-
await self.activate()
|
|
128
|
-
|
|
129
|
-
if command == "help":
|
|
130
|
-
return self._help()
|
|
131
|
-
|
|
132
|
-
elif command == "implement":
|
|
133
|
-
specification = kwargs.get("specification") or kwargs.get("text", "")
|
|
134
|
-
file_path = kwargs.get("file_path") or kwargs.get("file")
|
|
135
|
-
if not specification:
|
|
136
|
-
return {
|
|
137
|
-
"error": "Specification required. Usage: *implement <specification> <file_path>"
|
|
138
|
-
}
|
|
139
|
-
if not file_path:
|
|
140
|
-
return {
|
|
141
|
-
"error": "File path required. Usage: *implement <specification> <file_path>"
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
context = kwargs.get("context")
|
|
145
|
-
language = kwargs.get("language", "python")
|
|
146
|
-
return await self.implement(
|
|
147
|
-
specification, file_path, context=context, language=language
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
elif command == "generate-code":
|
|
151
|
-
specification = kwargs.get("specification") or kwargs.get("text", "")
|
|
152
|
-
if not specification:
|
|
153
|
-
return {
|
|
154
|
-
"error": "Specification required. Usage: *generate-code <specification> [--file=<file_path>]"
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
file_path = kwargs.get("file_path") or kwargs.get("file")
|
|
158
|
-
context = kwargs.get("context")
|
|
159
|
-
language = kwargs.get("language", "python")
|
|
160
|
-
return await self.generate_code(
|
|
161
|
-
specification, file_path=file_path, context=context, language=language
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
elif command == "refactor":
|
|
165
|
-
file_path = kwargs.get("file_path") or kwargs.get("file")
|
|
166
|
-
instruction = kwargs.get("instruction") or kwargs.get("text", "")
|
|
167
|
-
if not file_path:
|
|
168
|
-
return {
|
|
169
|
-
"error": "File path required. Usage: *refactor <file_path> <instruction>"
|
|
170
|
-
}
|
|
171
|
-
if not instruction:
|
|
172
|
-
return {
|
|
173
|
-
"error": "Instruction required. Usage: *refactor <file_path> <instruction>"
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return await self.refactor(file_path, instruction)
|
|
177
|
-
|
|
178
|
-
else:
|
|
179
|
-
return {
|
|
180
|
-
"error": f"Unknown command: {command}. Use *help to see available commands."
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
async def implement(
|
|
184
|
-
self,
|
|
185
|
-
specification: str,
|
|
186
|
-
file_path: str,
|
|
187
|
-
context: str | None = None,
|
|
188
|
-
language: str = "python",
|
|
189
|
-
) -> dict[str, Any]:
|
|
190
|
-
"""
|
|
191
|
-
Generate code from specification and write to file (with review).
|
|
192
|
-
|
|
193
|
-
Args:
|
|
194
|
-
specification: Description of what code to generate
|
|
195
|
-
file_path: Target file path
|
|
196
|
-
context: Optional context (existing code, patterns, etc.)
|
|
197
|
-
language: Programming language
|
|
198
|
-
|
|
199
|
-
Returns:
|
|
200
|
-
Result dictionary with code, file path, review results, etc.
|
|
201
|
-
"""
|
|
202
|
-
path = Path(file_path)
|
|
203
|
-
|
|
204
|
-
# Validate path
|
|
205
|
-
if not self._is_valid_path(path):
|
|
206
|
-
return {"error": f"Invalid or unsafe path: {file_path}"}
|
|
207
|
-
|
|
208
|
-
# Check if file exists
|
|
209
|
-
file_exists = path.exists()
|
|
210
|
-
|
|
211
|
-
# Consult experts for code generation guidance
|
|
212
|
-
expert_guidance = {}
|
|
213
|
-
# Use defensive check to ensure attribute exists (safety for MRO issue)
|
|
214
|
-
if hasattr(self, 'expert_registry') and self.expert_registry:
|
|
215
|
-
# Consult Security expert for secure coding practices
|
|
216
|
-
try:
|
|
217
|
-
security_consultation = await self.expert_registry.consult(
|
|
218
|
-
query=f"Secure coding practices for: {specification}. Language: {language}",
|
|
219
|
-
domain="security",
|
|
220
|
-
include_all=True,
|
|
221
|
-
prioritize_builtin=True,
|
|
222
|
-
agent_id="implementer",
|
|
223
|
-
)
|
|
224
|
-
expert_guidance["security"] = security_consultation.weighted_answer
|
|
225
|
-
except Exception:
|
|
226
|
-
logger.debug("Security expert consultation failed", exc_info=True)
|
|
227
|
-
|
|
228
|
-
# Consult Performance expert for performance optimization
|
|
229
|
-
try:
|
|
230
|
-
perf_consultation = await self.expert_registry.consult(
|
|
231
|
-
query=f"Performance optimization for code: {specification}",
|
|
232
|
-
domain="performance-optimization",
|
|
233
|
-
include_all=True,
|
|
234
|
-
prioritize_builtin=True,
|
|
235
|
-
agent_id="implementer",
|
|
236
|
-
)
|
|
237
|
-
expert_guidance["performance"] = perf_consultation.weighted_answer
|
|
238
|
-
except Exception:
|
|
239
|
-
logger.debug("Performance expert consultation failed", exc_info=True)
|
|
240
|
-
|
|
241
|
-
# Consult API Design expert if implementing/refactoring an API client
|
|
242
|
-
if await self._detect_api_client_pattern(specification, context):
|
|
243
|
-
try:
|
|
244
|
-
api_consultation = await self.expert_registry.consult(
|
|
245
|
-
query=f"Provide implementation guidance for this API client:\n\n{specification}",
|
|
246
|
-
domain="api-design-integration",
|
|
247
|
-
include_all=True,
|
|
248
|
-
prioritize_builtin=True,
|
|
249
|
-
agent_id="implementer",
|
|
250
|
-
)
|
|
251
|
-
expert_guidance["api_design"] = api_consultation.weighted_answer
|
|
252
|
-
except Exception:
|
|
253
|
-
logger.debug("API design expert consultation failed", exc_info=True)
|
|
254
|
-
|
|
255
|
-
# R7: Get Context7 documentation for libraries mentioned in specification
|
|
256
|
-
context7_docs = {}
|
|
257
|
-
if self.context7 and self.context7.enabled:
|
|
258
|
-
try:
|
|
259
|
-
# Detect libraries from specification and context
|
|
260
|
-
detected_libraries = []
|
|
261
|
-
if self.context7.library_detector:
|
|
262
|
-
# R7: Detect from specification text (prompt)
|
|
263
|
-
detected_libraries.extend(
|
|
264
|
-
self.context7.library_detector.detect_from_prompt(specification)
|
|
265
|
-
)
|
|
266
|
-
# Detect from context code if available
|
|
267
|
-
if context:
|
|
268
|
-
detected_libraries.extend(
|
|
269
|
-
self.context7.library_detector.detect_from_code(context, language=language)
|
|
270
|
-
)
|
|
271
|
-
|
|
272
|
-
# Get Context7 documentation for each detected library
|
|
273
|
-
for library in set(detected_libraries): # Remove duplicates
|
|
274
|
-
try:
|
|
275
|
-
docs_result = await self.context7.get_documentation(library, topic=None, use_fuzzy_match=True)
|
|
276
|
-
if docs_result and docs_result.get("content"):
|
|
277
|
-
context7_docs[library] = docs_result["content"]
|
|
278
|
-
logger.debug(f"Retrieved Context7 docs for library '{library}'")
|
|
279
|
-
except Exception as e:
|
|
280
|
-
logger.debug(f"Failed to get Context7 docs for library '{library}': {e}")
|
|
281
|
-
except Exception as e:
|
|
282
|
-
logger.debug(f"Context7 documentation lookup failed: {e}", exc_info=True)
|
|
283
|
-
|
|
284
|
-
# Prepare code generation instruction for Cursor Skills
|
|
285
|
-
try:
|
|
286
|
-
instruction = self.code_generator.prepare_code_generation(
|
|
287
|
-
specification=specification,
|
|
288
|
-
file_path=path,
|
|
289
|
-
context=context,
|
|
290
|
-
language=language,
|
|
291
|
-
expert_guidance=expert_guidance,
|
|
292
|
-
context7_docs=context7_docs if context7_docs else None,
|
|
293
|
-
)
|
|
294
|
-
except Exception as e:
|
|
295
|
-
return {"error": f"Failed to prepare code generation instruction: {str(e)}"}
|
|
296
|
-
|
|
297
|
-
# Return instruction object for Cursor Skills execution
|
|
298
|
-
skill_command = instruction.to_skill_command()
|
|
299
|
-
result = {
|
|
300
|
-
"type": "implement",
|
|
301
|
-
"execution_mode": "cursor_skills", # Explicit mode indication
|
|
302
|
-
"instruction": instruction.to_dict(),
|
|
303
|
-
"skill_command": skill_command,
|
|
304
|
-
"file": str(path),
|
|
305
|
-
"file_existed": file_exists,
|
|
306
|
-
"next_steps": [
|
|
307
|
-
"This instruction is prepared for Cursor Skills execution.",
|
|
308
|
-
"To execute, copy this command to Cursor chat:",
|
|
309
|
-
f" {skill_command}",
|
|
310
|
-
"",
|
|
311
|
-
"Or use Cursor Skills directly:",
|
|
312
|
-
f" @implementer *implement \"{specification}\" {file_path}",
|
|
313
|
-
"",
|
|
314
|
-
"Note: Code generation requires Cursor Skills (uses your configured LLM).",
|
|
315
|
-
"The framework prepares instructions; Cursor Skills execute them.",
|
|
316
|
-
],
|
|
317
|
-
}
|
|
318
|
-
if expert_guidance:
|
|
319
|
-
result["expert_guidance"] = expert_guidance
|
|
320
|
-
return result
|
|
321
|
-
|
|
322
|
-
async def generate_code(
|
|
323
|
-
self,
|
|
324
|
-
specification: str,
|
|
325
|
-
file_path: str | None = None,
|
|
326
|
-
context: str | None = None,
|
|
327
|
-
language: str = "python",
|
|
328
|
-
) -> dict[str, Any]:
|
|
329
|
-
"""
|
|
330
|
-
Generate code from specification (no file write).
|
|
331
|
-
|
|
332
|
-
Args:
|
|
333
|
-
specification: Description of what code to generate
|
|
334
|
-
file_path: Optional target file path for context
|
|
335
|
-
context: Optional context
|
|
336
|
-
language: Programming language
|
|
337
|
-
|
|
338
|
-
Returns:
|
|
339
|
-
Result dictionary with generated code
|
|
340
|
-
"""
|
|
341
|
-
path = Path(file_path) if file_path else None
|
|
342
|
-
|
|
343
|
-
if path and not self._is_valid_path(path):
|
|
344
|
-
return {"error": f"Invalid or unsafe path: {file_path}"}
|
|
345
|
-
|
|
346
|
-
# Consult experts for code generation guidance
|
|
347
|
-
expert_guidance = {}
|
|
348
|
-
# Use defensive check to ensure attribute exists (safety for MRO issue)
|
|
349
|
-
if hasattr(self, 'expert_registry') and self.expert_registry:
|
|
350
|
-
try:
|
|
351
|
-
security_consultation = await self.expert_registry.consult(
|
|
352
|
-
query=f"Secure coding practices for: {specification}",
|
|
353
|
-
domain="security",
|
|
354
|
-
include_all=True,
|
|
355
|
-
prioritize_builtin=True,
|
|
356
|
-
agent_id="implementer",
|
|
357
|
-
)
|
|
358
|
-
expert_guidance["security"] = security_consultation.weighted_answer
|
|
359
|
-
except Exception:
|
|
360
|
-
logger.debug("Security expert consultation failed", exc_info=True)
|
|
361
|
-
|
|
362
|
-
try:
|
|
363
|
-
perf_consultation = await self.expert_registry.consult(
|
|
364
|
-
query=f"Performance optimization for: {specification}",
|
|
365
|
-
domain="performance-optimization",
|
|
366
|
-
include_all=True,
|
|
367
|
-
prioritize_builtin=True,
|
|
368
|
-
agent_id="implementer",
|
|
369
|
-
)
|
|
370
|
-
expert_guidance["performance"] = perf_consultation.weighted_answer
|
|
371
|
-
except Exception:
|
|
372
|
-
logger.debug("Performance expert consultation failed", exc_info=True)
|
|
373
|
-
|
|
374
|
-
# Consult API Design expert if implementing/refactoring an API client
|
|
375
|
-
if await self._detect_api_client_pattern(specification, context):
|
|
376
|
-
try:
|
|
377
|
-
api_consultation = await self.expert_registry.consult(
|
|
378
|
-
query=f"Provide implementation guidance for this API client:\n\n{specification}",
|
|
379
|
-
domain="api-design-integration",
|
|
380
|
-
include_all=True,
|
|
381
|
-
prioritize_builtin=True,
|
|
382
|
-
agent_id="implementer",
|
|
383
|
-
)
|
|
384
|
-
expert_guidance["api_design"] = api_consultation.weighted_answer
|
|
385
|
-
except Exception:
|
|
386
|
-
logger.debug("API design expert consultation failed", exc_info=True)
|
|
387
|
-
|
|
388
|
-
try:
|
|
389
|
-
instruction = self.code_generator.prepare_code_generation(
|
|
390
|
-
specification=specification,
|
|
391
|
-
file_path=path,
|
|
392
|
-
context=context,
|
|
393
|
-
language=language,
|
|
394
|
-
expert_guidance=expert_guidance,
|
|
395
|
-
)
|
|
396
|
-
|
|
397
|
-
result: dict[str, Any] = {
|
|
398
|
-
"type": "generate_code",
|
|
399
|
-
"instruction": instruction.to_dict(),
|
|
400
|
-
"skill_command": instruction.to_skill_command(),
|
|
401
|
-
"file_path": str(path) if path else None,
|
|
402
|
-
"language": language,
|
|
403
|
-
}
|
|
404
|
-
if expert_guidance:
|
|
405
|
-
result["expert_guidance"] = expert_guidance
|
|
406
|
-
return result
|
|
407
|
-
except Exception as e:
|
|
408
|
-
return {"error": f"Failed to prepare code generation instruction: {str(e)}"}
|
|
409
|
-
|
|
410
|
-
async def refactor(
|
|
411
|
-
self, file_path: str, instruction: str, preview: bool = False
|
|
412
|
-
) -> dict[str, Any]:
|
|
413
|
-
"""
|
|
414
|
-
Refactor existing code file.
|
|
415
|
-
|
|
416
|
-
Phase 5.1: Enhanced file writing with validation and ErrorEnvelope
|
|
417
|
-
|
|
418
|
-
Args:
|
|
419
|
-
file_path: Path to file to refactor
|
|
420
|
-
instruction: Refactoring instruction
|
|
421
|
-
preview: If True, return refactored code without writing to file (default: False)
|
|
422
|
-
|
|
423
|
-
Returns:
|
|
424
|
-
Result dictionary with refactored code and file path, or ErrorEnvelope on error
|
|
425
|
-
"""
|
|
426
|
-
from ...core.error_envelope import ErrorEnvelopeBuilder
|
|
427
|
-
|
|
428
|
-
path = Path(file_path)
|
|
429
|
-
|
|
430
|
-
# Validate path with ErrorEnvelope
|
|
431
|
-
if not path.exists():
|
|
432
|
-
envelope = ErrorEnvelopeBuilder.from_exception(
|
|
433
|
-
FileNotFoundError(f"File not found: {file_path}"),
|
|
434
|
-
agent="implementer",
|
|
435
|
-
)
|
|
436
|
-
return envelope.to_dict()
|
|
437
|
-
|
|
438
|
-
if not self._is_valid_path(path):
|
|
439
|
-
envelope = ErrorEnvelopeBuilder.from_exception(
|
|
440
|
-
ValueError(f"Invalid or unsafe path: {file_path}"),
|
|
441
|
-
agent="implementer",
|
|
442
|
-
)
|
|
443
|
-
return envelope.to_dict()
|
|
444
|
-
|
|
445
|
-
# Read existing code with enhanced error handling
|
|
446
|
-
try:
|
|
447
|
-
existing_code = path.read_text(encoding="utf-8")
|
|
448
|
-
if not existing_code.strip():
|
|
449
|
-
envelope = ErrorEnvelopeBuilder.from_exception(
|
|
450
|
-
ValueError(f"File is empty: {file_path}"),
|
|
451
|
-
agent="implementer",
|
|
452
|
-
)
|
|
453
|
-
return envelope.to_dict()
|
|
454
|
-
except UnicodeDecodeError as e:
|
|
455
|
-
envelope = ErrorEnvelopeBuilder.from_exception(
|
|
456
|
-
e,
|
|
457
|
-
agent="implementer",
|
|
458
|
-
)
|
|
459
|
-
envelope.message = f"Failed to read file (encoding error): {file_path}. File may not be text-based."
|
|
460
|
-
return envelope.to_dict()
|
|
461
|
-
except Exception as e:
|
|
462
|
-
envelope = ErrorEnvelopeBuilder.from_exception(
|
|
463
|
-
e,
|
|
464
|
-
agent="implementer",
|
|
465
|
-
)
|
|
466
|
-
envelope.message = f"Failed to read file: {file_path}. {envelope.message}"
|
|
467
|
-
return envelope.to_dict()
|
|
468
|
-
|
|
469
|
-
# Detect language from file extension
|
|
470
|
-
language = self._detect_language(path)
|
|
471
|
-
|
|
472
|
-
# Prepare refactoring instruction for Cursor Skills with enhanced error handling
|
|
473
|
-
try:
|
|
474
|
-
refactor_instruction = self.code_generator.prepare_refactoring(
|
|
475
|
-
code=existing_code, instruction=instruction, language=language
|
|
476
|
-
)
|
|
477
|
-
except Exception as e:
|
|
478
|
-
envelope = ErrorEnvelopeBuilder.from_exception(
|
|
479
|
-
e,
|
|
480
|
-
agent="implementer",
|
|
481
|
-
)
|
|
482
|
-
envelope.message = f"Failed to prepare refactoring instruction: {envelope.message}"
|
|
483
|
-
return envelope.to_dict()
|
|
484
|
-
|
|
485
|
-
# Create backup before refactoring (best-effort, don't fail if backup fails)
|
|
486
|
-
backup_path = None
|
|
487
|
-
try:
|
|
488
|
-
backup_path = self._create_backup(path)
|
|
489
|
-
except Exception as e:
|
|
490
|
-
# Log warning but continue (backup failure shouldn't block refactoring)
|
|
491
|
-
import logging
|
|
492
|
-
|
|
493
|
-
logger = logging.getLogger(__name__)
|
|
494
|
-
logger.warning(f"Failed to create backup for {file_path}: {e}")
|
|
495
|
-
|
|
496
|
-
# Refactored code: in Cursor mode, the skill_command is executed by Cursor Skills
|
|
497
|
-
# (user's model), which performs the edit. In headless/CLI mode, code generation
|
|
498
|
-
# would require MAL/LLM; when available, we would set refactored_code and write.
|
|
499
|
-
refactored_code: str | None = None # Set when MAL/LLM generates in headless mode
|
|
500
|
-
|
|
501
|
-
result = {
|
|
502
|
-
"type": "refactor",
|
|
503
|
-
"file": str(path),
|
|
504
|
-
"original_code": existing_code,
|
|
505
|
-
"instruction": refactor_instruction.to_dict(),
|
|
506
|
-
"skill_command": refactor_instruction.to_skill_command(),
|
|
507
|
-
"backup": str(backup_path) if backup_path else None,
|
|
508
|
-
"preview": preview,
|
|
509
|
-
"approved": True, # Would be set based on review/approval
|
|
510
|
-
"refactored_code": refactored_code,
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
# When not preview and MAL/LLM is available, we would generate refactored_code
|
|
514
|
-
# and write to path. For now, writing is delegated to Cursor Skills via skill_command.
|
|
515
|
-
return result
|
|
516
|
-
|
|
517
|
-
async def _review_code(self, code: str, file_path: Path) -> dict[str, Any] | None:
|
|
518
|
-
"""Review generated code using ReviewerAgent."""
|
|
519
|
-
if self.reviewer is None:
|
|
520
|
-
# Lazy import to avoid circular dependency
|
|
521
|
-
from ...agents.reviewer.agent import ReviewerAgent
|
|
522
|
-
|
|
523
|
-
self.reviewer = ReviewerAgent(config=self.config)
|
|
524
|
-
await self.reviewer.activate()
|
|
525
|
-
|
|
526
|
-
# Create temporary file for review
|
|
527
|
-
import tempfile
|
|
528
|
-
|
|
529
|
-
with tempfile.NamedTemporaryFile(
|
|
530
|
-
mode="w", suffix=file_path.suffix, delete=False
|
|
531
|
-
) as tmp_file:
|
|
532
|
-
tmp_file.write(code)
|
|
533
|
-
tmp_file_path = Path(tmp_file.name)
|
|
534
|
-
|
|
535
|
-
try:
|
|
536
|
-
# Review the code
|
|
537
|
-
review_result = await self.reviewer.review_file(tmp_file_path)
|
|
538
|
-
return review_result
|
|
539
|
-
except Exception as e:
|
|
540
|
-
# Review failed, but don't block if it's just an error
|
|
541
|
-
return {"error": f"Review failed: {str(e)}"}
|
|
542
|
-
finally:
|
|
543
|
-
# Clean up temp file
|
|
544
|
-
if tmp_file_path.exists():
|
|
545
|
-
tmp_file_path.unlink()
|
|
546
|
-
|
|
547
|
-
def _is_valid_path(self, path: Path) -> bool:
|
|
548
|
-
"""Return True if file path appears safe and within size constraints."""
|
|
549
|
-
# Resolve to absolute path
|
|
550
|
-
try:
|
|
551
|
-
resolved = path.resolve()
|
|
552
|
-
except Exception:
|
|
553
|
-
return False
|
|
554
|
-
|
|
555
|
-
# Check for path traversal
|
|
556
|
-
if ".." in str(path) and not resolved.exists():
|
|
557
|
-
return False
|
|
558
|
-
|
|
559
|
-
# Check for suspicious patterns
|
|
560
|
-
suspicious = ["%00", "%2e", "%2f", "..", "//"]
|
|
561
|
-
path_str = str(path)
|
|
562
|
-
if any(pattern in path_str for pattern in suspicious):
|
|
563
|
-
# Allow pytest temp files
|
|
564
|
-
if "pytest-" not in path_str:
|
|
565
|
-
return False
|
|
566
|
-
|
|
567
|
-
# Check file size if file exists
|
|
568
|
-
if resolved.exists() and resolved.is_file():
|
|
569
|
-
try:
|
|
570
|
-
if resolved.stat().st_size > self.max_file_size:
|
|
571
|
-
return False
|
|
572
|
-
except Exception:
|
|
573
|
-
return False
|
|
574
|
-
|
|
575
|
-
return True
|
|
576
|
-
|
|
577
|
-
def _create_backup(self, path: Path) -> Path | None:
|
|
578
|
-
"""
|
|
579
|
-
Create backup of existing file.
|
|
580
|
-
|
|
581
|
-
Phase 5.1: Enhanced backup creation with validation
|
|
582
|
-
"""
|
|
583
|
-
if not path.exists():
|
|
584
|
-
return None
|
|
585
|
-
|
|
586
|
-
try:
|
|
587
|
-
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
588
|
-
backup_path = path.parent / f"{path.stem}.backup_{timestamp}{path.suffix}"
|
|
589
|
-
shutil.copy2(path, backup_path)
|
|
590
|
-
|
|
591
|
-
# Validate backup was created correctly (Phase 5.1: Write Validation)
|
|
592
|
-
if backup_path.exists() and backup_path.stat().st_size == path.stat().st_size:
|
|
593
|
-
return backup_path
|
|
594
|
-
else:
|
|
595
|
-
# Backup file size mismatch, clean up and return None
|
|
596
|
-
if backup_path.exists():
|
|
597
|
-
backup_path.unlink()
|
|
598
|
-
logger.warning(f"Backup validation failed for {path}, backup not created")
|
|
599
|
-
return None
|
|
600
|
-
except Exception as e:
|
|
601
|
-
logger.warning(f"Failed to create backup for {path}: {e}")
|
|
602
|
-
return None
|
|
603
|
-
|
|
604
|
-
def _detect_language(self, path: Path) -> str:
|
|
605
|
-
"""Detect programming language from file extension."""
|
|
606
|
-
extension_map = {
|
|
607
|
-
".py": "python",
|
|
608
|
-
".js": "javascript",
|
|
609
|
-
".ts": "typescript",
|
|
610
|
-
".java": "java",
|
|
611
|
-
".cpp": "cpp",
|
|
612
|
-
".c": "c",
|
|
613
|
-
".rs": "rust",
|
|
614
|
-
".go": "go",
|
|
615
|
-
".rb": "ruby",
|
|
616
|
-
".php": "php",
|
|
617
|
-
".swift": "swift",
|
|
618
|
-
".kt": "kotlin",
|
|
619
|
-
".md": "markdown",
|
|
620
|
-
".yaml": "yaml",
|
|
621
|
-
".yml": "yaml",
|
|
622
|
-
}
|
|
623
|
-
return extension_map.get(path.suffix.lower(), "python")
|
|
624
|
-
|
|
625
|
-
async def _detect_api_client_pattern(self, specification: str, context: str | None = None) -> bool:
|
|
626
|
-
"""
|
|
627
|
-
Detect if specification/context indicates an HTTP/API client implementation.
|
|
628
|
-
|
|
629
|
-
Checks for common patterns that indicate API client code:
|
|
630
|
-
- Keywords: "API client", "OAuth2", "refresh token", "external API", "HTTP client"
|
|
631
|
-
- Authentication patterns: "Bearer", "token", "authentication"
|
|
632
|
-
- API patterns: "REST API", "API integration", "third-party API"
|
|
633
|
-
|
|
634
|
-
Args:
|
|
635
|
-
specification: Code specification/description
|
|
636
|
-
context: Optional context code
|
|
637
|
-
|
|
638
|
-
Returns:
|
|
639
|
-
True if specification appears to be for an API client, False otherwise
|
|
640
|
-
"""
|
|
641
|
-
if not specification:
|
|
642
|
-
return False
|
|
643
|
-
|
|
644
|
-
# Combine specification and context for analysis
|
|
645
|
-
text_to_analyze = specification.lower()
|
|
646
|
-
if context:
|
|
647
|
-
text_to_analyze += " " + context.lower()
|
|
648
|
-
|
|
649
|
-
# API client keywords (enhanced)
|
|
650
|
-
api_client_keywords = [
|
|
651
|
-
"api client",
|
|
652
|
-
"http client",
|
|
653
|
-
"rest client",
|
|
654
|
-
"oauth2",
|
|
655
|
-
"oauth 2",
|
|
656
|
-
"oauth",
|
|
657
|
-
"refresh token",
|
|
658
|
-
"access token",
|
|
659
|
-
"external api",
|
|
660
|
-
"third-party api",
|
|
661
|
-
"api integration",
|
|
662
|
-
"rest api",
|
|
663
|
-
"api wrapper",
|
|
664
|
-
"graphql client",
|
|
665
|
-
"graphql api",
|
|
666
|
-
"websocket client",
|
|
667
|
-
"mqtt client",
|
|
668
|
-
"grpc client",
|
|
669
|
-
]
|
|
670
|
-
|
|
671
|
-
# Authentication keywords (enhanced with OAuth2 patterns)
|
|
672
|
-
auth_keywords = [
|
|
673
|
-
"bearer",
|
|
674
|
-
"token", # General token (covers access, refresh, bearer, etc.)
|
|
675
|
-
"authentication",
|
|
676
|
-
"authorization",
|
|
677
|
-
"api key",
|
|
678
|
-
"api_key",
|
|
679
|
-
"apikey",
|
|
680
|
-
"client_id",
|
|
681
|
-
"client_secret",
|
|
682
|
-
"token_url",
|
|
683
|
-
"api_base_url",
|
|
684
|
-
"jwt",
|
|
685
|
-
"id_token",
|
|
686
|
-
"grant_type",
|
|
687
|
-
"authorization_code",
|
|
688
|
-
"client_credentials",
|
|
689
|
-
"credentials", # General credentials
|
|
690
|
-
"auth", # Short form
|
|
691
|
-
]
|
|
692
|
-
|
|
693
|
-
# Structure keywords (enhanced with framework patterns)
|
|
694
|
-
structure_keywords = [
|
|
695
|
-
"class.*client",
|
|
696
|
-
"get method",
|
|
697
|
-
"post method",
|
|
698
|
-
"put method",
|
|
699
|
-
"delete method",
|
|
700
|
-
"patch method",
|
|
701
|
-
"api endpoint",
|
|
702
|
-
"endpoint", # General endpoint
|
|
703
|
-
"rest endpoint",
|
|
704
|
-
"make request",
|
|
705
|
-
"http request",
|
|
706
|
-
"fastapi",
|
|
707
|
-
"django rest",
|
|
708
|
-
"api route",
|
|
709
|
-
"router", # General router
|
|
710
|
-
]
|
|
711
|
-
|
|
712
|
-
# Check for API client keywords
|
|
713
|
-
has_api_keywords = any(keyword in text_to_analyze for keyword in api_client_keywords)
|
|
714
|
-
|
|
715
|
-
# Check for authentication patterns
|
|
716
|
-
has_auth = any(keyword in text_to_analyze for keyword in auth_keywords)
|
|
717
|
-
|
|
718
|
-
# Check for structure patterns
|
|
719
|
-
has_structure = any(keyword in text_to_analyze for keyword in structure_keywords)
|
|
720
|
-
|
|
721
|
-
# Specification is likely for an API client if it has API keywords AND (auth OR structure)
|
|
722
|
-
return has_api_keywords and (has_auth or has_structure)
|
|
723
|
-
|
|
724
|
-
def _help(self) -> dict[str, Any]:
|
|
725
|
-
"""
|
|
726
|
-
Return help information for Implementer Agent.
|
|
727
|
-
|
|
728
|
-
Returns standardized help format with commands, examples, configuration,
|
|
729
|
-
and safety features documentation.
|
|
730
|
-
|
|
731
|
-
Returns:
|
|
732
|
-
dict: Help information with standardized format:
|
|
733
|
-
- type (str): Always "help"
|
|
734
|
-
- content (str): Formatted markdown help text containing:
|
|
735
|
-
- Available commands list
|
|
736
|
-
- Usage examples for implement, generate-code, refactor
|
|
737
|
-
- Configuration options
|
|
738
|
-
- Safety features documentation
|
|
739
|
-
|
|
740
|
-
Note:
|
|
741
|
-
This method is synchronous as it performs no I/O operations.
|
|
742
|
-
Called via agent.run("help") which handles async context.
|
|
743
|
-
Command list is cached via BaseAgent.get_commands() for performance.
|
|
744
|
-
"""
|
|
745
|
-
commands = self.get_commands()
|
|
746
|
-
command_lines = [
|
|
747
|
-
f"- **{cmd['command']}**: {cmd['description']}"
|
|
748
|
-
for cmd in commands
|
|
749
|
-
]
|
|
750
|
-
|
|
751
|
-
content = f"""# {self.agent_name} - Help
|
|
752
|
-
|
|
753
|
-
## Available Commands
|
|
754
|
-
|
|
755
|
-
{chr(10).join(command_lines)}
|
|
756
|
-
|
|
757
|
-
## Usage Examples
|
|
758
|
-
|
|
759
|
-
### Implement (Generate and Write)
|
|
760
|
-
```
|
|
761
|
-
*implement "Create a function to calculate factorial" factorial.py
|
|
762
|
-
*implement "Add user authentication endpoint" api/auth.py --context="Use FastAPI patterns"
|
|
763
|
-
```
|
|
764
|
-
|
|
765
|
-
### Generate Code (No Write)
|
|
766
|
-
```
|
|
767
|
-
*generate-code "Create a REST API client class"
|
|
768
|
-
*generate-code "Add data validation function" --file=utils/validation.py
|
|
769
|
-
```
|
|
770
|
-
|
|
771
|
-
### Refactor
|
|
772
|
-
```
|
|
773
|
-
*refactor utils/helpers.py "Extract common logic into helper functions"
|
|
774
|
-
*refactor models.py "Improve error handling and add type hints"
|
|
775
|
-
```
|
|
776
|
-
|
|
777
|
-
## Configuration
|
|
778
|
-
|
|
779
|
-
- **require_review**: Require code review before writing (default: true)
|
|
780
|
-
- **auto_approve_threshold**: Auto-approve if score >= threshold (default: 80.0)
|
|
781
|
-
- **backup_files**: Create backup before overwriting (default: true)
|
|
782
|
-
- **max_file_size**: Maximum file size in bytes (default: 10MB)
|
|
783
|
-
|
|
784
|
-
## Safety Features
|
|
785
|
-
|
|
786
|
-
- ✅ Code review before writing (integrated with Reviewer Agent)
|
|
787
|
-
- ✅ File backups before overwriting
|
|
788
|
-
- ✅ Path validation (prevents path traversal)
|
|
789
|
-
- ✅ File size limits
|
|
790
|
-
- ✅ Automatic rollback on write failure
|
|
791
|
-
"""
|
|
792
|
-
|
|
793
|
-
return {"type": "help", "content": content}
|
|
794
|
-
|
|
795
|
-
async def close(self):
|
|
796
|
-
"""Clean up resources"""
|
|
797
|
-
if self.reviewer:
|
|
798
|
-
await self.reviewer.close()
|
|
1
|
+
"""
|
|
2
|
+
Implementer Agent - Generates and writes production code
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import shutil
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
# Import ReviewerAgent (circular import handled lazily)
|
|
11
|
+
from typing import TYPE_CHECKING, Any
|
|
12
|
+
|
|
13
|
+
from ...context7.agent_integration import Context7AgentHelper, get_context7_helper
|
|
14
|
+
from ...core.agent_base import BaseAgent
|
|
15
|
+
from ...core.config import ProjectConfig, load_config
|
|
16
|
+
from ...core.instructions import CodeGenerationInstruction
|
|
17
|
+
from ...experts.agent_integration import ExpertSupportMixin
|
|
18
|
+
from .code_generator import CodeGenerator
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from ..reviewer.agent import ReviewerAgent
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ImplementerAgent(BaseAgent, ExpertSupportMixin):
|
|
28
|
+
"""
|
|
29
|
+
Implementer Agent - Code generation and file writing.
|
|
30
|
+
|
|
31
|
+
Permissions: Read, Write, Edit, Grep, Glob, Bash
|
|
32
|
+
|
|
33
|
+
⚠️ CRITICAL ACCURACY REQUIREMENT:
|
|
34
|
+
- NEVER make up, invent, or fabricate information - Only report verified facts
|
|
35
|
+
- ALWAYS verify claims by checking actual results, not just test pass/fail
|
|
36
|
+
- Verify API calls succeed - inspect response data, status codes, error messages
|
|
37
|
+
- Distinguish between code paths executing and actual functionality working
|
|
38
|
+
- Admit uncertainty explicitly when you cannot verify
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(
|
|
42
|
+
self,
|
|
43
|
+
config: ProjectConfig | None = None,
|
|
44
|
+
expert_registry: Any | None = None,
|
|
45
|
+
):
|
|
46
|
+
super().__init__(
|
|
47
|
+
agent_id="implementer", agent_name="Implementer Agent", config=config
|
|
48
|
+
)
|
|
49
|
+
# Use config if provided, otherwise load defaults
|
|
50
|
+
if config is None:
|
|
51
|
+
config = load_config()
|
|
52
|
+
self.config = config
|
|
53
|
+
|
|
54
|
+
# Initialize code generator
|
|
55
|
+
self.code_generator = CodeGenerator()
|
|
56
|
+
|
|
57
|
+
# Get implementer config
|
|
58
|
+
implementer_config = (
|
|
59
|
+
config.agents.implementer if config and config.agents else None
|
|
60
|
+
)
|
|
61
|
+
self.require_review = (
|
|
62
|
+
implementer_config.require_review if implementer_config else True
|
|
63
|
+
)
|
|
64
|
+
self.auto_approve_threshold = (
|
|
65
|
+
implementer_config.auto_approve_threshold if implementer_config else 80.0
|
|
66
|
+
)
|
|
67
|
+
self.backup_files = (
|
|
68
|
+
implementer_config.backup_files if implementer_config else True
|
|
69
|
+
)
|
|
70
|
+
self.max_file_size = (
|
|
71
|
+
implementer_config.max_file_size if implementer_config else 10 * 1024 * 1024
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Initialize Context7 helper
|
|
75
|
+
self.context7: Context7AgentHelper | None = None
|
|
76
|
+
if config:
|
|
77
|
+
self.context7 = get_context7_helper(self, config)
|
|
78
|
+
|
|
79
|
+
# Expert registry initialization (required due to multiple inheritance MRO issue)
|
|
80
|
+
# BaseAgent.__init__() doesn't call super().__init__(), so ExpertSupportMixin.__init__()
|
|
81
|
+
# is never called via MRO. We must manually initialize to avoid AttributeError.
|
|
82
|
+
# The registry will be properly initialized in activate() via _initialize_expert_support()
|
|
83
|
+
self.expert_registry: Any | None = None
|
|
84
|
+
# Allow manual override if provided (for testing or special cases)
|
|
85
|
+
if expert_registry:
|
|
86
|
+
self.expert_registry = expert_registry
|
|
87
|
+
|
|
88
|
+
# Reviewer agent for code review
|
|
89
|
+
self.reviewer: ReviewerAgent | None = None
|
|
90
|
+
|
|
91
|
+
async def activate(self, project_root: Path | None = None, offline_mode: bool = False):
|
|
92
|
+
"""Activate the implementer agent with expert support."""
|
|
93
|
+
# Validate that expert_registry attribute exists (safety check)
|
|
94
|
+
if not hasattr(self, 'expert_registry'):
|
|
95
|
+
raise AttributeError(
|
|
96
|
+
f"{self.__class__.__name__}.expert_registry not initialized. "
|
|
97
|
+
"This should not happen if __init__() properly initializes the attribute."
|
|
98
|
+
)
|
|
99
|
+
await super().activate(project_root, offline_mode=offline_mode)
|
|
100
|
+
# Initialize expert support via mixin
|
|
101
|
+
await self._initialize_expert_support(project_root, offline_mode=offline_mode)
|
|
102
|
+
|
|
103
|
+
def get_commands(self) -> list[dict[str, str]]:
|
|
104
|
+
"""Return available commands for implementer agent"""
|
|
105
|
+
base_commands = super().get_commands()
|
|
106
|
+
return base_commands + [
|
|
107
|
+
{
|
|
108
|
+
"command": "*implement",
|
|
109
|
+
"description": "Generate and write code to file (with review)",
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"command": "*generate-code",
|
|
113
|
+
"description": "Generate code from specification (no file write)",
|
|
114
|
+
},
|
|
115
|
+
{"command": "*refactor", "description": "Refactor existing code file"},
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
async def run(self, command: str, **kwargs) -> dict[str, Any]:
|
|
119
|
+
"""
|
|
120
|
+
Execute implementer agent command.
|
|
121
|
+
|
|
122
|
+
Commands:
|
|
123
|
+
- *implement <specification> <file_path>: Generate and write code (with review)
|
|
124
|
+
- *generate-code <specification> [--file=<file_path>]: Generate code only
|
|
125
|
+
- *refactor <file_path> <instruction>: Refactor existing code
|
|
126
|
+
"""
|
|
127
|
+
await self.activate()
|
|
128
|
+
|
|
129
|
+
if command == "help":
|
|
130
|
+
return self._help()
|
|
131
|
+
|
|
132
|
+
elif command == "implement":
|
|
133
|
+
specification = kwargs.get("specification") or kwargs.get("text", "")
|
|
134
|
+
file_path = kwargs.get("file_path") or kwargs.get("file")
|
|
135
|
+
if not specification:
|
|
136
|
+
return {
|
|
137
|
+
"error": "Specification required. Usage: *implement <specification> <file_path>"
|
|
138
|
+
}
|
|
139
|
+
if not file_path:
|
|
140
|
+
return {
|
|
141
|
+
"error": "File path required. Usage: *implement <specification> <file_path>"
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
context = kwargs.get("context")
|
|
145
|
+
language = kwargs.get("language", "python")
|
|
146
|
+
return await self.implement(
|
|
147
|
+
specification, file_path, context=context, language=language
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
elif command == "generate-code":
|
|
151
|
+
specification = kwargs.get("specification") or kwargs.get("text", "")
|
|
152
|
+
if not specification:
|
|
153
|
+
return {
|
|
154
|
+
"error": "Specification required. Usage: *generate-code <specification> [--file=<file_path>]"
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
file_path = kwargs.get("file_path") or kwargs.get("file")
|
|
158
|
+
context = kwargs.get("context")
|
|
159
|
+
language = kwargs.get("language", "python")
|
|
160
|
+
return await self.generate_code(
|
|
161
|
+
specification, file_path=file_path, context=context, language=language
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
elif command == "refactor":
|
|
165
|
+
file_path = kwargs.get("file_path") or kwargs.get("file")
|
|
166
|
+
instruction = kwargs.get("instruction") or kwargs.get("text", "")
|
|
167
|
+
if not file_path:
|
|
168
|
+
return {
|
|
169
|
+
"error": "File path required. Usage: *refactor <file_path> <instruction>"
|
|
170
|
+
}
|
|
171
|
+
if not instruction:
|
|
172
|
+
return {
|
|
173
|
+
"error": "Instruction required. Usage: *refactor <file_path> <instruction>"
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return await self.refactor(file_path, instruction)
|
|
177
|
+
|
|
178
|
+
else:
|
|
179
|
+
return {
|
|
180
|
+
"error": f"Unknown command: {command}. Use *help to see available commands."
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
async def implement(
|
|
184
|
+
self,
|
|
185
|
+
specification: str,
|
|
186
|
+
file_path: str,
|
|
187
|
+
context: str | None = None,
|
|
188
|
+
language: str = "python",
|
|
189
|
+
) -> dict[str, Any]:
|
|
190
|
+
"""
|
|
191
|
+
Generate code from specification and write to file (with review).
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
specification: Description of what code to generate
|
|
195
|
+
file_path: Target file path
|
|
196
|
+
context: Optional context (existing code, patterns, etc.)
|
|
197
|
+
language: Programming language
|
|
198
|
+
|
|
199
|
+
Returns:
|
|
200
|
+
Result dictionary with code, file path, review results, etc.
|
|
201
|
+
"""
|
|
202
|
+
path = Path(file_path)
|
|
203
|
+
|
|
204
|
+
# Validate path
|
|
205
|
+
if not self._is_valid_path(path):
|
|
206
|
+
return {"error": f"Invalid or unsafe path: {file_path}"}
|
|
207
|
+
|
|
208
|
+
# Check if file exists
|
|
209
|
+
file_exists = path.exists()
|
|
210
|
+
|
|
211
|
+
# Consult experts for code generation guidance
|
|
212
|
+
expert_guidance = {}
|
|
213
|
+
# Use defensive check to ensure attribute exists (safety for MRO issue)
|
|
214
|
+
if hasattr(self, 'expert_registry') and self.expert_registry:
|
|
215
|
+
# Consult Security expert for secure coding practices
|
|
216
|
+
try:
|
|
217
|
+
security_consultation = await self.expert_registry.consult(
|
|
218
|
+
query=f"Secure coding practices for: {specification}. Language: {language}",
|
|
219
|
+
domain="security",
|
|
220
|
+
include_all=True,
|
|
221
|
+
prioritize_builtin=True,
|
|
222
|
+
agent_id="implementer",
|
|
223
|
+
)
|
|
224
|
+
expert_guidance["security"] = security_consultation.weighted_answer
|
|
225
|
+
except Exception:
|
|
226
|
+
logger.debug("Security expert consultation failed", exc_info=True)
|
|
227
|
+
|
|
228
|
+
# Consult Performance expert for performance optimization
|
|
229
|
+
try:
|
|
230
|
+
perf_consultation = await self.expert_registry.consult(
|
|
231
|
+
query=f"Performance optimization for code: {specification}",
|
|
232
|
+
domain="performance-optimization",
|
|
233
|
+
include_all=True,
|
|
234
|
+
prioritize_builtin=True,
|
|
235
|
+
agent_id="implementer",
|
|
236
|
+
)
|
|
237
|
+
expert_guidance["performance"] = perf_consultation.weighted_answer
|
|
238
|
+
except Exception:
|
|
239
|
+
logger.debug("Performance expert consultation failed", exc_info=True)
|
|
240
|
+
|
|
241
|
+
# Consult API Design expert if implementing/refactoring an API client
|
|
242
|
+
if await self._detect_api_client_pattern(specification, context):
|
|
243
|
+
try:
|
|
244
|
+
api_consultation = await self.expert_registry.consult(
|
|
245
|
+
query=f"Provide implementation guidance for this API client:\n\n{specification}",
|
|
246
|
+
domain="api-design-integration",
|
|
247
|
+
include_all=True,
|
|
248
|
+
prioritize_builtin=True,
|
|
249
|
+
agent_id="implementer",
|
|
250
|
+
)
|
|
251
|
+
expert_guidance["api_design"] = api_consultation.weighted_answer
|
|
252
|
+
except Exception:
|
|
253
|
+
logger.debug("API design expert consultation failed", exc_info=True)
|
|
254
|
+
|
|
255
|
+
# R7: Get Context7 documentation for libraries mentioned in specification
|
|
256
|
+
context7_docs = {}
|
|
257
|
+
if self.context7 and self.context7.enabled:
|
|
258
|
+
try:
|
|
259
|
+
# Detect libraries from specification and context
|
|
260
|
+
detected_libraries = []
|
|
261
|
+
if self.context7.library_detector:
|
|
262
|
+
# R7: Detect from specification text (prompt)
|
|
263
|
+
detected_libraries.extend(
|
|
264
|
+
self.context7.library_detector.detect_from_prompt(specification)
|
|
265
|
+
)
|
|
266
|
+
# Detect from context code if available
|
|
267
|
+
if context:
|
|
268
|
+
detected_libraries.extend(
|
|
269
|
+
self.context7.library_detector.detect_from_code(context, language=language)
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
# Get Context7 documentation for each detected library
|
|
273
|
+
for library in set(detected_libraries): # Remove duplicates
|
|
274
|
+
try:
|
|
275
|
+
docs_result = await self.context7.get_documentation(library, topic=None, use_fuzzy_match=True)
|
|
276
|
+
if docs_result and docs_result.get("content"):
|
|
277
|
+
context7_docs[library] = docs_result["content"]
|
|
278
|
+
logger.debug(f"Retrieved Context7 docs for library '{library}'")
|
|
279
|
+
except Exception as e:
|
|
280
|
+
logger.debug(f"Failed to get Context7 docs for library '{library}': {e}")
|
|
281
|
+
except Exception as e:
|
|
282
|
+
logger.debug(f"Context7 documentation lookup failed: {e}", exc_info=True)
|
|
283
|
+
|
|
284
|
+
# Prepare code generation instruction for Cursor Skills
|
|
285
|
+
try:
|
|
286
|
+
instruction = self.code_generator.prepare_code_generation(
|
|
287
|
+
specification=specification,
|
|
288
|
+
file_path=path,
|
|
289
|
+
context=context,
|
|
290
|
+
language=language,
|
|
291
|
+
expert_guidance=expert_guidance,
|
|
292
|
+
context7_docs=context7_docs if context7_docs else None,
|
|
293
|
+
)
|
|
294
|
+
except Exception as e:
|
|
295
|
+
return {"error": f"Failed to prepare code generation instruction: {str(e)}"}
|
|
296
|
+
|
|
297
|
+
# Return instruction object for Cursor Skills execution
|
|
298
|
+
skill_command = instruction.to_skill_command()
|
|
299
|
+
result = {
|
|
300
|
+
"type": "implement",
|
|
301
|
+
"execution_mode": "cursor_skills", # Explicit mode indication
|
|
302
|
+
"instruction": instruction.to_dict(),
|
|
303
|
+
"skill_command": skill_command,
|
|
304
|
+
"file": str(path),
|
|
305
|
+
"file_existed": file_exists,
|
|
306
|
+
"next_steps": [
|
|
307
|
+
"This instruction is prepared for Cursor Skills execution.",
|
|
308
|
+
"To execute, copy this command to Cursor chat:",
|
|
309
|
+
f" {skill_command}",
|
|
310
|
+
"",
|
|
311
|
+
"Or use Cursor Skills directly:",
|
|
312
|
+
f" @implementer *implement \"{specification}\" {file_path}",
|
|
313
|
+
"",
|
|
314
|
+
"Note: Code generation requires Cursor Skills (uses your configured LLM).",
|
|
315
|
+
"The framework prepares instructions; Cursor Skills execute them.",
|
|
316
|
+
],
|
|
317
|
+
}
|
|
318
|
+
if expert_guidance:
|
|
319
|
+
result["expert_guidance"] = expert_guidance
|
|
320
|
+
return result
|
|
321
|
+
|
|
322
|
+
async def generate_code(
|
|
323
|
+
self,
|
|
324
|
+
specification: str,
|
|
325
|
+
file_path: str | None = None,
|
|
326
|
+
context: str | None = None,
|
|
327
|
+
language: str = "python",
|
|
328
|
+
) -> dict[str, Any]:
|
|
329
|
+
"""
|
|
330
|
+
Generate code from specification (no file write).
|
|
331
|
+
|
|
332
|
+
Args:
|
|
333
|
+
specification: Description of what code to generate
|
|
334
|
+
file_path: Optional target file path for context
|
|
335
|
+
context: Optional context
|
|
336
|
+
language: Programming language
|
|
337
|
+
|
|
338
|
+
Returns:
|
|
339
|
+
Result dictionary with generated code
|
|
340
|
+
"""
|
|
341
|
+
path = Path(file_path) if file_path else None
|
|
342
|
+
|
|
343
|
+
if path and not self._is_valid_path(path):
|
|
344
|
+
return {"error": f"Invalid or unsafe path: {file_path}"}
|
|
345
|
+
|
|
346
|
+
# Consult experts for code generation guidance
|
|
347
|
+
expert_guidance = {}
|
|
348
|
+
# Use defensive check to ensure attribute exists (safety for MRO issue)
|
|
349
|
+
if hasattr(self, 'expert_registry') and self.expert_registry:
|
|
350
|
+
try:
|
|
351
|
+
security_consultation = await self.expert_registry.consult(
|
|
352
|
+
query=f"Secure coding practices for: {specification}",
|
|
353
|
+
domain="security",
|
|
354
|
+
include_all=True,
|
|
355
|
+
prioritize_builtin=True,
|
|
356
|
+
agent_id="implementer",
|
|
357
|
+
)
|
|
358
|
+
expert_guidance["security"] = security_consultation.weighted_answer
|
|
359
|
+
except Exception:
|
|
360
|
+
logger.debug("Security expert consultation failed", exc_info=True)
|
|
361
|
+
|
|
362
|
+
try:
|
|
363
|
+
perf_consultation = await self.expert_registry.consult(
|
|
364
|
+
query=f"Performance optimization for: {specification}",
|
|
365
|
+
domain="performance-optimization",
|
|
366
|
+
include_all=True,
|
|
367
|
+
prioritize_builtin=True,
|
|
368
|
+
agent_id="implementer",
|
|
369
|
+
)
|
|
370
|
+
expert_guidance["performance"] = perf_consultation.weighted_answer
|
|
371
|
+
except Exception:
|
|
372
|
+
logger.debug("Performance expert consultation failed", exc_info=True)
|
|
373
|
+
|
|
374
|
+
# Consult API Design expert if implementing/refactoring an API client
|
|
375
|
+
if await self._detect_api_client_pattern(specification, context):
|
|
376
|
+
try:
|
|
377
|
+
api_consultation = await self.expert_registry.consult(
|
|
378
|
+
query=f"Provide implementation guidance for this API client:\n\n{specification}",
|
|
379
|
+
domain="api-design-integration",
|
|
380
|
+
include_all=True,
|
|
381
|
+
prioritize_builtin=True,
|
|
382
|
+
agent_id="implementer",
|
|
383
|
+
)
|
|
384
|
+
expert_guidance["api_design"] = api_consultation.weighted_answer
|
|
385
|
+
except Exception:
|
|
386
|
+
logger.debug("API design expert consultation failed", exc_info=True)
|
|
387
|
+
|
|
388
|
+
try:
|
|
389
|
+
instruction = self.code_generator.prepare_code_generation(
|
|
390
|
+
specification=specification,
|
|
391
|
+
file_path=path,
|
|
392
|
+
context=context,
|
|
393
|
+
language=language,
|
|
394
|
+
expert_guidance=expert_guidance,
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
result: dict[str, Any] = {
|
|
398
|
+
"type": "generate_code",
|
|
399
|
+
"instruction": instruction.to_dict(),
|
|
400
|
+
"skill_command": instruction.to_skill_command(),
|
|
401
|
+
"file_path": str(path) if path else None,
|
|
402
|
+
"language": language,
|
|
403
|
+
}
|
|
404
|
+
if expert_guidance:
|
|
405
|
+
result["expert_guidance"] = expert_guidance
|
|
406
|
+
return result
|
|
407
|
+
except Exception as e:
|
|
408
|
+
return {"error": f"Failed to prepare code generation instruction: {str(e)}"}
|
|
409
|
+
|
|
410
|
+
async def refactor(
|
|
411
|
+
self, file_path: str, instruction: str, preview: bool = False
|
|
412
|
+
) -> dict[str, Any]:
|
|
413
|
+
"""
|
|
414
|
+
Refactor existing code file.
|
|
415
|
+
|
|
416
|
+
Phase 5.1: Enhanced file writing with validation and ErrorEnvelope
|
|
417
|
+
|
|
418
|
+
Args:
|
|
419
|
+
file_path: Path to file to refactor
|
|
420
|
+
instruction: Refactoring instruction
|
|
421
|
+
preview: If True, return refactored code without writing to file (default: False)
|
|
422
|
+
|
|
423
|
+
Returns:
|
|
424
|
+
Result dictionary with refactored code and file path, or ErrorEnvelope on error
|
|
425
|
+
"""
|
|
426
|
+
from ...core.error_envelope import ErrorEnvelopeBuilder
|
|
427
|
+
|
|
428
|
+
path = Path(file_path)
|
|
429
|
+
|
|
430
|
+
# Validate path with ErrorEnvelope
|
|
431
|
+
if not path.exists():
|
|
432
|
+
envelope = ErrorEnvelopeBuilder.from_exception(
|
|
433
|
+
FileNotFoundError(f"File not found: {file_path}"),
|
|
434
|
+
agent="implementer",
|
|
435
|
+
)
|
|
436
|
+
return envelope.to_dict()
|
|
437
|
+
|
|
438
|
+
if not self._is_valid_path(path):
|
|
439
|
+
envelope = ErrorEnvelopeBuilder.from_exception(
|
|
440
|
+
ValueError(f"Invalid or unsafe path: {file_path}"),
|
|
441
|
+
agent="implementer",
|
|
442
|
+
)
|
|
443
|
+
return envelope.to_dict()
|
|
444
|
+
|
|
445
|
+
# Read existing code with enhanced error handling
|
|
446
|
+
try:
|
|
447
|
+
existing_code = path.read_text(encoding="utf-8")
|
|
448
|
+
if not existing_code.strip():
|
|
449
|
+
envelope = ErrorEnvelopeBuilder.from_exception(
|
|
450
|
+
ValueError(f"File is empty: {file_path}"),
|
|
451
|
+
agent="implementer",
|
|
452
|
+
)
|
|
453
|
+
return envelope.to_dict()
|
|
454
|
+
except UnicodeDecodeError as e:
|
|
455
|
+
envelope = ErrorEnvelopeBuilder.from_exception(
|
|
456
|
+
e,
|
|
457
|
+
agent="implementer",
|
|
458
|
+
)
|
|
459
|
+
envelope.message = f"Failed to read file (encoding error): {file_path}. File may not be text-based."
|
|
460
|
+
return envelope.to_dict()
|
|
461
|
+
except Exception as e:
|
|
462
|
+
envelope = ErrorEnvelopeBuilder.from_exception(
|
|
463
|
+
e,
|
|
464
|
+
agent="implementer",
|
|
465
|
+
)
|
|
466
|
+
envelope.message = f"Failed to read file: {file_path}. {envelope.message}"
|
|
467
|
+
return envelope.to_dict()
|
|
468
|
+
|
|
469
|
+
# Detect language from file extension
|
|
470
|
+
language = self._detect_language(path)
|
|
471
|
+
|
|
472
|
+
# Prepare refactoring instruction for Cursor Skills with enhanced error handling
|
|
473
|
+
try:
|
|
474
|
+
refactor_instruction = self.code_generator.prepare_refactoring(
|
|
475
|
+
code=existing_code, instruction=instruction, language=language
|
|
476
|
+
)
|
|
477
|
+
except Exception as e:
|
|
478
|
+
envelope = ErrorEnvelopeBuilder.from_exception(
|
|
479
|
+
e,
|
|
480
|
+
agent="implementer",
|
|
481
|
+
)
|
|
482
|
+
envelope.message = f"Failed to prepare refactoring instruction: {envelope.message}"
|
|
483
|
+
return envelope.to_dict()
|
|
484
|
+
|
|
485
|
+
# Create backup before refactoring (best-effort, don't fail if backup fails)
|
|
486
|
+
backup_path = None
|
|
487
|
+
try:
|
|
488
|
+
backup_path = self._create_backup(path)
|
|
489
|
+
except Exception as e:
|
|
490
|
+
# Log warning but continue (backup failure shouldn't block refactoring)
|
|
491
|
+
import logging
|
|
492
|
+
|
|
493
|
+
logger = logging.getLogger(__name__)
|
|
494
|
+
logger.warning(f"Failed to create backup for {file_path}: {e}")
|
|
495
|
+
|
|
496
|
+
# Refactored code: in Cursor mode, the skill_command is executed by Cursor Skills
|
|
497
|
+
# (user's model), which performs the edit. In headless/CLI mode, code generation
|
|
498
|
+
# would require MAL/LLM; when available, we would set refactored_code and write.
|
|
499
|
+
refactored_code: str | None = None # Set when MAL/LLM generates in headless mode
|
|
500
|
+
|
|
501
|
+
result = {
|
|
502
|
+
"type": "refactor",
|
|
503
|
+
"file": str(path),
|
|
504
|
+
"original_code": existing_code,
|
|
505
|
+
"instruction": refactor_instruction.to_dict(),
|
|
506
|
+
"skill_command": refactor_instruction.to_skill_command(),
|
|
507
|
+
"backup": str(backup_path) if backup_path else None,
|
|
508
|
+
"preview": preview,
|
|
509
|
+
"approved": True, # Would be set based on review/approval
|
|
510
|
+
"refactored_code": refactored_code,
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
# When not preview and MAL/LLM is available, we would generate refactored_code
|
|
514
|
+
# and write to path. For now, writing is delegated to Cursor Skills via skill_command.
|
|
515
|
+
return result
|
|
516
|
+
|
|
517
|
+
async def _review_code(self, code: str, file_path: Path) -> dict[str, Any] | None:
|
|
518
|
+
"""Review generated code using ReviewerAgent."""
|
|
519
|
+
if self.reviewer is None:
|
|
520
|
+
# Lazy import to avoid circular dependency
|
|
521
|
+
from ...agents.reviewer.agent import ReviewerAgent
|
|
522
|
+
|
|
523
|
+
self.reviewer = ReviewerAgent(config=self.config)
|
|
524
|
+
await self.reviewer.activate()
|
|
525
|
+
|
|
526
|
+
# Create temporary file for review
|
|
527
|
+
import tempfile
|
|
528
|
+
|
|
529
|
+
with tempfile.NamedTemporaryFile(
|
|
530
|
+
mode="w", suffix=file_path.suffix, delete=False
|
|
531
|
+
) as tmp_file:
|
|
532
|
+
tmp_file.write(code)
|
|
533
|
+
tmp_file_path = Path(tmp_file.name)
|
|
534
|
+
|
|
535
|
+
try:
|
|
536
|
+
# Review the code
|
|
537
|
+
review_result = await self.reviewer.review_file(tmp_file_path)
|
|
538
|
+
return review_result
|
|
539
|
+
except Exception as e:
|
|
540
|
+
# Review failed, but don't block if it's just an error
|
|
541
|
+
return {"error": f"Review failed: {str(e)}"}
|
|
542
|
+
finally:
|
|
543
|
+
# Clean up temp file
|
|
544
|
+
if tmp_file_path.exists():
|
|
545
|
+
tmp_file_path.unlink()
|
|
546
|
+
|
|
547
|
+
def _is_valid_path(self, path: Path) -> bool:
|
|
548
|
+
"""Return True if file path appears safe and within size constraints."""
|
|
549
|
+
# Resolve to absolute path
|
|
550
|
+
try:
|
|
551
|
+
resolved = path.resolve()
|
|
552
|
+
except Exception:
|
|
553
|
+
return False
|
|
554
|
+
|
|
555
|
+
# Check for path traversal
|
|
556
|
+
if ".." in str(path) and not resolved.exists():
|
|
557
|
+
return False
|
|
558
|
+
|
|
559
|
+
# Check for suspicious patterns
|
|
560
|
+
suspicious = ["%00", "%2e", "%2f", "..", "//"]
|
|
561
|
+
path_str = str(path)
|
|
562
|
+
if any(pattern in path_str for pattern in suspicious):
|
|
563
|
+
# Allow pytest temp files
|
|
564
|
+
if "pytest-" not in path_str:
|
|
565
|
+
return False
|
|
566
|
+
|
|
567
|
+
# Check file size if file exists
|
|
568
|
+
if resolved.exists() and resolved.is_file():
|
|
569
|
+
try:
|
|
570
|
+
if resolved.stat().st_size > self.max_file_size:
|
|
571
|
+
return False
|
|
572
|
+
except Exception:
|
|
573
|
+
return False
|
|
574
|
+
|
|
575
|
+
return True
|
|
576
|
+
|
|
577
|
+
def _create_backup(self, path: Path) -> Path | None:
|
|
578
|
+
"""
|
|
579
|
+
Create backup of existing file.
|
|
580
|
+
|
|
581
|
+
Phase 5.1: Enhanced backup creation with validation
|
|
582
|
+
"""
|
|
583
|
+
if not path.exists():
|
|
584
|
+
return None
|
|
585
|
+
|
|
586
|
+
try:
|
|
587
|
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
588
|
+
backup_path = path.parent / f"{path.stem}.backup_{timestamp}{path.suffix}"
|
|
589
|
+
shutil.copy2(path, backup_path)
|
|
590
|
+
|
|
591
|
+
# Validate backup was created correctly (Phase 5.1: Write Validation)
|
|
592
|
+
if backup_path.exists() and backup_path.stat().st_size == path.stat().st_size:
|
|
593
|
+
return backup_path
|
|
594
|
+
else:
|
|
595
|
+
# Backup file size mismatch, clean up and return None
|
|
596
|
+
if backup_path.exists():
|
|
597
|
+
backup_path.unlink()
|
|
598
|
+
logger.warning(f"Backup validation failed for {path}, backup not created")
|
|
599
|
+
return None
|
|
600
|
+
except Exception as e:
|
|
601
|
+
logger.warning(f"Failed to create backup for {path}: {e}")
|
|
602
|
+
return None
|
|
603
|
+
|
|
604
|
+
def _detect_language(self, path: Path) -> str:
|
|
605
|
+
"""Detect programming language from file extension."""
|
|
606
|
+
extension_map = {
|
|
607
|
+
".py": "python",
|
|
608
|
+
".js": "javascript",
|
|
609
|
+
".ts": "typescript",
|
|
610
|
+
".java": "java",
|
|
611
|
+
".cpp": "cpp",
|
|
612
|
+
".c": "c",
|
|
613
|
+
".rs": "rust",
|
|
614
|
+
".go": "go",
|
|
615
|
+
".rb": "ruby",
|
|
616
|
+
".php": "php",
|
|
617
|
+
".swift": "swift",
|
|
618
|
+
".kt": "kotlin",
|
|
619
|
+
".md": "markdown",
|
|
620
|
+
".yaml": "yaml",
|
|
621
|
+
".yml": "yaml",
|
|
622
|
+
}
|
|
623
|
+
return extension_map.get(path.suffix.lower(), "python")
|
|
624
|
+
|
|
625
|
+
async def _detect_api_client_pattern(self, specification: str, context: str | None = None) -> bool:
|
|
626
|
+
"""
|
|
627
|
+
Detect if specification/context indicates an HTTP/API client implementation.
|
|
628
|
+
|
|
629
|
+
Checks for common patterns that indicate API client code:
|
|
630
|
+
- Keywords: "API client", "OAuth2", "refresh token", "external API", "HTTP client"
|
|
631
|
+
- Authentication patterns: "Bearer", "token", "authentication"
|
|
632
|
+
- API patterns: "REST API", "API integration", "third-party API"
|
|
633
|
+
|
|
634
|
+
Args:
|
|
635
|
+
specification: Code specification/description
|
|
636
|
+
context: Optional context code
|
|
637
|
+
|
|
638
|
+
Returns:
|
|
639
|
+
True if specification appears to be for an API client, False otherwise
|
|
640
|
+
"""
|
|
641
|
+
if not specification:
|
|
642
|
+
return False
|
|
643
|
+
|
|
644
|
+
# Combine specification and context for analysis
|
|
645
|
+
text_to_analyze = specification.lower()
|
|
646
|
+
if context:
|
|
647
|
+
text_to_analyze += " " + context.lower()
|
|
648
|
+
|
|
649
|
+
# API client keywords (enhanced)
|
|
650
|
+
api_client_keywords = [
|
|
651
|
+
"api client",
|
|
652
|
+
"http client",
|
|
653
|
+
"rest client",
|
|
654
|
+
"oauth2",
|
|
655
|
+
"oauth 2",
|
|
656
|
+
"oauth",
|
|
657
|
+
"refresh token",
|
|
658
|
+
"access token",
|
|
659
|
+
"external api",
|
|
660
|
+
"third-party api",
|
|
661
|
+
"api integration",
|
|
662
|
+
"rest api",
|
|
663
|
+
"api wrapper",
|
|
664
|
+
"graphql client",
|
|
665
|
+
"graphql api",
|
|
666
|
+
"websocket client",
|
|
667
|
+
"mqtt client",
|
|
668
|
+
"grpc client",
|
|
669
|
+
]
|
|
670
|
+
|
|
671
|
+
# Authentication keywords (enhanced with OAuth2 patterns)
|
|
672
|
+
auth_keywords = [
|
|
673
|
+
"bearer",
|
|
674
|
+
"token", # General token (covers access, refresh, bearer, etc.)
|
|
675
|
+
"authentication",
|
|
676
|
+
"authorization",
|
|
677
|
+
"api key",
|
|
678
|
+
"api_key",
|
|
679
|
+
"apikey",
|
|
680
|
+
"client_id",
|
|
681
|
+
"client_secret",
|
|
682
|
+
"token_url",
|
|
683
|
+
"api_base_url",
|
|
684
|
+
"jwt",
|
|
685
|
+
"id_token",
|
|
686
|
+
"grant_type",
|
|
687
|
+
"authorization_code",
|
|
688
|
+
"client_credentials",
|
|
689
|
+
"credentials", # General credentials
|
|
690
|
+
"auth", # Short form
|
|
691
|
+
]
|
|
692
|
+
|
|
693
|
+
# Structure keywords (enhanced with framework patterns)
|
|
694
|
+
structure_keywords = [
|
|
695
|
+
"class.*client",
|
|
696
|
+
"get method",
|
|
697
|
+
"post method",
|
|
698
|
+
"put method",
|
|
699
|
+
"delete method",
|
|
700
|
+
"patch method",
|
|
701
|
+
"api endpoint",
|
|
702
|
+
"endpoint", # General endpoint
|
|
703
|
+
"rest endpoint",
|
|
704
|
+
"make request",
|
|
705
|
+
"http request",
|
|
706
|
+
"fastapi",
|
|
707
|
+
"django rest",
|
|
708
|
+
"api route",
|
|
709
|
+
"router", # General router
|
|
710
|
+
]
|
|
711
|
+
|
|
712
|
+
# Check for API client keywords
|
|
713
|
+
has_api_keywords = any(keyword in text_to_analyze for keyword in api_client_keywords)
|
|
714
|
+
|
|
715
|
+
# Check for authentication patterns
|
|
716
|
+
has_auth = any(keyword in text_to_analyze for keyword in auth_keywords)
|
|
717
|
+
|
|
718
|
+
# Check for structure patterns
|
|
719
|
+
has_structure = any(keyword in text_to_analyze for keyword in structure_keywords)
|
|
720
|
+
|
|
721
|
+
# Specification is likely for an API client if it has API keywords AND (auth OR structure)
|
|
722
|
+
return has_api_keywords and (has_auth or has_structure)
|
|
723
|
+
|
|
724
|
+
def _help(self) -> dict[str, Any]:
|
|
725
|
+
"""
|
|
726
|
+
Return help information for Implementer Agent.
|
|
727
|
+
|
|
728
|
+
Returns standardized help format with commands, examples, configuration,
|
|
729
|
+
and safety features documentation.
|
|
730
|
+
|
|
731
|
+
Returns:
|
|
732
|
+
dict: Help information with standardized format:
|
|
733
|
+
- type (str): Always "help"
|
|
734
|
+
- content (str): Formatted markdown help text containing:
|
|
735
|
+
- Available commands list
|
|
736
|
+
- Usage examples for implement, generate-code, refactor
|
|
737
|
+
- Configuration options
|
|
738
|
+
- Safety features documentation
|
|
739
|
+
|
|
740
|
+
Note:
|
|
741
|
+
This method is synchronous as it performs no I/O operations.
|
|
742
|
+
Called via agent.run("help") which handles async context.
|
|
743
|
+
Command list is cached via BaseAgent.get_commands() for performance.
|
|
744
|
+
"""
|
|
745
|
+
commands = self.get_commands()
|
|
746
|
+
command_lines = [
|
|
747
|
+
f"- **{cmd['command']}**: {cmd['description']}"
|
|
748
|
+
for cmd in commands
|
|
749
|
+
]
|
|
750
|
+
|
|
751
|
+
content = f"""# {self.agent_name} - Help
|
|
752
|
+
|
|
753
|
+
## Available Commands
|
|
754
|
+
|
|
755
|
+
{chr(10).join(command_lines)}
|
|
756
|
+
|
|
757
|
+
## Usage Examples
|
|
758
|
+
|
|
759
|
+
### Implement (Generate and Write)
|
|
760
|
+
```
|
|
761
|
+
*implement "Create a function to calculate factorial" factorial.py
|
|
762
|
+
*implement "Add user authentication endpoint" api/auth.py --context="Use FastAPI patterns"
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
### Generate Code (No Write)
|
|
766
|
+
```
|
|
767
|
+
*generate-code "Create a REST API client class"
|
|
768
|
+
*generate-code "Add data validation function" --file=utils/validation.py
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
### Refactor
|
|
772
|
+
```
|
|
773
|
+
*refactor utils/helpers.py "Extract common logic into helper functions"
|
|
774
|
+
*refactor models.py "Improve error handling and add type hints"
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
## Configuration
|
|
778
|
+
|
|
779
|
+
- **require_review**: Require code review before writing (default: true)
|
|
780
|
+
- **auto_approve_threshold**: Auto-approve if score >= threshold (default: 80.0)
|
|
781
|
+
- **backup_files**: Create backup before overwriting (default: true)
|
|
782
|
+
- **max_file_size**: Maximum file size in bytes (default: 10MB)
|
|
783
|
+
|
|
784
|
+
## Safety Features
|
|
785
|
+
|
|
786
|
+
- ✅ Code review before writing (integrated with Reviewer Agent)
|
|
787
|
+
- ✅ File backups before overwriting
|
|
788
|
+
- ✅ Path validation (prevents path traversal)
|
|
789
|
+
- ✅ File size limits
|
|
790
|
+
- ✅ Automatic rollback on write failure
|
|
791
|
+
"""
|
|
792
|
+
|
|
793
|
+
return {"type": "help", "content": content}
|
|
794
|
+
|
|
795
|
+
async def close(self):
|
|
796
|
+
"""Clean up resources"""
|
|
797
|
+
if self.reviewer:
|
|
798
|
+
await self.reviewer.close()
|