tapps-agents 3.6.0__py3-none-any.whl → 3.6.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tapps_agents/__init__.py +2 -2
- tapps_agents/agents/__init__.py +22 -22
- tapps_agents/agents/analyst/__init__.py +5 -5
- tapps_agents/agents/architect/__init__.py +5 -5
- tapps_agents/agents/architect/agent.py +1033 -1033
- tapps_agents/agents/architect/pattern_detector.py +75 -75
- tapps_agents/agents/cleanup/__init__.py +7 -7
- tapps_agents/agents/cleanup/agent.py +445 -445
- tapps_agents/agents/debugger/__init__.py +7 -7
- tapps_agents/agents/debugger/agent.py +310 -310
- tapps_agents/agents/debugger/error_analyzer.py +437 -437
- tapps_agents/agents/designer/__init__.py +5 -5
- tapps_agents/agents/designer/agent.py +786 -786
- tapps_agents/agents/designer/visual_designer.py +638 -638
- tapps_agents/agents/documenter/__init__.py +7 -7
- tapps_agents/agents/documenter/agent.py +531 -531
- tapps_agents/agents/documenter/doc_generator.py +472 -472
- tapps_agents/agents/documenter/doc_validator.py +393 -393
- tapps_agents/agents/documenter/framework_doc_updater.py +493 -493
- tapps_agents/agents/enhancer/__init__.py +7 -7
- tapps_agents/agents/evaluator/__init__.py +7 -7
- tapps_agents/agents/evaluator/agent.py +443 -443
- tapps_agents/agents/evaluator/priority_evaluator.py +641 -641
- tapps_agents/agents/evaluator/quality_analyzer.py +147 -147
- tapps_agents/agents/evaluator/report_generator.py +344 -344
- tapps_agents/agents/evaluator/usage_analyzer.py +192 -192
- tapps_agents/agents/evaluator/workflow_analyzer.py +189 -189
- tapps_agents/agents/implementer/__init__.py +7 -7
- tapps_agents/agents/implementer/agent.py +798 -798
- tapps_agents/agents/implementer/auto_fix.py +1119 -1119
- tapps_agents/agents/implementer/code_generator.py +73 -73
- tapps_agents/agents/improver/__init__.py +1 -1
- tapps_agents/agents/improver/agent.py +753 -753
- tapps_agents/agents/ops/__init__.py +1 -1
- tapps_agents/agents/ops/agent.py +619 -619
- tapps_agents/agents/ops/dependency_analyzer.py +600 -600
- tapps_agents/agents/orchestrator/__init__.py +5 -5
- tapps_agents/agents/orchestrator/agent.py +522 -522
- tapps_agents/agents/planner/__init__.py +7 -7
- tapps_agents/agents/planner/agent.py +1127 -1127
- tapps_agents/agents/reviewer/__init__.py +24 -24
- tapps_agents/agents/reviewer/agent.py +3513 -3513
- tapps_agents/agents/reviewer/aggregator.py +213 -213
- tapps_agents/agents/reviewer/batch_review.py +448 -448
- tapps_agents/agents/reviewer/cache.py +443 -443
- tapps_agents/agents/reviewer/context7_enhancer.py +630 -630
- tapps_agents/agents/reviewer/context_detector.py +203 -203
- tapps_agents/agents/reviewer/docker_compose_validator.py +158 -158
- tapps_agents/agents/reviewer/dockerfile_validator.py +176 -176
- tapps_agents/agents/reviewer/error_handling.py +126 -126
- tapps_agents/agents/reviewer/feedback_generator.py +490 -490
- tapps_agents/agents/reviewer/influxdb_validator.py +316 -316
- tapps_agents/agents/reviewer/issue_tracking.py +169 -169
- tapps_agents/agents/reviewer/library_detector.py +295 -295
- tapps_agents/agents/reviewer/library_patterns.py +268 -268
- tapps_agents/agents/reviewer/maintainability_scorer.py +593 -593
- tapps_agents/agents/reviewer/metric_strategies.py +276 -276
- tapps_agents/agents/reviewer/mqtt_validator.py +160 -160
- tapps_agents/agents/reviewer/output_enhancer.py +105 -105
- tapps_agents/agents/reviewer/pattern_detector.py +241 -241
- tapps_agents/agents/reviewer/performance_scorer.py +357 -357
- tapps_agents/agents/reviewer/phased_review.py +516 -516
- tapps_agents/agents/reviewer/progressive_review.py +435 -435
- tapps_agents/agents/reviewer/react_scorer.py +331 -331
- tapps_agents/agents/reviewer/score_constants.py +228 -228
- tapps_agents/agents/reviewer/score_validator.py +507 -507
- tapps_agents/agents/reviewer/scorer_registry.py +373 -373
- tapps_agents/agents/reviewer/service_discovery.py +534 -534
- tapps_agents/agents/reviewer/tools/parallel_executor.py +581 -581
- tapps_agents/agents/reviewer/tools/ruff_grouping.py +250 -250
- tapps_agents/agents/reviewer/tools/scoped_mypy.py +284 -284
- tapps_agents/agents/reviewer/typescript_scorer.py +1142 -1142
- tapps_agents/agents/reviewer/validation.py +208 -208
- tapps_agents/agents/reviewer/websocket_validator.py +132 -132
- tapps_agents/agents/tester/__init__.py +7 -7
- tapps_agents/agents/tester/accessibility_auditor.py +309 -309
- tapps_agents/agents/tester/agent.py +1080 -1080
- tapps_agents/agents/tester/batch_generator.py +54 -54
- tapps_agents/agents/tester/context_learner.py +51 -51
- tapps_agents/agents/tester/coverage_analyzer.py +386 -386
- tapps_agents/agents/tester/coverage_test_generator.py +290 -290
- tapps_agents/agents/tester/debug_enhancer.py +238 -238
- tapps_agents/agents/tester/device_emulator.py +241 -241
- tapps_agents/agents/tester/integration_generator.py +62 -62
- tapps_agents/agents/tester/network_recorder.py +300 -300
- tapps_agents/agents/tester/performance_monitor.py +320 -320
- tapps_agents/agents/tester/test_fixer.py +316 -316
- tapps_agents/agents/tester/test_generator.py +632 -632
- tapps_agents/agents/tester/trace_manager.py +234 -234
- tapps_agents/agents/tester/visual_regression.py +291 -291
- tapps_agents/analysis/pattern_detector.py +36 -36
- tapps_agents/beads/hydration.py +213 -213
- tapps_agents/beads/parse.py +32 -32
- tapps_agents/beads/specs.py +206 -206
- tapps_agents/cli/__init__.py +9 -9
- tapps_agents/cli/__main__.py +8 -8
- tapps_agents/cli/base.py +478 -478
- tapps_agents/cli/command_classifier.py +72 -72
- tapps_agents/cli/commands/__init__.py +2 -2
- tapps_agents/cli/commands/analyst.py +173 -173
- tapps_agents/cli/commands/architect.py +109 -109
- tapps_agents/cli/commands/cleanup_agent.py +92 -92
- tapps_agents/cli/commands/common.py +126 -126
- tapps_agents/cli/commands/debugger.py +90 -90
- tapps_agents/cli/commands/designer.py +112 -112
- tapps_agents/cli/commands/documenter.py +136 -136
- tapps_agents/cli/commands/enhancer.py +110 -110
- tapps_agents/cli/commands/evaluator.py +255 -255
- tapps_agents/cli/commands/implementer.py +301 -301
- tapps_agents/cli/commands/improver.py +91 -91
- tapps_agents/cli/commands/knowledge.py +111 -111
- tapps_agents/cli/commands/learning.py +172 -172
- tapps_agents/cli/commands/observability.py +283 -283
- tapps_agents/cli/commands/ops.py +135 -135
- tapps_agents/cli/commands/orchestrator.py +116 -116
- tapps_agents/cli/commands/planner.py +237 -237
- tapps_agents/cli/commands/reviewer.py +1872 -1872
- tapps_agents/cli/commands/status.py +285 -285
- tapps_agents/cli/commands/task.py +227 -227
- tapps_agents/cli/commands/tester.py +191 -191
- tapps_agents/cli/feedback.py +936 -936
- tapps_agents/cli/formatters.py +608 -608
- tapps_agents/cli/help/__init__.py +7 -7
- tapps_agents/cli/help/static_help.py +425 -425
- tapps_agents/cli/network_detection.py +110 -110
- tapps_agents/cli/output_compactor.py +274 -274
- tapps_agents/cli/parsers/__init__.py +2 -2
- tapps_agents/cli/parsers/analyst.py +186 -186
- tapps_agents/cli/parsers/architect.py +167 -167
- tapps_agents/cli/parsers/cleanup_agent.py +228 -228
- tapps_agents/cli/parsers/debugger.py +116 -116
- tapps_agents/cli/parsers/designer.py +182 -182
- tapps_agents/cli/parsers/documenter.py +134 -134
- tapps_agents/cli/parsers/enhancer.py +113 -113
- tapps_agents/cli/parsers/evaluator.py +213 -213
- tapps_agents/cli/parsers/implementer.py +168 -168
- tapps_agents/cli/parsers/improver.py +132 -132
- tapps_agents/cli/parsers/ops.py +159 -159
- tapps_agents/cli/parsers/orchestrator.py +98 -98
- tapps_agents/cli/parsers/planner.py +145 -145
- tapps_agents/cli/parsers/reviewer.py +462 -462
- tapps_agents/cli/parsers/tester.py +124 -124
- tapps_agents/cli/progress_heartbeat.py +254 -254
- tapps_agents/cli/streaming_progress.py +336 -336
- tapps_agents/cli/utils/__init__.py +6 -6
- tapps_agents/cli/utils/agent_lifecycle.py +48 -48
- tapps_agents/cli/utils/error_formatter.py +82 -82
- tapps_agents/cli/utils/error_recovery.py +188 -188
- tapps_agents/cli/utils/output_handler.py +59 -59
- tapps_agents/cli/utils/prompt_enhancer.py +319 -319
- tapps_agents/cli/validators/__init__.py +9 -9
- tapps_agents/cli/validators/command_validator.py +81 -81
- tapps_agents/context7/__init__.py +112 -112
- tapps_agents/context7/agent_integration.py +869 -869
- tapps_agents/context7/analytics.py +382 -382
- tapps_agents/context7/analytics_dashboard.py +299 -299
- tapps_agents/context7/async_cache.py +681 -681
- tapps_agents/context7/backup_client.py +958 -958
- tapps_agents/context7/cache_locking.py +194 -194
- tapps_agents/context7/cache_metadata.py +214 -214
- tapps_agents/context7/cache_prewarm.py +488 -488
- tapps_agents/context7/cache_structure.py +168 -168
- tapps_agents/context7/cache_warming.py +604 -604
- tapps_agents/context7/circuit_breaker.py +376 -376
- tapps_agents/context7/cleanup.py +461 -461
- tapps_agents/context7/commands.py +858 -858
- tapps_agents/context7/credential_validation.py +276 -276
- tapps_agents/context7/cross_reference_resolver.py +168 -168
- tapps_agents/context7/cross_references.py +424 -424
- tapps_agents/context7/doc_manager.py +225 -225
- tapps_agents/context7/fuzzy_matcher.py +369 -369
- tapps_agents/context7/kb_cache.py +404 -404
- tapps_agents/context7/language_detector.py +219 -219
- tapps_agents/context7/library_detector.py +725 -725
- tapps_agents/context7/lookup.py +738 -738
- tapps_agents/context7/metadata.py +258 -258
- tapps_agents/context7/refresh_queue.py +300 -300
- tapps_agents/context7/security.py +373 -373
- tapps_agents/context7/staleness_policies.py +278 -278
- tapps_agents/context7/tiles_integration.py +47 -47
- tapps_agents/continuous_bug_fix/__init__.py +20 -20
- tapps_agents/continuous_bug_fix/bug_finder.py +306 -306
- tapps_agents/continuous_bug_fix/bug_fix_coordinator.py +177 -177
- tapps_agents/continuous_bug_fix/commit_manager.py +178 -178
- tapps_agents/continuous_bug_fix/continuous_bug_fixer.py +322 -322
- tapps_agents/continuous_bug_fix/proactive_bug_finder.py +285 -285
- tapps_agents/core/__init__.py +298 -298
- tapps_agents/core/adaptive_cache_config.py +432 -432
- tapps_agents/core/agent_base.py +647 -647
- tapps_agents/core/agent_cache.py +466 -466
- tapps_agents/core/agent_learning.py +1865 -1865
- tapps_agents/core/analytics_dashboard.py +563 -563
- tapps_agents/core/analytics_enhancements.py +597 -597
- tapps_agents/core/anonymization.py +274 -274
- tapps_agents/core/ast_parser.py +228 -228
- tapps_agents/core/async_file_ops.py +402 -402
- tapps_agents/core/best_practice_consultant.py +299 -299
- tapps_agents/core/brownfield_analyzer.py +299 -299
- tapps_agents/core/brownfield_review.py +541 -541
- tapps_agents/core/browser_controller.py +513 -513
- tapps_agents/core/capability_registry.py +418 -418
- tapps_agents/core/change_impact_analyzer.py +190 -190
- tapps_agents/core/checkpoint_manager.py +377 -377
- tapps_agents/core/code_generator.py +329 -329
- tapps_agents/core/code_validator.py +276 -276
- tapps_agents/core/command_registry.py +327 -327
- tapps_agents/core/context_gathering/__init__.py +2 -2
- tapps_agents/core/context_gathering/repository_explorer.py +28 -28
- tapps_agents/core/context_intelligence/__init__.py +2 -2
- tapps_agents/core/context_intelligence/relevance_scorer.py +24 -24
- tapps_agents/core/context_intelligence/token_budget_manager.py +27 -27
- tapps_agents/core/context_manager.py +240 -240
- tapps_agents/core/cursor_feedback_monitor.py +146 -146
- tapps_agents/core/cursor_verification.py +290 -290
- tapps_agents/core/customization_loader.py +280 -280
- tapps_agents/core/customization_schema.py +260 -260
- tapps_agents/core/customization_template.py +238 -238
- tapps_agents/core/debug_logger.py +124 -124
- tapps_agents/core/design_validator.py +298 -298
- tapps_agents/core/diagram_generator.py +226 -226
- tapps_agents/core/docker_utils.py +232 -232
- tapps_agents/core/document_generator.py +617 -617
- tapps_agents/core/domain_detector.py +30 -30
- tapps_agents/core/error_envelope.py +454 -454
- tapps_agents/core/error_handler.py +270 -270
- tapps_agents/core/estimation_tracker.py +189 -189
- tapps_agents/core/eval_prompt_engine.py +116 -116
- tapps_agents/core/evaluation_base.py +119 -119
- tapps_agents/core/evaluation_models.py +320 -320
- tapps_agents/core/evaluation_orchestrator.py +225 -225
- tapps_agents/core/evaluators/__init__.py +7 -7
- tapps_agents/core/evaluators/architectural_evaluator.py +205 -205
- tapps_agents/core/evaluators/behavioral_evaluator.py +160 -160
- tapps_agents/core/evaluators/performance_profile_evaluator.py +160 -160
- tapps_agents/core/evaluators/security_posture_evaluator.py +148 -148
- tapps_agents/core/evaluators/spec_compliance_evaluator.py +181 -181
- tapps_agents/core/exceptions.py +107 -107
- tapps_agents/core/expert_config_generator.py +293 -293
- tapps_agents/core/export_schema.py +202 -202
- tapps_agents/core/external_feedback_models.py +102 -102
- tapps_agents/core/external_feedback_storage.py +213 -213
- tapps_agents/core/fallback_strategy.py +314 -314
- tapps_agents/core/feedback_analyzer.py +162 -162
- tapps_agents/core/feedback_collector.py +178 -178
- tapps_agents/core/git_operations.py +445 -445
- tapps_agents/core/hardware_profiler.py +151 -151
- tapps_agents/core/instructions.py +324 -324
- tapps_agents/core/io_guardrails.py +69 -69
- tapps_agents/core/issue_manifest.py +249 -249
- tapps_agents/core/issue_schema.py +139 -139
- tapps_agents/core/json_utils.py +128 -128
- tapps_agents/core/knowledge_graph.py +446 -446
- tapps_agents/core/language_detector.py +296 -296
- tapps_agents/core/learning_confidence.py +242 -242
- tapps_agents/core/learning_dashboard.py +246 -246
- tapps_agents/core/learning_decision.py +384 -384
- tapps_agents/core/learning_explainability.py +578 -578
- tapps_agents/core/learning_export.py +287 -287
- tapps_agents/core/learning_integration.py +228 -228
- tapps_agents/core/llm_behavior.py +232 -232
- tapps_agents/core/long_duration_support.py +786 -786
- tapps_agents/core/mcp_setup.py +106 -106
- tapps_agents/core/memory_integration.py +396 -396
- tapps_agents/core/meta_learning.py +666 -666
- tapps_agents/core/module_path_sanitizer.py +199 -199
- tapps_agents/core/multi_agent_orchestrator.py +382 -382
- tapps_agents/core/network_errors.py +125 -125
- tapps_agents/core/nfr_validator.py +336 -336
- tapps_agents/core/offline_mode.py +158 -158
- tapps_agents/core/output_contracts.py +300 -300
- tapps_agents/core/output_formatter.py +300 -300
- tapps_agents/core/path_normalizer.py +174 -174
- tapps_agents/core/path_validator.py +322 -322
- tapps_agents/core/pattern_library.py +250 -250
- tapps_agents/core/performance_benchmark.py +301 -301
- tapps_agents/core/performance_monitor.py +184 -184
- tapps_agents/core/playwright_mcp_controller.py +771 -771
- tapps_agents/core/policy_loader.py +135 -135
- tapps_agents/core/progress.py +166 -166
- tapps_agents/core/project_profile.py +354 -354
- tapps_agents/core/project_type_detector.py +454 -454
- tapps_agents/core/prompt_base.py +223 -223
- tapps_agents/core/prompt_learning/__init__.py +2 -2
- tapps_agents/core/prompt_learning/learning_loop.py +24 -24
- tapps_agents/core/prompt_learning/project_prompt_store.py +25 -25
- tapps_agents/core/prompt_learning/skills_prompt_analyzer.py +35 -35
- tapps_agents/core/prompt_optimization/__init__.py +6 -6
- tapps_agents/core/prompt_optimization/ab_tester.py +114 -114
- tapps_agents/core/prompt_optimization/correlation_analyzer.py +160 -160
- tapps_agents/core/prompt_optimization/progressive_refiner.py +129 -129
- tapps_agents/core/prompt_optimization/prompt_library.py +37 -37
- tapps_agents/core/requirements_evaluator.py +431 -431
- tapps_agents/core/resource_aware_executor.py +449 -449
- tapps_agents/core/resource_monitor.py +343 -343
- tapps_agents/core/resume_handler.py +298 -298
- tapps_agents/core/retry_handler.py +197 -197
- tapps_agents/core/review_checklists.py +479 -479
- tapps_agents/core/role_loader.py +201 -201
- tapps_agents/core/role_template_loader.py +201 -201
- tapps_agents/core/runtime_mode.py +60 -60
- tapps_agents/core/security_scanner.py +342 -342
- tapps_agents/core/skill_agent_registry.py +194 -194
- tapps_agents/core/skill_integration.py +208 -208
- tapps_agents/core/skill_loader.py +492 -492
- tapps_agents/core/skill_template.py +341 -341
- tapps_agents/core/skill_validator.py +478 -478
- tapps_agents/core/stack_analyzer.py +35 -35
- tapps_agents/core/startup.py +174 -174
- tapps_agents/core/storage_manager.py +397 -397
- tapps_agents/core/storage_models.py +166 -166
- tapps_agents/core/story_evaluator.py +410 -410
- tapps_agents/core/subprocess_utils.py +170 -170
- tapps_agents/core/task_duration.py +296 -296
- tapps_agents/core/task_memory.py +582 -582
- tapps_agents/core/task_state.py +226 -226
- tapps_agents/core/tech_stack_priorities.py +208 -208
- tapps_agents/core/temp_directory.py +194 -194
- tapps_agents/core/template_merger.py +600 -600
- tapps_agents/core/template_selector.py +280 -280
- tapps_agents/core/test_generator.py +286 -286
- tapps_agents/core/tiered_context.py +253 -253
- tapps_agents/core/token_monitor.py +345 -345
- tapps_agents/core/traceability.py +254 -254
- tapps_agents/core/trajectory_tracker.py +50 -50
- tapps_agents/core/unicode_safe.py +143 -143
- tapps_agents/core/unified_cache_config.py +170 -170
- tapps_agents/core/unified_state.py +324 -324
- tapps_agents/core/validate_cursor_setup.py +237 -237
- tapps_agents/core/validation_registry.py +136 -136
- tapps_agents/core/validators/__init__.py +4 -4
- tapps_agents/core/validators/python_validator.py +87 -87
- tapps_agents/core/verification_agent.py +90 -90
- tapps_agents/core/visual_feedback.py +644 -644
- tapps_agents/core/workflow_validator.py +197 -197
- tapps_agents/core/worktree.py +367 -367
- tapps_agents/docker/__init__.py +10 -10
- tapps_agents/docker/analyzer.py +186 -186
- tapps_agents/docker/debugger.py +229 -229
- tapps_agents/docker/error_patterns.py +216 -216
- tapps_agents/epic/__init__.py +22 -22
- tapps_agents/epic/beads_sync.py +115 -115
- tapps_agents/epic/markdown_sync.py +105 -105
- tapps_agents/epic/models.py +96 -96
- tapps_agents/experts/__init__.py +163 -163
- tapps_agents/experts/agent_integration.py +243 -243
- tapps_agents/experts/auto_generator.py +331 -331
- tapps_agents/experts/base_expert.py +536 -536
- tapps_agents/experts/builtin_registry.py +261 -261
- tapps_agents/experts/business_metrics.py +565 -565
- tapps_agents/experts/cache.py +266 -266
- tapps_agents/experts/confidence_breakdown.py +306 -306
- tapps_agents/experts/confidence_calculator.py +336 -336
- tapps_agents/experts/confidence_metrics.py +236 -236
- tapps_agents/experts/domain_config.py +311 -311
- tapps_agents/experts/domain_detector.py +550 -550
- tapps_agents/experts/domain_utils.py +84 -84
- tapps_agents/experts/expert_config.py +113 -113
- tapps_agents/experts/expert_engine.py +465 -465
- tapps_agents/experts/expert_registry.py +744 -744
- tapps_agents/experts/expert_synthesizer.py +70 -70
- tapps_agents/experts/governance.py +197 -197
- tapps_agents/experts/history_logger.py +312 -312
- tapps_agents/experts/knowledge/README.md +180 -180
- tapps_agents/experts/knowledge/accessibility/accessible-forms.md +331 -331
- tapps_agents/experts/knowledge/accessibility/aria-patterns.md +344 -344
- tapps_agents/experts/knowledge/accessibility/color-contrast.md +285 -285
- tapps_agents/experts/knowledge/accessibility/keyboard-navigation.md +332 -332
- tapps_agents/experts/knowledge/accessibility/screen-readers.md +282 -282
- tapps_agents/experts/knowledge/accessibility/semantic-html.md +355 -355
- tapps_agents/experts/knowledge/accessibility/testing-accessibility.md +369 -369
- tapps_agents/experts/knowledge/accessibility/wcag-2.1.md +296 -296
- tapps_agents/experts/knowledge/accessibility/wcag-2.2.md +211 -211
- tapps_agents/experts/knowledge/agent-learning/best-practices.md +715 -715
- tapps_agents/experts/knowledge/agent-learning/pattern-extraction.md +282 -282
- tapps_agents/experts/knowledge/agent-learning/prompt-optimization.md +320 -320
- tapps_agents/experts/knowledge/ai-frameworks/model-optimization.md +90 -90
- tapps_agents/experts/knowledge/ai-frameworks/openvino-patterns.md +260 -260
- tapps_agents/experts/knowledge/api-design-integration/api-gateway-patterns.md +309 -309
- tapps_agents/experts/knowledge/api-design-integration/api-security-patterns.md +521 -521
- tapps_agents/experts/knowledge/api-design-integration/api-versioning.md +421 -421
- tapps_agents/experts/knowledge/api-design-integration/async-protocol-patterns.md +61 -61
- tapps_agents/experts/knowledge/api-design-integration/contract-testing.md +221 -221
- tapps_agents/experts/knowledge/api-design-integration/external-api-integration.md +489 -489
- tapps_agents/experts/knowledge/api-design-integration/fastapi-patterns.md +360 -360
- tapps_agents/experts/knowledge/api-design-integration/fastapi-testing.md +262 -262
- tapps_agents/experts/knowledge/api-design-integration/graphql-patterns.md +582 -582
- tapps_agents/experts/knowledge/api-design-integration/grpc-best-practices.md +499 -499
- tapps_agents/experts/knowledge/api-design-integration/mqtt-patterns.md +455 -455
- tapps_agents/experts/knowledge/api-design-integration/rate-limiting.md +507 -507
- tapps_agents/experts/knowledge/api-design-integration/restful-api-design.md +618 -618
- tapps_agents/experts/knowledge/api-design-integration/websocket-patterns.md +480 -480
- tapps_agents/experts/knowledge/cloud-infrastructure/cloud-native-patterns.md +175 -175
- tapps_agents/experts/knowledge/cloud-infrastructure/container-health-checks.md +261 -261
- tapps_agents/experts/knowledge/cloud-infrastructure/containerization.md +222 -222
- tapps_agents/experts/knowledge/cloud-infrastructure/cost-optimization.md +122 -122
- tapps_agents/experts/knowledge/cloud-infrastructure/disaster-recovery.md +153 -153
- tapps_agents/experts/knowledge/cloud-infrastructure/dockerfile-patterns.md +285 -285
- tapps_agents/experts/knowledge/cloud-infrastructure/infrastructure-as-code.md +187 -187
- tapps_agents/experts/knowledge/cloud-infrastructure/kubernetes-patterns.md +253 -253
- tapps_agents/experts/knowledge/cloud-infrastructure/multi-cloud-strategies.md +155 -155
- tapps_agents/experts/knowledge/cloud-infrastructure/serverless-architecture.md +200 -200
- tapps_agents/experts/knowledge/code-quality-analysis/README.md +16 -16
- tapps_agents/experts/knowledge/code-quality-analysis/code-metrics.md +137 -137
- tapps_agents/experts/knowledge/code-quality-analysis/complexity-analysis.md +181 -181
- tapps_agents/experts/knowledge/code-quality-analysis/technical-debt-patterns.md +191 -191
- tapps_agents/experts/knowledge/data-privacy-compliance/anonymization.md +313 -313
- tapps_agents/experts/knowledge/data-privacy-compliance/ccpa.md +255 -255
- tapps_agents/experts/knowledge/data-privacy-compliance/consent-management.md +282 -282
- tapps_agents/experts/knowledge/data-privacy-compliance/data-minimization.md +275 -275
- tapps_agents/experts/knowledge/data-privacy-compliance/data-retention.md +297 -297
- tapps_agents/experts/knowledge/data-privacy-compliance/data-subject-rights.md +383 -383
- tapps_agents/experts/knowledge/data-privacy-compliance/encryption-privacy.md +285 -285
- tapps_agents/experts/knowledge/data-privacy-compliance/gdpr.md +344 -344
- tapps_agents/experts/knowledge/data-privacy-compliance/hipaa.md +385 -385
- tapps_agents/experts/knowledge/data-privacy-compliance/privacy-by-design.md +280 -280
- tapps_agents/experts/knowledge/database-data-management/acid-vs-cap.md +164 -164
- tapps_agents/experts/knowledge/database-data-management/backup-and-recovery.md +182 -182
- tapps_agents/experts/knowledge/database-data-management/data-modeling.md +172 -172
- tapps_agents/experts/knowledge/database-data-management/database-design.md +187 -187
- tapps_agents/experts/knowledge/database-data-management/flux-query-optimization.md +342 -342
- tapps_agents/experts/knowledge/database-data-management/influxdb-connection-patterns.md +432 -432
- tapps_agents/experts/knowledge/database-data-management/influxdb-patterns.md +442 -442
- tapps_agents/experts/knowledge/database-data-management/migration-strategies.md +216 -216
- tapps_agents/experts/knowledge/database-data-management/nosql-patterns.md +259 -259
- tapps_agents/experts/knowledge/database-data-management/scalability-patterns.md +184 -184
- tapps_agents/experts/knowledge/database-data-management/sql-optimization.md +175 -175
- tapps_agents/experts/knowledge/database-data-management/time-series-modeling.md +444 -444
- tapps_agents/experts/knowledge/development-workflow/README.md +16 -16
- tapps_agents/experts/knowledge/development-workflow/automation-best-practices.md +216 -216
- tapps_agents/experts/knowledge/development-workflow/build-strategies.md +198 -198
- tapps_agents/experts/knowledge/development-workflow/deployment-patterns.md +205 -205
- tapps_agents/experts/knowledge/development-workflow/git-workflows.md +205 -205
- tapps_agents/experts/knowledge/documentation-knowledge-management/README.md +16 -16
- tapps_agents/experts/knowledge/documentation-knowledge-management/api-documentation-patterns.md +231 -231
- tapps_agents/experts/knowledge/documentation-knowledge-management/documentation-standards.md +191 -191
- tapps_agents/experts/knowledge/documentation-knowledge-management/knowledge-management.md +171 -171
- tapps_agents/experts/knowledge/documentation-knowledge-management/technical-writing-guide.md +192 -192
- tapps_agents/experts/knowledge/observability-monitoring/alerting-patterns.md +461 -461
- tapps_agents/experts/knowledge/observability-monitoring/apm-tools.md +459 -459
- tapps_agents/experts/knowledge/observability-monitoring/distributed-tracing.md +367 -367
- tapps_agents/experts/knowledge/observability-monitoring/logging-strategies.md +478 -478
- tapps_agents/experts/knowledge/observability-monitoring/metrics-and-monitoring.md +510 -510
- tapps_agents/experts/knowledge/observability-monitoring/observability-best-practices.md +492 -492
- tapps_agents/experts/knowledge/observability-monitoring/open-telemetry.md +573 -573
- tapps_agents/experts/knowledge/observability-monitoring/slo-sli-sla.md +419 -419
- tapps_agents/experts/knowledge/performance/anti-patterns.md +284 -284
- tapps_agents/experts/knowledge/performance/api-performance.md +256 -256
- tapps_agents/experts/knowledge/performance/caching.md +327 -327
- tapps_agents/experts/knowledge/performance/database-performance.md +252 -252
- tapps_agents/experts/knowledge/performance/optimization-patterns.md +327 -327
- tapps_agents/experts/knowledge/performance/profiling.md +297 -297
- tapps_agents/experts/knowledge/performance/resource-management.md +293 -293
- tapps_agents/experts/knowledge/performance/scalability.md +306 -306
- tapps_agents/experts/knowledge/security/owasp-top10.md +209 -209
- tapps_agents/experts/knowledge/security/secure-coding-practices.md +207 -207
- tapps_agents/experts/knowledge/security/threat-modeling.md +220 -220
- tapps_agents/experts/knowledge/security/vulnerability-patterns.md +342 -342
- tapps_agents/experts/knowledge/software-architecture/docker-compose-patterns.md +314 -314
- tapps_agents/experts/knowledge/software-architecture/microservices-patterns.md +379 -379
- tapps_agents/experts/knowledge/software-architecture/service-communication.md +316 -316
- tapps_agents/experts/knowledge/testing/best-practices.md +310 -310
- tapps_agents/experts/knowledge/testing/coverage-analysis.md +293 -293
- tapps_agents/experts/knowledge/testing/mocking.md +256 -256
- tapps_agents/experts/knowledge/testing/test-automation.md +276 -276
- tapps_agents/experts/knowledge/testing/test-data.md +271 -271
- tapps_agents/experts/knowledge/testing/test-design-patterns.md +280 -280
- tapps_agents/experts/knowledge/testing/test-maintenance.md +236 -236
- tapps_agents/experts/knowledge/testing/test-strategies.md +311 -311
- tapps_agents/experts/knowledge/user-experience/information-architecture.md +325 -325
- tapps_agents/experts/knowledge/user-experience/interaction-design.md +363 -363
- tapps_agents/experts/knowledge/user-experience/prototyping.md +293 -293
- tapps_agents/experts/knowledge/user-experience/usability-heuristics.md +337 -337
- tapps_agents/experts/knowledge/user-experience/usability-testing.md +311 -311
- tapps_agents/experts/knowledge/user-experience/user-journeys.md +296 -296
- tapps_agents/experts/knowledge/user-experience/user-research.md +373 -373
- tapps_agents/experts/knowledge/user-experience/ux-principles.md +340 -340
- tapps_agents/experts/knowledge_freshness.py +321 -321
- tapps_agents/experts/knowledge_ingestion.py +438 -438
- tapps_agents/experts/knowledge_need_detector.py +93 -93
- tapps_agents/experts/knowledge_validator.py +382 -382
- tapps_agents/experts/observability.py +440 -440
- tapps_agents/experts/passive_notifier.py +238 -238
- tapps_agents/experts/proactive_orchestrator.py +32 -32
- tapps_agents/experts/rag_chunker.py +205 -205
- tapps_agents/experts/rag_embedder.py +152 -152
- tapps_agents/experts/rag_evaluation.py +299 -299
- tapps_agents/experts/rag_index.py +303 -303
- tapps_agents/experts/rag_metrics.py +293 -293
- tapps_agents/experts/rag_safety.py +263 -263
- tapps_agents/experts/report_generator.py +296 -296
- tapps_agents/experts/setup_wizard.py +441 -441
- tapps_agents/experts/simple_rag.py +431 -431
- tapps_agents/experts/vector_rag.py +354 -354
- tapps_agents/experts/weight_distributor.py +304 -304
- tapps_agents/health/__init__.py +24 -24
- tapps_agents/health/base.py +75 -75
- tapps_agents/health/checks/__init__.py +22 -22
- tapps_agents/health/checks/automation.py +127 -127
- tapps_agents/health/checks/context7_cache.py +210 -210
- tapps_agents/health/checks/environment.py +116 -116
- tapps_agents/health/checks/execution.py +170 -170
- tapps_agents/health/checks/knowledge_base.py +187 -187
- tapps_agents/health/checks/outcomes.backup_20260204_064058.py +324 -0
- tapps_agents/health/checks/outcomes.backup_20260204_064256.py +324 -0
- tapps_agents/health/checks/outcomes.backup_20260204_064600.py +324 -0
- tapps_agents/health/checks/outcomes.py +324 -324
- tapps_agents/health/collector.py +280 -280
- tapps_agents/health/dashboard.py +137 -137
- tapps_agents/health/metrics.py +151 -151
- tapps_agents/health/registry.py +166 -166
- tapps_agents/hooks/__init__.py +33 -33
- tapps_agents/hooks/config.py +140 -140
- tapps_agents/hooks/events.py +135 -135
- tapps_agents/hooks/executor.py +128 -128
- tapps_agents/hooks/manager.py +143 -143
- tapps_agents/integration/__init__.py +8 -8
- tapps_agents/integration/service_integrator.py +121 -121
- tapps_agents/integrations/__init__.py +10 -10
- tapps_agents/integrations/clawdbot.py +525 -525
- tapps_agents/integrations/memory_bridge.py +356 -356
- tapps_agents/mcp/__init__.py +18 -18
- tapps_agents/mcp/gateway.py +112 -112
- tapps_agents/mcp/servers/__init__.py +13 -13
- tapps_agents/mcp/servers/analysis.py +204 -204
- tapps_agents/mcp/servers/context7.py +198 -198
- tapps_agents/mcp/servers/filesystem.py +218 -218
- tapps_agents/mcp/servers/git.py +201 -201
- tapps_agents/mcp/tool_registry.py +115 -115
- tapps_agents/quality/__init__.py +54 -54
- tapps_agents/quality/coverage_analyzer.py +379 -379
- tapps_agents/quality/enforcement.py +82 -82
- tapps_agents/quality/gates/__init__.py +37 -37
- tapps_agents/quality/gates/approval_gate.py +255 -255
- tapps_agents/quality/gates/base.py +84 -84
- tapps_agents/quality/gates/exceptions.py +43 -43
- tapps_agents/quality/gates/policy_gate.py +195 -195
- tapps_agents/quality/gates/registry.py +239 -239
- tapps_agents/quality/gates/security_gate.py +156 -156
- tapps_agents/quality/quality_gates.py +369 -369
- tapps_agents/quality/secret_scanner.py +335 -335
- tapps_agents/resources/__init__.py +5 -0
- tapps_agents/resources/claude/__init__.py +1 -0
- tapps_agents/resources/claude/commands/README.md +156 -0
- tapps_agents/resources/claude/commands/__init__.py +1 -0
- tapps_agents/resources/claude/commands/build-fix.md +22 -0
- tapps_agents/resources/claude/commands/build.md +77 -0
- tapps_agents/resources/claude/commands/debug.md +53 -0
- tapps_agents/resources/claude/commands/design.md +68 -0
- tapps_agents/resources/claude/commands/docs.md +53 -0
- tapps_agents/resources/claude/commands/e2e.md +22 -0
- tapps_agents/resources/claude/commands/fix.md +54 -0
- tapps_agents/resources/claude/commands/implement.md +53 -0
- tapps_agents/resources/claude/commands/improve.md +53 -0
- tapps_agents/resources/claude/commands/library-docs.md +64 -0
- tapps_agents/resources/claude/commands/lint.md +52 -0
- tapps_agents/resources/claude/commands/plan.md +65 -0
- tapps_agents/resources/claude/commands/refactor-clean.md +21 -0
- tapps_agents/resources/claude/commands/refactor.md +55 -0
- tapps_agents/resources/claude/commands/review.md +67 -0
- tapps_agents/resources/claude/commands/score.md +60 -0
- tapps_agents/resources/claude/commands/security-review.md +22 -0
- tapps_agents/resources/claude/commands/security-scan.md +54 -0
- tapps_agents/resources/claude/commands/tdd.md +24 -0
- tapps_agents/resources/claude/commands/test-coverage.md +21 -0
- tapps_agents/resources/claude/commands/test.md +54 -0
- tapps_agents/resources/claude/commands/update-codemaps.md +20 -0
- tapps_agents/resources/claude/commands/update-docs.md +21 -0
- tapps_agents/resources/claude/skills/__init__.py +1 -0
- tapps_agents/resources/claude/skills/analyst/SKILL.md +272 -0
- tapps_agents/resources/claude/skills/analyst/__init__.py +1 -0
- tapps_agents/resources/claude/skills/architect/SKILL.md +282 -0
- tapps_agents/resources/claude/skills/architect/__init__.py +1 -0
- tapps_agents/resources/claude/skills/backend-patterns/SKILL.md +30 -0
- tapps_agents/resources/claude/skills/backend-patterns/__init__.py +1 -0
- tapps_agents/resources/claude/skills/coding-standards/SKILL.md +29 -0
- tapps_agents/resources/claude/skills/coding-standards/__init__.py +1 -0
- tapps_agents/resources/claude/skills/debugger/SKILL.md +203 -0
- tapps_agents/resources/claude/skills/debugger/__init__.py +1 -0
- tapps_agents/resources/claude/skills/designer/SKILL.md +243 -0
- tapps_agents/resources/claude/skills/designer/__init__.py +1 -0
- tapps_agents/resources/claude/skills/documenter/SKILL.md +252 -0
- tapps_agents/resources/claude/skills/documenter/__init__.py +1 -0
- tapps_agents/resources/claude/skills/enhancer/SKILL.md +307 -0
- tapps_agents/resources/claude/skills/enhancer/__init__.py +1 -0
- tapps_agents/resources/claude/skills/evaluator/SKILL.md +204 -0
- tapps_agents/resources/claude/skills/evaluator/__init__.py +1 -0
- tapps_agents/resources/claude/skills/frontend-patterns/SKILL.md +29 -0
- tapps_agents/resources/claude/skills/frontend-patterns/__init__.py +1 -0
- tapps_agents/resources/claude/skills/implementer/SKILL.md +188 -0
- tapps_agents/resources/claude/skills/implementer/__init__.py +1 -0
- tapps_agents/resources/claude/skills/improver/SKILL.md +218 -0
- tapps_agents/resources/claude/skills/improver/__init__.py +1 -0
- tapps_agents/resources/claude/skills/ops/SKILL.md +281 -0
- tapps_agents/resources/claude/skills/ops/__init__.py +1 -0
- tapps_agents/resources/claude/skills/orchestrator/SKILL.md +390 -0
- tapps_agents/resources/claude/skills/orchestrator/__init__.py +1 -0
- tapps_agents/resources/claude/skills/planner/SKILL.md +254 -0
- tapps_agents/resources/claude/skills/planner/__init__.py +1 -0
- tapps_agents/resources/claude/skills/reviewer/SKILL.md +434 -0
- tapps_agents/resources/claude/skills/reviewer/__init__.py +1 -0
- tapps_agents/resources/claude/skills/security-review/SKILL.md +31 -0
- tapps_agents/resources/claude/skills/security-review/__init__.py +1 -0
- tapps_agents/resources/claude/skills/simple-mode/SKILL.md +695 -0
- tapps_agents/resources/claude/skills/simple-mode/__init__.py +1 -0
- tapps_agents/resources/claude/skills/tester/SKILL.md +219 -0
- tapps_agents/resources/claude/skills/tester/__init__.py +1 -0
- tapps_agents/resources/cursor/.cursorignore +35 -0
- tapps_agents/resources/cursor/__init__.py +1 -0
- tapps_agents/resources/cursor/commands/__init__.py +1 -0
- tapps_agents/resources/cursor/commands/build-fix.md +11 -0
- tapps_agents/resources/cursor/commands/build.md +11 -0
- tapps_agents/resources/cursor/commands/e2e.md +11 -0
- tapps_agents/resources/cursor/commands/fix.md +11 -0
- tapps_agents/resources/cursor/commands/refactor-clean.md +11 -0
- tapps_agents/resources/cursor/commands/review.md +11 -0
- tapps_agents/resources/cursor/commands/security-review.md +11 -0
- tapps_agents/resources/cursor/commands/tdd.md +11 -0
- tapps_agents/resources/cursor/commands/test-coverage.md +11 -0
- tapps_agents/resources/cursor/commands/test.md +11 -0
- tapps_agents/resources/cursor/commands/update-codemaps.md +10 -0
- tapps_agents/resources/cursor/commands/update-docs.md +11 -0
- tapps_agents/resources/cursor/rules/__init__.py +1 -0
- tapps_agents/resources/cursor/rules/agent-capabilities.mdc +687 -0
- tapps_agents/resources/cursor/rules/coding-style.mdc +31 -0
- tapps_agents/resources/cursor/rules/command-reference.mdc +2081 -0
- tapps_agents/resources/cursor/rules/cursor-mode-usage.mdc +125 -0
- tapps_agents/resources/cursor/rules/git-workflow.mdc +29 -0
- tapps_agents/resources/cursor/rules/performance.mdc +29 -0
- tapps_agents/resources/cursor/rules/project-context.mdc +163 -0
- tapps_agents/resources/cursor/rules/project-profiling.mdc +197 -0
- tapps_agents/resources/cursor/rules/quick-reference.mdc +630 -0
- tapps_agents/resources/cursor/rules/security.mdc +32 -0
- tapps_agents/resources/cursor/rules/simple-mode.mdc +500 -0
- tapps_agents/resources/cursor/rules/testing.mdc +31 -0
- tapps_agents/resources/cursor/rules/when-to-use.mdc +156 -0
- tapps_agents/resources/cursor/rules/workflow-presets.mdc +179 -0
- tapps_agents/resources/customizations/__init__.py +1 -0
- tapps_agents/resources/customizations/example-custom.yaml +83 -0
- tapps_agents/resources/hooks/__init__.py +1 -0
- tapps_agents/resources/hooks/templates/README.md +5 -0
- tapps_agents/resources/hooks/templates/__init__.py +1 -0
- tapps_agents/resources/hooks/templates/add-project-context.yaml +8 -0
- tapps_agents/resources/hooks/templates/auto-format-js.yaml +10 -0
- tapps_agents/resources/hooks/templates/auto-format-python.yaml +10 -0
- tapps_agents/resources/hooks/templates/git-commit-check.yaml +7 -0
- tapps_agents/resources/hooks/templates/notify-on-complete.yaml +8 -0
- tapps_agents/resources/hooks/templates/quality-gate.yaml +8 -0
- tapps_agents/resources/hooks/templates/security-scan-on-edit.yaml +10 -0
- tapps_agents/resources/hooks/templates/session-end-log.yaml +7 -0
- tapps_agents/resources/hooks/templates/show-beads-ready.yaml +8 -0
- tapps_agents/resources/hooks/templates/test-on-edit.yaml +10 -0
- tapps_agents/resources/hooks/templates/update-docs-on-complete.yaml +8 -0
- tapps_agents/resources/hooks/templates/user-prompt-log.yaml +7 -0
- tapps_agents/resources/scripts/__init__.py +1 -0
- tapps_agents/resources/scripts/set_bd_path.ps1 +51 -0
- tapps_agents/resources/workflows/__init__.py +1 -0
- tapps_agents/resources/workflows/presets/__init__.py +1 -0
- tapps_agents/resources/workflows/presets/brownfield-analysis.yaml +235 -0
- tapps_agents/resources/workflows/presets/fix.yaml +78 -0
- tapps_agents/resources/workflows/presets/full-sdlc.yaml +122 -0
- tapps_agents/resources/workflows/presets/quality.yaml +82 -0
- tapps_agents/resources/workflows/presets/rapid-dev.yaml +84 -0
- tapps_agents/session/__init__.py +19 -19
- tapps_agents/session/manager.py +256 -256
- tapps_agents/simple_mode/__init__.py +66 -66
- tapps_agents/simple_mode/agent_contracts.py +357 -357
- tapps_agents/simple_mode/beads_hooks.py +151 -151
- tapps_agents/simple_mode/code_snippet_handler.py +382 -382
- tapps_agents/simple_mode/documentation_manager.py +395 -395
- tapps_agents/simple_mode/documentation_reader.py +187 -187
- tapps_agents/simple_mode/file_inference.py +292 -292
- tapps_agents/simple_mode/framework_change_detector.py +268 -268
- tapps_agents/simple_mode/intent_parser.py +510 -510
- tapps_agents/simple_mode/learning_progression.py +358 -358
- tapps_agents/simple_mode/nl_handler.py +700 -700
- tapps_agents/simple_mode/onboarding.py +253 -253
- tapps_agents/simple_mode/orchestrators/__init__.py +38 -38
- tapps_agents/simple_mode/orchestrators/breakdown_orchestrator.py +49 -49
- tapps_agents/simple_mode/orchestrators/brownfield_orchestrator.py +135 -135
- tapps_agents/simple_mode/orchestrators/deliverable_checklist.py +349 -349
- tapps_agents/simple_mode/orchestrators/enhance_orchestrator.py +53 -53
- tapps_agents/simple_mode/orchestrators/epic_orchestrator.py +122 -122
- tapps_agents/simple_mode/orchestrators/explore_orchestrator.py +184 -184
- tapps_agents/simple_mode/orchestrators/plan_analysis_orchestrator.py +206 -206
- tapps_agents/simple_mode/orchestrators/pr_orchestrator.py +237 -237
- tapps_agents/simple_mode/orchestrators/refactor_orchestrator.py +222 -222
- tapps_agents/simple_mode/orchestrators/requirements_tracer.py +262 -262
- tapps_agents/simple_mode/orchestrators/resume_orchestrator.py +210 -210
- tapps_agents/simple_mode/orchestrators/review_orchestrator.py +161 -161
- tapps_agents/simple_mode/orchestrators/test_orchestrator.py +82 -82
- tapps_agents/simple_mode/output_aggregator.py +340 -340
- tapps_agents/simple_mode/result_formatters.py +598 -598
- tapps_agents/simple_mode/step_dependencies.py +382 -382
- tapps_agents/simple_mode/step_results.py +276 -276
- tapps_agents/simple_mode/streaming.py +388 -388
- tapps_agents/simple_mode/variations.py +129 -129
- tapps_agents/simple_mode/visual_feedback.py +238 -238
- tapps_agents/simple_mode/zero_config.py +274 -274
- tapps_agents/suggestions/__init__.py +8 -8
- tapps_agents/suggestions/inline_suggester.py +52 -52
- tapps_agents/templates/__init__.py +8 -8
- tapps_agents/templates/microservice_generator.py +274 -274
- tapps_agents/utils/env_validator.py +291 -291
- tapps_agents/workflow/__init__.py +171 -171
- tapps_agents/workflow/acceptance_verifier.py +132 -132
- tapps_agents/workflow/agent_handlers/__init__.py +41 -41
- tapps_agents/workflow/agent_handlers/analyst_handler.py +75 -75
- tapps_agents/workflow/agent_handlers/architect_handler.py +107 -107
- tapps_agents/workflow/agent_handlers/base.py +84 -84
- tapps_agents/workflow/agent_handlers/debugger_handler.py +100 -100
- tapps_agents/workflow/agent_handlers/designer_handler.py +110 -110
- tapps_agents/workflow/agent_handlers/documenter_handler.py +94 -94
- tapps_agents/workflow/agent_handlers/implementer_handler.py +235 -235
- tapps_agents/workflow/agent_handlers/ops_handler.py +62 -62
- tapps_agents/workflow/agent_handlers/orchestrator_handler.py +43 -43
- tapps_agents/workflow/agent_handlers/planner_handler.py +98 -98
- tapps_agents/workflow/agent_handlers/registry.py +119 -119
- tapps_agents/workflow/agent_handlers/reviewer_handler.py +119 -119
- tapps_agents/workflow/agent_handlers/tester_handler.py +69 -69
- tapps_agents/workflow/analytics_accessor.py +337 -337
- tapps_agents/workflow/analytics_alerts.py +416 -416
- tapps_agents/workflow/analytics_dashboard_cursor.py +281 -281
- tapps_agents/workflow/analytics_dual_write.py +103 -103
- tapps_agents/workflow/analytics_integration.py +119 -119
- tapps_agents/workflow/analytics_query_parser.py +278 -278
- tapps_agents/workflow/analytics_visualizer.py +259 -259
- tapps_agents/workflow/artifact_helper.py +204 -204
- tapps_agents/workflow/audit_logger.py +263 -263
- tapps_agents/workflow/auto_execution_config.py +340 -340
- tapps_agents/workflow/auto_progression.py +586 -586
- tapps_agents/workflow/branch_cleanup.py +349 -349
- tapps_agents/workflow/checkpoint.py +256 -256
- tapps_agents/workflow/checkpoint_manager.py +178 -178
- tapps_agents/workflow/code_artifact.py +179 -179
- tapps_agents/workflow/common_enums.py +96 -96
- tapps_agents/workflow/confirmation_handler.py +130 -130
- tapps_agents/workflow/context_analyzer.py +222 -222
- tapps_agents/workflow/context_artifact.py +230 -230
- tapps_agents/workflow/cursor_chat.py +94 -94
- tapps_agents/workflow/cursor_skill_helper.py +516 -516
- tapps_agents/workflow/dependency_resolver.py +244 -244
- tapps_agents/workflow/design_artifact.py +156 -156
- tapps_agents/workflow/detector.py +751 -751
- tapps_agents/workflow/direct_execution_fallback.py +301 -301
- tapps_agents/workflow/docs_artifact.py +168 -168
- tapps_agents/workflow/enforcer.py +389 -389
- tapps_agents/workflow/enhancement_artifact.py +142 -142
- tapps_agents/workflow/error_recovery.py +806 -806
- tapps_agents/workflow/event_bus.py +183 -183
- tapps_agents/workflow/event_log.py +612 -612
- tapps_agents/workflow/events.py +63 -63
- tapps_agents/workflow/exceptions.py +43 -43
- tapps_agents/workflow/execution_graph.py +498 -498
- tapps_agents/workflow/execution_plan.py +126 -126
- tapps_agents/workflow/file_utils.py +186 -186
- tapps_agents/workflow/gate_evaluator.py +182 -182
- tapps_agents/workflow/gate_integration.py +200 -200
- tapps_agents/workflow/graph_visualizer.py +130 -130
- tapps_agents/workflow/health_checker.py +206 -206
- tapps_agents/workflow/logging_helper.py +243 -243
- tapps_agents/workflow/manifest.py +582 -582
- tapps_agents/workflow/marker_writer.py +250 -250
- tapps_agents/workflow/messaging.py +325 -325
- tapps_agents/workflow/metadata_models.py +91 -91
- tapps_agents/workflow/metrics_integration.py +226 -226
- tapps_agents/workflow/migration_utils.py +116 -116
- tapps_agents/workflow/models.py +148 -148
- tapps_agents/workflow/nlp_config.py +198 -198
- tapps_agents/workflow/nlp_error_handler.py +207 -207
- tapps_agents/workflow/nlp_executor.py +163 -163
- tapps_agents/workflow/nlp_parser.py +528 -528
- tapps_agents/workflow/observability_dashboard.py +451 -451
- tapps_agents/workflow/observer.py +170 -170
- tapps_agents/workflow/ops_artifact.py +257 -257
- tapps_agents/workflow/output_passing.py +214 -214
- tapps_agents/workflow/parallel_executor.py +463 -463
- tapps_agents/workflow/planning_artifact.py +179 -179
- tapps_agents/workflow/preset_loader.py +285 -285
- tapps_agents/workflow/preset_recommender.py +270 -270
- tapps_agents/workflow/progress_logger.py +145 -145
- tapps_agents/workflow/progress_manager.py +303 -303
- tapps_agents/workflow/progress_monitor.py +186 -186
- tapps_agents/workflow/progress_updates.py +423 -423
- tapps_agents/workflow/quality_artifact.py +158 -158
- tapps_agents/workflow/quality_loopback.py +101 -101
- tapps_agents/workflow/recommender.py +387 -387
- tapps_agents/workflow/remediation_loop.py +166 -166
- tapps_agents/workflow/result_aggregator.py +300 -300
- tapps_agents/workflow/review_artifact.py +185 -185
- tapps_agents/workflow/schema_validator.py +522 -522
- tapps_agents/workflow/session_handoff.py +178 -178
- tapps_agents/workflow/skill_invoker.py +648 -648
- tapps_agents/workflow/state_manager.py +756 -756
- tapps_agents/workflow/state_persistence_config.py +331 -331
- tapps_agents/workflow/status_monitor.py +449 -449
- tapps_agents/workflow/step_checkpoint.py +314 -314
- tapps_agents/workflow/step_details.py +201 -201
- tapps_agents/workflow/story_models.py +147 -147
- tapps_agents/workflow/streaming.py +416 -416
- tapps_agents/workflow/suggestion_engine.py +552 -552
- tapps_agents/workflow/testing_artifact.py +186 -186
- tapps_agents/workflow/timeline.py +158 -158
- tapps_agents/workflow/token_integration.py +209 -209
- tapps_agents/workflow/validation.py +217 -217
- tapps_agents/workflow/visual_feedback.py +391 -391
- tapps_agents/workflow/workflow_chain.py +95 -95
- tapps_agents/workflow/workflow_summary.py +219 -219
- tapps_agents/workflow/worktree_manager.py +724 -724
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/METADATA +672 -672
- tapps_agents-3.6.1.dist-info/RECORD +883 -0
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/licenses/LICENSE +22 -22
- tapps_agents-3.6.0.dist-info/RECORD +0 -758
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/WHEEL +0 -0
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/entry_points.txt +0 -0
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/top_level.txt +0 -0
|
@@ -1,516 +1,516 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Cursor Skill Helper - Utilities for invoking Cursor Skills.
|
|
3
|
-
|
|
4
|
-
This module provides helpers for working with Cursor Skills in workflow execution.
|
|
5
|
-
Since Cursor doesn't have a direct programmatic API for Skills, this module
|
|
6
|
-
creates command files and instructions that can be used by Background Agents
|
|
7
|
-
or manually executed in Cursor chat.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
from __future__ import annotations
|
|
11
|
-
|
|
12
|
-
import json
|
|
13
|
-
import re
|
|
14
|
-
from datetime import datetime
|
|
15
|
-
from pathlib import Path
|
|
16
|
-
from typing import Any
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def redact_secrets_from_text(text: str) -> str:
|
|
20
|
-
"""
|
|
21
|
-
Redact potentially sensitive information from text (API keys, tokens, passwords).
|
|
22
|
-
|
|
23
|
-
This is used to prevent accidental exposure of secrets in coordination files
|
|
24
|
-
that may be persisted or shared. Implements a "minimum necessary" policy:
|
|
25
|
-
only redacts obvious secrets, not all data.
|
|
26
|
-
|
|
27
|
-
Args:
|
|
28
|
-
text: Text that may contain secrets
|
|
29
|
-
|
|
30
|
-
Returns:
|
|
31
|
-
Text with secrets redacted
|
|
32
|
-
"""
|
|
33
|
-
if not text:
|
|
34
|
-
return text
|
|
35
|
-
|
|
36
|
-
# Redact API keys (common patterns: sk-..., pk-..., api_key=..., API key: ..., --api_key value)
|
|
37
|
-
# First, catch standalone sk-/pk- patterns (e.g., sk-test123, including in command-line args)
|
|
38
|
-
text = re.sub(r'\b(sk|pk)-[A-Za-z0-9]{10,}', r'\1-***REDACTED***', text, flags=re.IGNORECASE)
|
|
39
|
-
# Then catch key=value patterns
|
|
40
|
-
text = re.sub(r'\b(sk|pk|api_key|apikey)=[^\s&"\'`]+', r'\1=***REDACTED***', text, flags=re.IGNORECASE)
|
|
41
|
-
text = re.sub(r'\b(api\s+key|api_key|apikey):\s*[A-Za-z0-9_-]{20,}', r'\1: ***REDACTED***', text, flags=re.IGNORECASE)
|
|
42
|
-
# Command-line arguments: --api_key value, --api_key=value, or --api_key="value" (catch remaining values, but not already redacted)
|
|
43
|
-
def redact_api_key_arg(match):
|
|
44
|
-
value = match.group(1)
|
|
45
|
-
if 'REDACTED' in value:
|
|
46
|
-
return match.group(0) # Already redacted, don't change
|
|
47
|
-
return '--api_key ***REDACTED***'
|
|
48
|
-
text = re.sub(r'--api[_-]?key(?:\s+|=)((?:"[^"]*"|\'[^\']*\'|[^\s"\'`]+))', redact_api_key_arg, text, flags=re.IGNORECASE)
|
|
49
|
-
|
|
50
|
-
# Redact passwords
|
|
51
|
-
text = re.sub(r'\b(password|pwd|passwd)=[^\s&"\'`]+', r'\1=***REDACTED***', text, flags=re.IGNORECASE)
|
|
52
|
-
text = re.sub(r'\b(password|pwd|passwd):\s*[^\s"\'`]+', r'\1: ***REDACTED***', text, flags=re.IGNORECASE)
|
|
53
|
-
# Command-line arguments: --password value, --pwd value, --password=value, or --pwd="value"
|
|
54
|
-
text = re.sub(r'--(?:password|pwd|passwd)(?:\s+|=)(?:"[^"]*"|\'[^\']*\'|[^\s"\'`]+)', r'--password ***REDACTED***', text, flags=re.IGNORECASE)
|
|
55
|
-
|
|
56
|
-
# Redact tokens
|
|
57
|
-
text = re.sub(r'\b(token|auth|bearer)\s+[A-Za-z0-9_-]{20,}', r'\1 ***REDACTED***', text, flags=re.IGNORECASE)
|
|
58
|
-
text = re.sub(r'\b(token|auth|bearer):\s*[A-Za-z0-9_-]{20,}', r'\1: ***REDACTED***', text, flags=re.IGNORECASE)
|
|
59
|
-
# Command-line arguments: --token value, --auth value, --token=value, or --auth="value"
|
|
60
|
-
text = re.sub(r'--(?:token|auth)(?:\s+|=)(?:"[^"]*"|\'[^\']*\'|[^\s"\'`]+)', r'--token ***REDACTED***', text, flags=re.IGNORECASE)
|
|
61
|
-
|
|
62
|
-
# Redact AWS keys
|
|
63
|
-
text = re.sub(r'\b(AKIA[0-9A-Z]{16})\b', r'***REDACTED***', text)
|
|
64
|
-
text = re.sub(r'\baws[_-]?secret[_-]?access[_-]?key\s*[=:]\s*["\']?[a-zA-Z0-9/+=]{40}["\']?', r'aws_secret_access_key=***REDACTED***', text, flags=re.IGNORECASE)
|
|
65
|
-
|
|
66
|
-
# Redact private keys (PEM format)
|
|
67
|
-
text = re.sub(r'-----BEGIN\s+(RSA\s+)?PRIVATE\s+KEY-----[\s\S]*?-----END\s+(RSA\s+)?PRIVATE\s+KEY-----', r'-----BEGIN PRIVATE KEY-----\n***REDACTED***\n-----END PRIVATE KEY-----', text)
|
|
68
|
-
|
|
69
|
-
return text
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def minimize_content(content: str, max_length: int = 5000) -> str:
|
|
73
|
-
"""
|
|
74
|
-
Minimize content by truncating if too long (minimum necessary persistence).
|
|
75
|
-
|
|
76
|
-
For very long prompts or content, store a reference/ID instead of full content
|
|
77
|
-
when possible.
|
|
78
|
-
|
|
79
|
-
Args:
|
|
80
|
-
content: Content to minimize
|
|
81
|
-
max_length: Maximum length before truncation (default: 5000 chars)
|
|
82
|
-
|
|
83
|
-
Returns:
|
|
84
|
-
Minimized content (truncated with note if needed)
|
|
85
|
-
"""
|
|
86
|
-
if not content:
|
|
87
|
-
return content
|
|
88
|
-
|
|
89
|
-
if len(content) <= max_length:
|
|
90
|
-
return content
|
|
91
|
-
|
|
92
|
-
# Truncate and add note
|
|
93
|
-
truncated = content[:max_length]
|
|
94
|
-
return f"{truncated}\n\n[... Content truncated for persistence (total length: {len(content)} chars) ...]"
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
def create_skill_command_file(
|
|
98
|
-
command: str,
|
|
99
|
-
worktree_path: Path,
|
|
100
|
-
workflow_id: str | None = None,
|
|
101
|
-
step_id: str | None = None,
|
|
102
|
-
expected_artifacts: list[str] | None = None,
|
|
103
|
-
metadata: dict[str, Any] | None = None,
|
|
104
|
-
) -> tuple[Path, Path]:
|
|
105
|
-
"""
|
|
106
|
-
Create a Skill command file with structured metadata (webMCP pattern).
|
|
107
|
-
|
|
108
|
-
This function creates both:
|
|
109
|
-
1. A simple command file (`.cursor-skill-command.txt`) for backward compatibility
|
|
110
|
-
2. A structured metadata file (`.cursor-skill-metadata.json`) with workflow context
|
|
111
|
-
|
|
112
|
-
Args:
|
|
113
|
-
command: The Skill command (e.g., "@analyst gather-requirements ...")
|
|
114
|
-
worktree_path: Path to the worktree where the command should be executed
|
|
115
|
-
workflow_id: Optional workflow ID for tracking
|
|
116
|
-
step_id: Optional step ID for tracking
|
|
117
|
-
expected_artifacts: List of expected artifact file paths (relative to worktree)
|
|
118
|
-
metadata: Optional additional metadata dictionary
|
|
119
|
-
|
|
120
|
-
Returns:
|
|
121
|
-
Tuple of (command_file_path, metadata_file_path)
|
|
122
|
-
"""
|
|
123
|
-
# Redact secrets from command before persisting
|
|
124
|
-
redacted_command = redact_secrets_from_text(command)
|
|
125
|
-
|
|
126
|
-
# Create correlation metadata header
|
|
127
|
-
correlation_metadata = {
|
|
128
|
-
"workflow_id": workflow_id,
|
|
129
|
-
"step_id": step_id,
|
|
130
|
-
"created_at": datetime.now().isoformat(),
|
|
131
|
-
"expected_artifacts": expected_artifacts or [],
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
# Existing command file (backward compatible)
|
|
135
|
-
command_file = worktree_path / ".cursor-skill-command.txt"
|
|
136
|
-
|
|
137
|
-
# Create a structured command file (maintains backward compatibility)
|
|
138
|
-
# Use redacted command for persistence, but include original if different
|
|
139
|
-
command_data = {
|
|
140
|
-
"command": redacted_command,
|
|
141
|
-
"correlation": correlation_metadata,
|
|
142
|
-
"worktree_path": str(worktree_path),
|
|
143
|
-
"instructions": (
|
|
144
|
-
"This command can be executed in Cursor by:\n"
|
|
145
|
-
"1. Copying the 'command' field below into Cursor chat\n"
|
|
146
|
-
"2. Or using a Background Agent configured to read this file\n"
|
|
147
|
-
"3. Or manually executing the command in the worktree directory"
|
|
148
|
-
),
|
|
149
|
-
"note": "Command has been redacted to remove secrets. Original command contains same structure.",
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
# If redaction changed the command, note it (but don't store original secrets)
|
|
153
|
-
if redacted_command != command:
|
|
154
|
-
command_data["redaction_applied"] = True
|
|
155
|
-
command_data["original_length"] = len(command)
|
|
156
|
-
|
|
157
|
-
# Write JSON format (backward compatible)
|
|
158
|
-
command_file.write_text(json.dumps(command_data, indent=2), encoding="utf-8")
|
|
159
|
-
|
|
160
|
-
# Also write a simple text version for easy copying (redacted)
|
|
161
|
-
simple_file = worktree_path / ".cursor-skill-command-simple.txt"
|
|
162
|
-
simple_file.write_text(redacted_command, encoding="utf-8")
|
|
163
|
-
|
|
164
|
-
# New structured metadata file (webMCP pattern)
|
|
165
|
-
metadata_file = worktree_path / ".cursor-skill-metadata.json"
|
|
166
|
-
structured_data = {
|
|
167
|
-
"version": "1.0",
|
|
168
|
-
"type": "skill_command",
|
|
169
|
-
"command": redacted_command, # Use redacted command
|
|
170
|
-
"correlation": correlation_metadata,
|
|
171
|
-
"workflow_context": {
|
|
172
|
-
"workflow_id": workflow_id,
|
|
173
|
-
"step_id": step_id,
|
|
174
|
-
"expected_artifacts": expected_artifacts or [],
|
|
175
|
-
},
|
|
176
|
-
"interaction_pattern": {
|
|
177
|
-
"mode": "async",
|
|
178
|
-
"completion_detection": "status_file_and_artifacts",
|
|
179
|
-
"progress_updates": True,
|
|
180
|
-
"error_handling": "retry_with_backoff",
|
|
181
|
-
},
|
|
182
|
-
"metadata": metadata or {},
|
|
183
|
-
"timestamp": datetime.now().isoformat(),
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
# Note if redaction was applied
|
|
187
|
-
if redacted_command != command:
|
|
188
|
-
structured_data["redaction_applied"] = True
|
|
189
|
-
|
|
190
|
-
metadata_file.write_text(
|
|
191
|
-
json.dumps(structured_data, indent=2), encoding="utf-8"
|
|
192
|
-
)
|
|
193
|
-
|
|
194
|
-
return command_file, metadata_file
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
def create_skill_execution_instructions(
|
|
198
|
-
worktree_path: Path,
|
|
199
|
-
command: str,
|
|
200
|
-
expected_artifacts: list[str] | None = None,
|
|
201
|
-
workflow_id: str | None = None,
|
|
202
|
-
step_id: str | None = None,
|
|
203
|
-
) -> Path:
|
|
204
|
-
"""
|
|
205
|
-
Create execution instructions for a Skill command.
|
|
206
|
-
|
|
207
|
-
Args:
|
|
208
|
-
worktree_path: Path to the worktree
|
|
209
|
-
command: The Skill command (will be redacted)
|
|
210
|
-
expected_artifacts: List of expected artifact file paths
|
|
211
|
-
workflow_id: Optional workflow ID for correlation
|
|
212
|
-
step_id: Optional step ID for correlation
|
|
213
|
-
|
|
214
|
-
Returns:
|
|
215
|
-
Path to the instructions file
|
|
216
|
-
"""
|
|
217
|
-
instructions_file = worktree_path / ".cursor-skill-instructions.md"
|
|
218
|
-
|
|
219
|
-
# Redact secrets from command in instructions
|
|
220
|
-
redacted_command = redact_secrets_from_text(command)
|
|
221
|
-
|
|
222
|
-
instructions = f"""# Cursor Skill Execution Instructions
|
|
223
|
-
|
|
224
|
-
## Correlation Metadata
|
|
225
|
-
|
|
226
|
-
- **Workflow ID**: {workflow_id or 'N/A'}
|
|
227
|
-
- **Step ID**: {step_id or 'N/A'}
|
|
228
|
-
- **Created At**: {datetime.now().isoformat()}
|
|
229
|
-
|
|
230
|
-
## Command to Execute
|
|
231
|
-
|
|
232
|
-
Copy and paste this command into Cursor chat:
|
|
233
|
-
|
|
234
|
-
```
|
|
235
|
-
{redacted_command}
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
"""
|
|
239
|
-
|
|
240
|
-
if redacted_command != command:
|
|
241
|
-
instructions += "> **Note**: Command has been redacted to remove secrets. Execute in your environment with actual values.\n\n"
|
|
242
|
-
|
|
243
|
-
instructions += "## Expected Results\n\nAfter execution, the following artifacts should be created:\n\n"
|
|
244
|
-
|
|
245
|
-
if expected_artifacts:
|
|
246
|
-
for artifact in expected_artifacts:
|
|
247
|
-
instructions += f"- `{artifact}`\n"
|
|
248
|
-
else:
|
|
249
|
-
instructions += "- Check the worktree directory for generated files\n"
|
|
250
|
-
|
|
251
|
-
instructions += f"""
|
|
252
|
-
## Worktree Location
|
|
253
|
-
|
|
254
|
-
All work is done in: `{worktree_path}`
|
|
255
|
-
|
|
256
|
-
## Troubleshooting
|
|
257
|
-
|
|
258
|
-
If the step fails or times out:
|
|
259
|
-
1. Check the failure marker at: `.tapps-agents/workflows/markers/{workflow_id or 'WORKFLOW_ID'}/step-{step_id or 'STEP_ID'}/FAILED.json`
|
|
260
|
-
2. Verify expected artifacts were created
|
|
261
|
-
3. Check the command file: `.cursor-skill-command.txt`
|
|
262
|
-
|
|
263
|
-
## Next Steps
|
|
264
|
-
|
|
265
|
-
1. Execute the command in Cursor chat
|
|
266
|
-
2. Wait for the Skill to complete
|
|
267
|
-
3. Verify that expected artifacts are created
|
|
268
|
-
4. The workflow executor will detect completion when artifacts are present
|
|
269
|
-
"""
|
|
270
|
-
|
|
271
|
-
instructions_file.write_text(instructions, encoding="utf-8")
|
|
272
|
-
return instructions_file
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
def check_skill_completion(
|
|
276
|
-
worktree_path: Path,
|
|
277
|
-
expected_artifacts: list[str] | None = None,
|
|
278
|
-
workflow_id: str | None = None,
|
|
279
|
-
step_id: str | None = None,
|
|
280
|
-
) -> dict[str, Any]:
|
|
281
|
-
"""
|
|
282
|
-
Check if a Skill command has completed by looking for expected artifacts.
|
|
283
|
-
|
|
284
|
-
Args:
|
|
285
|
-
worktree_path: Path to the worktree
|
|
286
|
-
expected_artifacts: List of expected artifact file paths (relative to worktree)
|
|
287
|
-
workflow_id: Optional workflow ID for marker location reference
|
|
288
|
-
step_id: Optional step ID for marker location reference
|
|
289
|
-
|
|
290
|
-
Returns:
|
|
291
|
-
Dictionary with completion status, found artifacts, and marker locations
|
|
292
|
-
"""
|
|
293
|
-
result = {
|
|
294
|
-
"completed": False,
|
|
295
|
-
"found_artifacts": [],
|
|
296
|
-
"missing_artifacts": [],
|
|
297
|
-
"worktree_path": str(worktree_path),
|
|
298
|
-
"marker_locations": {},
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
# Check for DONE/FAILED markers in marker directory
|
|
302
|
-
if workflow_id and step_id:
|
|
303
|
-
project_root = worktree_path
|
|
304
|
-
# Try to find project root by looking for .tapps-agents
|
|
305
|
-
while project_root != project_root.parent:
|
|
306
|
-
if (project_root / ".tapps-agents").exists():
|
|
307
|
-
break
|
|
308
|
-
project_root = project_root.parent
|
|
309
|
-
|
|
310
|
-
marker_dir = (
|
|
311
|
-
project_root
|
|
312
|
-
/ ".tapps-agents"
|
|
313
|
-
/ "workflows"
|
|
314
|
-
/ "markers"
|
|
315
|
-
/ workflow_id
|
|
316
|
-
/ f"step-{step_id}"
|
|
317
|
-
)
|
|
318
|
-
done_marker = marker_dir / "DONE.json"
|
|
319
|
-
failed_marker = marker_dir / "FAILED.json"
|
|
320
|
-
|
|
321
|
-
if done_marker.exists():
|
|
322
|
-
result["completed"] = True
|
|
323
|
-
result["completion_type"] = "marker"
|
|
324
|
-
result["marker_locations"]["done"] = str(done_marker)
|
|
325
|
-
# Try to read marker for artifact info
|
|
326
|
-
try:
|
|
327
|
-
marker_data = json.loads(done_marker.read_text(encoding="utf-8"))
|
|
328
|
-
result["found_artifacts"] = marker_data.get("found_artifacts", [])
|
|
329
|
-
result["expected_artifacts"] = marker_data.get("expected_artifacts", [])
|
|
330
|
-
except Exception:
|
|
331
|
-
pass
|
|
332
|
-
return result
|
|
333
|
-
elif failed_marker.exists():
|
|
334
|
-
result["completed"] = True # Technically completed (with failure)
|
|
335
|
-
result["completion_type"] = "failed_marker"
|
|
336
|
-
result["marker_locations"]["failed"] = str(failed_marker)
|
|
337
|
-
# Try to read marker for error info
|
|
338
|
-
try:
|
|
339
|
-
marker_data = json.loads(failed_marker.read_text(encoding="utf-8"))
|
|
340
|
-
result["error"] = marker_data.get("error", "Unknown error")
|
|
341
|
-
result["error_type"] = marker_data.get("error_type")
|
|
342
|
-
result["found_artifacts"] = marker_data.get("found_artifacts", [])
|
|
343
|
-
result["expected_artifacts"] = marker_data.get("expected_artifacts", [])
|
|
344
|
-
except Exception:
|
|
345
|
-
pass
|
|
346
|
-
return result
|
|
347
|
-
|
|
348
|
-
if not expected_artifacts:
|
|
349
|
-
# If no expected artifacts, check for common ones
|
|
350
|
-
common_artifacts = [
|
|
351
|
-
"requirements.md",
|
|
352
|
-
"stories",
|
|
353
|
-
"architecture.md",
|
|
354
|
-
"api-specs",
|
|
355
|
-
"src",
|
|
356
|
-
"tests",
|
|
357
|
-
"docs",
|
|
358
|
-
]
|
|
359
|
-
expected_artifacts = common_artifacts
|
|
360
|
-
|
|
361
|
-
# Check artifact files with last modified times
|
|
362
|
-
artifact_details = []
|
|
363
|
-
for artifact_path in expected_artifacts:
|
|
364
|
-
full_path = worktree_path / artifact_path
|
|
365
|
-
if full_path.exists():
|
|
366
|
-
result["found_artifacts"].append(artifact_path)
|
|
367
|
-
try:
|
|
368
|
-
mtime = full_path.stat().st_mtime
|
|
369
|
-
artifact_details.append({
|
|
370
|
-
"path": artifact_path,
|
|
371
|
-
"exists": True,
|
|
372
|
-
"last_modified": datetime.fromtimestamp(mtime).isoformat(),
|
|
373
|
-
})
|
|
374
|
-
except OSError:
|
|
375
|
-
artifact_details.append({
|
|
376
|
-
"path": artifact_path,
|
|
377
|
-
"exists": True,
|
|
378
|
-
"last_modified": None,
|
|
379
|
-
})
|
|
380
|
-
else:
|
|
381
|
-
result["missing_artifacts"].append(artifact_path)
|
|
382
|
-
artifact_details.append({
|
|
383
|
-
"path": artifact_path,
|
|
384
|
-
"exists": False,
|
|
385
|
-
})
|
|
386
|
-
|
|
387
|
-
result["artifact_details"] = artifact_details
|
|
388
|
-
|
|
389
|
-
# Check for background agent artifacts (quality/testing)
|
|
390
|
-
quality_report = worktree_path / "reports" / "quality" / "quality-report.json"
|
|
391
|
-
test_report = worktree_path / "reports" / "tests" / "test-report.json"
|
|
392
|
-
|
|
393
|
-
if quality_report.exists():
|
|
394
|
-
result["found_artifacts"].append("reports/quality/quality-report.json")
|
|
395
|
-
if test_report.exists():
|
|
396
|
-
result["found_artifacts"].append("reports/tests/test-report.json")
|
|
397
|
-
|
|
398
|
-
# Consider complete if at least one expected artifact exists
|
|
399
|
-
# or if a completion marker exists
|
|
400
|
-
completion_marker = worktree_path / ".skill-completed.txt"
|
|
401
|
-
if completion_marker.exists() or result["found_artifacts"]:
|
|
402
|
-
result["completed"] = True
|
|
403
|
-
result["completion_type"] = "artifacts"
|
|
404
|
-
|
|
405
|
-
return result
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
def read_skill_metadata(worktree_path: Path) -> dict[str, Any] | None:
|
|
409
|
-
"""
|
|
410
|
-
Read structured metadata from a worktree.
|
|
411
|
-
|
|
412
|
-
Args:
|
|
413
|
-
worktree_path: Path to the worktree containing metadata
|
|
414
|
-
|
|
415
|
-
Returns:
|
|
416
|
-
Dictionary with metadata if found, None otherwise
|
|
417
|
-
"""
|
|
418
|
-
metadata_file = worktree_path / ".cursor-skill-metadata.json"
|
|
419
|
-
|
|
420
|
-
if not metadata_file.exists():
|
|
421
|
-
return None
|
|
422
|
-
|
|
423
|
-
try:
|
|
424
|
-
metadata_content = metadata_file.read_text(encoding="utf-8")
|
|
425
|
-
return json.loads(metadata_content)
|
|
426
|
-
except (json.JSONDecodeError, OSError) as e:
|
|
427
|
-
# Log error but don't fail - metadata is optional
|
|
428
|
-
import logging
|
|
429
|
-
logger = logging.getLogger(__name__)
|
|
430
|
-
logger.warning(f"Failed to read skill metadata from {metadata_file}: {e}")
|
|
431
|
-
return None
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
def get_expected_artifacts_from_metadata(worktree_path: Path) -> list[str]:
|
|
435
|
-
"""
|
|
436
|
-
Extract expected artifacts from metadata file.
|
|
437
|
-
|
|
438
|
-
Args:
|
|
439
|
-
worktree_path: Path to the worktree containing metadata
|
|
440
|
-
|
|
441
|
-
Returns:
|
|
442
|
-
List of expected artifact paths, empty list if metadata not found
|
|
443
|
-
"""
|
|
444
|
-
metadata = read_skill_metadata(worktree_path)
|
|
445
|
-
if not metadata:
|
|
446
|
-
return []
|
|
447
|
-
|
|
448
|
-
workflow_context = metadata.get("workflow_context", {})
|
|
449
|
-
return workflow_context.get("expected_artifacts", [])
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
def write_structured_status_file(
|
|
453
|
-
status_file: Path,
|
|
454
|
-
status: str,
|
|
455
|
-
progress: dict[str, Any] | None = None,
|
|
456
|
-
partial_results: dict[str, Any] | None = None,
|
|
457
|
-
error: dict[str, Any] | None = None,
|
|
458
|
-
artifacts: list[str] | None = None,
|
|
459
|
-
output: str | None = None,
|
|
460
|
-
metadata: dict[str, Any] | None = None,
|
|
461
|
-
started_at: str | None = None,
|
|
462
|
-
completed_at: str | None = None,
|
|
463
|
-
) -> None:
|
|
464
|
-
"""
|
|
465
|
-
Write structured status file (Phase 4 - Enhanced format).
|
|
466
|
-
|
|
467
|
-
This function creates a structured status file that includes:
|
|
468
|
-
- Progress updates (percentage, current step, message)
|
|
469
|
-
- Partial results (artifacts, output)
|
|
470
|
-
- Error details (message, code, retryable, retry_count)
|
|
471
|
-
- Metadata (workflow_id, step_id, command)
|
|
472
|
-
|
|
473
|
-
Args:
|
|
474
|
-
status_file: Path to status file to write
|
|
475
|
-
status: Status string ("running", "completed", "failed", "pending")
|
|
476
|
-
progress: Optional progress information
|
|
477
|
-
partial_results: Optional partial results
|
|
478
|
-
error: Optional error information
|
|
479
|
-
artifacts: Optional list of artifact paths
|
|
480
|
-
output: Optional execution output
|
|
481
|
-
metadata: Optional metadata (workflow_id, step_id, command)
|
|
482
|
-
started_at: Optional ISO datetime string for start time
|
|
483
|
-
completed_at: Optional ISO datetime string for completion time
|
|
484
|
-
"""
|
|
485
|
-
status_data = {
|
|
486
|
-
"version": "1.0",
|
|
487
|
-
"status": status,
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
if started_at:
|
|
491
|
-
status_data["started_at"] = started_at
|
|
492
|
-
if completed_at:
|
|
493
|
-
status_data["completed_at"] = completed_at
|
|
494
|
-
|
|
495
|
-
if progress:
|
|
496
|
-
status_data["progress"] = progress
|
|
497
|
-
|
|
498
|
-
if partial_results:
|
|
499
|
-
status_data["partial_results"] = partial_results
|
|
500
|
-
|
|
501
|
-
if error:
|
|
502
|
-
status_data["error"] = error
|
|
503
|
-
|
|
504
|
-
if artifacts:
|
|
505
|
-
status_data["artifacts"] = artifacts
|
|
506
|
-
|
|
507
|
-
if output:
|
|
508
|
-
status_data["output"] = output
|
|
509
|
-
|
|
510
|
-
if metadata:
|
|
511
|
-
status_data["metadata"] = metadata
|
|
512
|
-
|
|
513
|
-
status_file.write_text(
|
|
514
|
-
json.dumps(status_data, indent=2), encoding="utf-8"
|
|
515
|
-
)
|
|
516
|
-
|
|
1
|
+
"""
|
|
2
|
+
Cursor Skill Helper - Utilities for invoking Cursor Skills.
|
|
3
|
+
|
|
4
|
+
This module provides helpers for working with Cursor Skills in workflow execution.
|
|
5
|
+
Since Cursor doesn't have a direct programmatic API for Skills, this module
|
|
6
|
+
creates command files and instructions that can be used by Background Agents
|
|
7
|
+
or manually executed in Cursor chat.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import json
|
|
13
|
+
import re
|
|
14
|
+
from datetime import datetime
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def redact_secrets_from_text(text: str) -> str:
|
|
20
|
+
"""
|
|
21
|
+
Redact potentially sensitive information from text (API keys, tokens, passwords).
|
|
22
|
+
|
|
23
|
+
This is used to prevent accidental exposure of secrets in coordination files
|
|
24
|
+
that may be persisted or shared. Implements a "minimum necessary" policy:
|
|
25
|
+
only redacts obvious secrets, not all data.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
text: Text that may contain secrets
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
Text with secrets redacted
|
|
32
|
+
"""
|
|
33
|
+
if not text:
|
|
34
|
+
return text
|
|
35
|
+
|
|
36
|
+
# Redact API keys (common patterns: sk-..., pk-..., api_key=..., API key: ..., --api_key value)
|
|
37
|
+
# First, catch standalone sk-/pk- patterns (e.g., sk-test123, including in command-line args)
|
|
38
|
+
text = re.sub(r'\b(sk|pk)-[A-Za-z0-9]{10,}', r'\1-***REDACTED***', text, flags=re.IGNORECASE)
|
|
39
|
+
# Then catch key=value patterns
|
|
40
|
+
text = re.sub(r'\b(sk|pk|api_key|apikey)=[^\s&"\'`]+', r'\1=***REDACTED***', text, flags=re.IGNORECASE)
|
|
41
|
+
text = re.sub(r'\b(api\s+key|api_key|apikey):\s*[A-Za-z0-9_-]{20,}', r'\1: ***REDACTED***', text, flags=re.IGNORECASE)
|
|
42
|
+
# Command-line arguments: --api_key value, --api_key=value, or --api_key="value" (catch remaining values, but not already redacted)
|
|
43
|
+
def redact_api_key_arg(match):
|
|
44
|
+
value = match.group(1)
|
|
45
|
+
if 'REDACTED' in value:
|
|
46
|
+
return match.group(0) # Already redacted, don't change
|
|
47
|
+
return '--api_key ***REDACTED***'
|
|
48
|
+
text = re.sub(r'--api[_-]?key(?:\s+|=)((?:"[^"]*"|\'[^\']*\'|[^\s"\'`]+))', redact_api_key_arg, text, flags=re.IGNORECASE)
|
|
49
|
+
|
|
50
|
+
# Redact passwords
|
|
51
|
+
text = re.sub(r'\b(password|pwd|passwd)=[^\s&"\'`]+', r'\1=***REDACTED***', text, flags=re.IGNORECASE)
|
|
52
|
+
text = re.sub(r'\b(password|pwd|passwd):\s*[^\s"\'`]+', r'\1: ***REDACTED***', text, flags=re.IGNORECASE)
|
|
53
|
+
# Command-line arguments: --password value, --pwd value, --password=value, or --pwd="value"
|
|
54
|
+
text = re.sub(r'--(?:password|pwd|passwd)(?:\s+|=)(?:"[^"]*"|\'[^\']*\'|[^\s"\'`]+)', r'--password ***REDACTED***', text, flags=re.IGNORECASE)
|
|
55
|
+
|
|
56
|
+
# Redact tokens
|
|
57
|
+
text = re.sub(r'\b(token|auth|bearer)\s+[A-Za-z0-9_-]{20,}', r'\1 ***REDACTED***', text, flags=re.IGNORECASE)
|
|
58
|
+
text = re.sub(r'\b(token|auth|bearer):\s*[A-Za-z0-9_-]{20,}', r'\1: ***REDACTED***', text, flags=re.IGNORECASE)
|
|
59
|
+
# Command-line arguments: --token value, --auth value, --token=value, or --auth="value"
|
|
60
|
+
text = re.sub(r'--(?:token|auth)(?:\s+|=)(?:"[^"]*"|\'[^\']*\'|[^\s"\'`]+)', r'--token ***REDACTED***', text, flags=re.IGNORECASE)
|
|
61
|
+
|
|
62
|
+
# Redact AWS keys
|
|
63
|
+
text = re.sub(r'\b(AKIA[0-9A-Z]{16})\b', r'***REDACTED***', text)
|
|
64
|
+
text = re.sub(r'\baws[_-]?secret[_-]?access[_-]?key\s*[=:]\s*["\']?[a-zA-Z0-9/+=]{40}["\']?', r'aws_secret_access_key=***REDACTED***', text, flags=re.IGNORECASE)
|
|
65
|
+
|
|
66
|
+
# Redact private keys (PEM format)
|
|
67
|
+
text = re.sub(r'-----BEGIN\s+(RSA\s+)?PRIVATE\s+KEY-----[\s\S]*?-----END\s+(RSA\s+)?PRIVATE\s+KEY-----', r'-----BEGIN PRIVATE KEY-----\n***REDACTED***\n-----END PRIVATE KEY-----', text)
|
|
68
|
+
|
|
69
|
+
return text
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def minimize_content(content: str, max_length: int = 5000) -> str:
|
|
73
|
+
"""
|
|
74
|
+
Minimize content by truncating if too long (minimum necessary persistence).
|
|
75
|
+
|
|
76
|
+
For very long prompts or content, store a reference/ID instead of full content
|
|
77
|
+
when possible.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
content: Content to minimize
|
|
81
|
+
max_length: Maximum length before truncation (default: 5000 chars)
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
Minimized content (truncated with note if needed)
|
|
85
|
+
"""
|
|
86
|
+
if not content:
|
|
87
|
+
return content
|
|
88
|
+
|
|
89
|
+
if len(content) <= max_length:
|
|
90
|
+
return content
|
|
91
|
+
|
|
92
|
+
# Truncate and add note
|
|
93
|
+
truncated = content[:max_length]
|
|
94
|
+
return f"{truncated}\n\n[... Content truncated for persistence (total length: {len(content)} chars) ...]"
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def create_skill_command_file(
|
|
98
|
+
command: str,
|
|
99
|
+
worktree_path: Path,
|
|
100
|
+
workflow_id: str | None = None,
|
|
101
|
+
step_id: str | None = None,
|
|
102
|
+
expected_artifacts: list[str] | None = None,
|
|
103
|
+
metadata: dict[str, Any] | None = None,
|
|
104
|
+
) -> tuple[Path, Path]:
|
|
105
|
+
"""
|
|
106
|
+
Create a Skill command file with structured metadata (webMCP pattern).
|
|
107
|
+
|
|
108
|
+
This function creates both:
|
|
109
|
+
1. A simple command file (`.cursor-skill-command.txt`) for backward compatibility
|
|
110
|
+
2. A structured metadata file (`.cursor-skill-metadata.json`) with workflow context
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
command: The Skill command (e.g., "@analyst gather-requirements ...")
|
|
114
|
+
worktree_path: Path to the worktree where the command should be executed
|
|
115
|
+
workflow_id: Optional workflow ID for tracking
|
|
116
|
+
step_id: Optional step ID for tracking
|
|
117
|
+
expected_artifacts: List of expected artifact file paths (relative to worktree)
|
|
118
|
+
metadata: Optional additional metadata dictionary
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
Tuple of (command_file_path, metadata_file_path)
|
|
122
|
+
"""
|
|
123
|
+
# Redact secrets from command before persisting
|
|
124
|
+
redacted_command = redact_secrets_from_text(command)
|
|
125
|
+
|
|
126
|
+
# Create correlation metadata header
|
|
127
|
+
correlation_metadata = {
|
|
128
|
+
"workflow_id": workflow_id,
|
|
129
|
+
"step_id": step_id,
|
|
130
|
+
"created_at": datetime.now().isoformat(),
|
|
131
|
+
"expected_artifacts": expected_artifacts or [],
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
# Existing command file (backward compatible)
|
|
135
|
+
command_file = worktree_path / ".cursor-skill-command.txt"
|
|
136
|
+
|
|
137
|
+
# Create a structured command file (maintains backward compatibility)
|
|
138
|
+
# Use redacted command for persistence, but include original if different
|
|
139
|
+
command_data = {
|
|
140
|
+
"command": redacted_command,
|
|
141
|
+
"correlation": correlation_metadata,
|
|
142
|
+
"worktree_path": str(worktree_path),
|
|
143
|
+
"instructions": (
|
|
144
|
+
"This command can be executed in Cursor by:\n"
|
|
145
|
+
"1. Copying the 'command' field below into Cursor chat\n"
|
|
146
|
+
"2. Or using a Background Agent configured to read this file\n"
|
|
147
|
+
"3. Or manually executing the command in the worktree directory"
|
|
148
|
+
),
|
|
149
|
+
"note": "Command has been redacted to remove secrets. Original command contains same structure.",
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
# If redaction changed the command, note it (but don't store original secrets)
|
|
153
|
+
if redacted_command != command:
|
|
154
|
+
command_data["redaction_applied"] = True
|
|
155
|
+
command_data["original_length"] = len(command)
|
|
156
|
+
|
|
157
|
+
# Write JSON format (backward compatible)
|
|
158
|
+
command_file.write_text(json.dumps(command_data, indent=2), encoding="utf-8")
|
|
159
|
+
|
|
160
|
+
# Also write a simple text version for easy copying (redacted)
|
|
161
|
+
simple_file = worktree_path / ".cursor-skill-command-simple.txt"
|
|
162
|
+
simple_file.write_text(redacted_command, encoding="utf-8")
|
|
163
|
+
|
|
164
|
+
# New structured metadata file (webMCP pattern)
|
|
165
|
+
metadata_file = worktree_path / ".cursor-skill-metadata.json"
|
|
166
|
+
structured_data = {
|
|
167
|
+
"version": "1.0",
|
|
168
|
+
"type": "skill_command",
|
|
169
|
+
"command": redacted_command, # Use redacted command
|
|
170
|
+
"correlation": correlation_metadata,
|
|
171
|
+
"workflow_context": {
|
|
172
|
+
"workflow_id": workflow_id,
|
|
173
|
+
"step_id": step_id,
|
|
174
|
+
"expected_artifacts": expected_artifacts or [],
|
|
175
|
+
},
|
|
176
|
+
"interaction_pattern": {
|
|
177
|
+
"mode": "async",
|
|
178
|
+
"completion_detection": "status_file_and_artifacts",
|
|
179
|
+
"progress_updates": True,
|
|
180
|
+
"error_handling": "retry_with_backoff",
|
|
181
|
+
},
|
|
182
|
+
"metadata": metadata or {},
|
|
183
|
+
"timestamp": datetime.now().isoformat(),
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
# Note if redaction was applied
|
|
187
|
+
if redacted_command != command:
|
|
188
|
+
structured_data["redaction_applied"] = True
|
|
189
|
+
|
|
190
|
+
metadata_file.write_text(
|
|
191
|
+
json.dumps(structured_data, indent=2), encoding="utf-8"
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
return command_file, metadata_file
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def create_skill_execution_instructions(
|
|
198
|
+
worktree_path: Path,
|
|
199
|
+
command: str,
|
|
200
|
+
expected_artifacts: list[str] | None = None,
|
|
201
|
+
workflow_id: str | None = None,
|
|
202
|
+
step_id: str | None = None,
|
|
203
|
+
) -> Path:
|
|
204
|
+
"""
|
|
205
|
+
Create execution instructions for a Skill command.
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
worktree_path: Path to the worktree
|
|
209
|
+
command: The Skill command (will be redacted)
|
|
210
|
+
expected_artifacts: List of expected artifact file paths
|
|
211
|
+
workflow_id: Optional workflow ID for correlation
|
|
212
|
+
step_id: Optional step ID for correlation
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
Path to the instructions file
|
|
216
|
+
"""
|
|
217
|
+
instructions_file = worktree_path / ".cursor-skill-instructions.md"
|
|
218
|
+
|
|
219
|
+
# Redact secrets from command in instructions
|
|
220
|
+
redacted_command = redact_secrets_from_text(command)
|
|
221
|
+
|
|
222
|
+
instructions = f"""# Cursor Skill Execution Instructions
|
|
223
|
+
|
|
224
|
+
## Correlation Metadata
|
|
225
|
+
|
|
226
|
+
- **Workflow ID**: {workflow_id or 'N/A'}
|
|
227
|
+
- **Step ID**: {step_id or 'N/A'}
|
|
228
|
+
- **Created At**: {datetime.now().isoformat()}
|
|
229
|
+
|
|
230
|
+
## Command to Execute
|
|
231
|
+
|
|
232
|
+
Copy and paste this command into Cursor chat:
|
|
233
|
+
|
|
234
|
+
```
|
|
235
|
+
{redacted_command}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
"""
|
|
239
|
+
|
|
240
|
+
if redacted_command != command:
|
|
241
|
+
instructions += "> **Note**: Command has been redacted to remove secrets. Execute in your environment with actual values.\n\n"
|
|
242
|
+
|
|
243
|
+
instructions += "## Expected Results\n\nAfter execution, the following artifacts should be created:\n\n"
|
|
244
|
+
|
|
245
|
+
if expected_artifacts:
|
|
246
|
+
for artifact in expected_artifacts:
|
|
247
|
+
instructions += f"- `{artifact}`\n"
|
|
248
|
+
else:
|
|
249
|
+
instructions += "- Check the worktree directory for generated files\n"
|
|
250
|
+
|
|
251
|
+
instructions += f"""
|
|
252
|
+
## Worktree Location
|
|
253
|
+
|
|
254
|
+
All work is done in: `{worktree_path}`
|
|
255
|
+
|
|
256
|
+
## Troubleshooting
|
|
257
|
+
|
|
258
|
+
If the step fails or times out:
|
|
259
|
+
1. Check the failure marker at: `.tapps-agents/workflows/markers/{workflow_id or 'WORKFLOW_ID'}/step-{step_id or 'STEP_ID'}/FAILED.json`
|
|
260
|
+
2. Verify expected artifacts were created
|
|
261
|
+
3. Check the command file: `.cursor-skill-command.txt`
|
|
262
|
+
|
|
263
|
+
## Next Steps
|
|
264
|
+
|
|
265
|
+
1. Execute the command in Cursor chat
|
|
266
|
+
2. Wait for the Skill to complete
|
|
267
|
+
3. Verify that expected artifacts are created
|
|
268
|
+
4. The workflow executor will detect completion when artifacts are present
|
|
269
|
+
"""
|
|
270
|
+
|
|
271
|
+
instructions_file.write_text(instructions, encoding="utf-8")
|
|
272
|
+
return instructions_file
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def check_skill_completion(
|
|
276
|
+
worktree_path: Path,
|
|
277
|
+
expected_artifacts: list[str] | None = None,
|
|
278
|
+
workflow_id: str | None = None,
|
|
279
|
+
step_id: str | None = None,
|
|
280
|
+
) -> dict[str, Any]:
|
|
281
|
+
"""
|
|
282
|
+
Check if a Skill command has completed by looking for expected artifacts.
|
|
283
|
+
|
|
284
|
+
Args:
|
|
285
|
+
worktree_path: Path to the worktree
|
|
286
|
+
expected_artifacts: List of expected artifact file paths (relative to worktree)
|
|
287
|
+
workflow_id: Optional workflow ID for marker location reference
|
|
288
|
+
step_id: Optional step ID for marker location reference
|
|
289
|
+
|
|
290
|
+
Returns:
|
|
291
|
+
Dictionary with completion status, found artifacts, and marker locations
|
|
292
|
+
"""
|
|
293
|
+
result = {
|
|
294
|
+
"completed": False,
|
|
295
|
+
"found_artifacts": [],
|
|
296
|
+
"missing_artifacts": [],
|
|
297
|
+
"worktree_path": str(worktree_path),
|
|
298
|
+
"marker_locations": {},
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
# Check for DONE/FAILED markers in marker directory
|
|
302
|
+
if workflow_id and step_id:
|
|
303
|
+
project_root = worktree_path
|
|
304
|
+
# Try to find project root by looking for .tapps-agents
|
|
305
|
+
while project_root != project_root.parent:
|
|
306
|
+
if (project_root / ".tapps-agents").exists():
|
|
307
|
+
break
|
|
308
|
+
project_root = project_root.parent
|
|
309
|
+
|
|
310
|
+
marker_dir = (
|
|
311
|
+
project_root
|
|
312
|
+
/ ".tapps-agents"
|
|
313
|
+
/ "workflows"
|
|
314
|
+
/ "markers"
|
|
315
|
+
/ workflow_id
|
|
316
|
+
/ f"step-{step_id}"
|
|
317
|
+
)
|
|
318
|
+
done_marker = marker_dir / "DONE.json"
|
|
319
|
+
failed_marker = marker_dir / "FAILED.json"
|
|
320
|
+
|
|
321
|
+
if done_marker.exists():
|
|
322
|
+
result["completed"] = True
|
|
323
|
+
result["completion_type"] = "marker"
|
|
324
|
+
result["marker_locations"]["done"] = str(done_marker)
|
|
325
|
+
# Try to read marker for artifact info
|
|
326
|
+
try:
|
|
327
|
+
marker_data = json.loads(done_marker.read_text(encoding="utf-8"))
|
|
328
|
+
result["found_artifacts"] = marker_data.get("found_artifacts", [])
|
|
329
|
+
result["expected_artifacts"] = marker_data.get("expected_artifacts", [])
|
|
330
|
+
except Exception:
|
|
331
|
+
pass
|
|
332
|
+
return result
|
|
333
|
+
elif failed_marker.exists():
|
|
334
|
+
result["completed"] = True # Technically completed (with failure)
|
|
335
|
+
result["completion_type"] = "failed_marker"
|
|
336
|
+
result["marker_locations"]["failed"] = str(failed_marker)
|
|
337
|
+
# Try to read marker for error info
|
|
338
|
+
try:
|
|
339
|
+
marker_data = json.loads(failed_marker.read_text(encoding="utf-8"))
|
|
340
|
+
result["error"] = marker_data.get("error", "Unknown error")
|
|
341
|
+
result["error_type"] = marker_data.get("error_type")
|
|
342
|
+
result["found_artifacts"] = marker_data.get("found_artifacts", [])
|
|
343
|
+
result["expected_artifacts"] = marker_data.get("expected_artifacts", [])
|
|
344
|
+
except Exception:
|
|
345
|
+
pass
|
|
346
|
+
return result
|
|
347
|
+
|
|
348
|
+
if not expected_artifacts:
|
|
349
|
+
# If no expected artifacts, check for common ones
|
|
350
|
+
common_artifacts = [
|
|
351
|
+
"requirements.md",
|
|
352
|
+
"stories",
|
|
353
|
+
"architecture.md",
|
|
354
|
+
"api-specs",
|
|
355
|
+
"src",
|
|
356
|
+
"tests",
|
|
357
|
+
"docs",
|
|
358
|
+
]
|
|
359
|
+
expected_artifacts = common_artifacts
|
|
360
|
+
|
|
361
|
+
# Check artifact files with last modified times
|
|
362
|
+
artifact_details = []
|
|
363
|
+
for artifact_path in expected_artifacts:
|
|
364
|
+
full_path = worktree_path / artifact_path
|
|
365
|
+
if full_path.exists():
|
|
366
|
+
result["found_artifacts"].append(artifact_path)
|
|
367
|
+
try:
|
|
368
|
+
mtime = full_path.stat().st_mtime
|
|
369
|
+
artifact_details.append({
|
|
370
|
+
"path": artifact_path,
|
|
371
|
+
"exists": True,
|
|
372
|
+
"last_modified": datetime.fromtimestamp(mtime).isoformat(),
|
|
373
|
+
})
|
|
374
|
+
except OSError:
|
|
375
|
+
artifact_details.append({
|
|
376
|
+
"path": artifact_path,
|
|
377
|
+
"exists": True,
|
|
378
|
+
"last_modified": None,
|
|
379
|
+
})
|
|
380
|
+
else:
|
|
381
|
+
result["missing_artifacts"].append(artifact_path)
|
|
382
|
+
artifact_details.append({
|
|
383
|
+
"path": artifact_path,
|
|
384
|
+
"exists": False,
|
|
385
|
+
})
|
|
386
|
+
|
|
387
|
+
result["artifact_details"] = artifact_details
|
|
388
|
+
|
|
389
|
+
# Check for background agent artifacts (quality/testing)
|
|
390
|
+
quality_report = worktree_path / "reports" / "quality" / "quality-report.json"
|
|
391
|
+
test_report = worktree_path / "reports" / "tests" / "test-report.json"
|
|
392
|
+
|
|
393
|
+
if quality_report.exists():
|
|
394
|
+
result["found_artifacts"].append("reports/quality/quality-report.json")
|
|
395
|
+
if test_report.exists():
|
|
396
|
+
result["found_artifacts"].append("reports/tests/test-report.json")
|
|
397
|
+
|
|
398
|
+
# Consider complete if at least one expected artifact exists
|
|
399
|
+
# or if a completion marker exists
|
|
400
|
+
completion_marker = worktree_path / ".skill-completed.txt"
|
|
401
|
+
if completion_marker.exists() or result["found_artifacts"]:
|
|
402
|
+
result["completed"] = True
|
|
403
|
+
result["completion_type"] = "artifacts"
|
|
404
|
+
|
|
405
|
+
return result
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
def read_skill_metadata(worktree_path: Path) -> dict[str, Any] | None:
|
|
409
|
+
"""
|
|
410
|
+
Read structured metadata from a worktree.
|
|
411
|
+
|
|
412
|
+
Args:
|
|
413
|
+
worktree_path: Path to the worktree containing metadata
|
|
414
|
+
|
|
415
|
+
Returns:
|
|
416
|
+
Dictionary with metadata if found, None otherwise
|
|
417
|
+
"""
|
|
418
|
+
metadata_file = worktree_path / ".cursor-skill-metadata.json"
|
|
419
|
+
|
|
420
|
+
if not metadata_file.exists():
|
|
421
|
+
return None
|
|
422
|
+
|
|
423
|
+
try:
|
|
424
|
+
metadata_content = metadata_file.read_text(encoding="utf-8")
|
|
425
|
+
return json.loads(metadata_content)
|
|
426
|
+
except (json.JSONDecodeError, OSError) as e:
|
|
427
|
+
# Log error but don't fail - metadata is optional
|
|
428
|
+
import logging
|
|
429
|
+
logger = logging.getLogger(__name__)
|
|
430
|
+
logger.warning(f"Failed to read skill metadata from {metadata_file}: {e}")
|
|
431
|
+
return None
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
def get_expected_artifacts_from_metadata(worktree_path: Path) -> list[str]:
|
|
435
|
+
"""
|
|
436
|
+
Extract expected artifacts from metadata file.
|
|
437
|
+
|
|
438
|
+
Args:
|
|
439
|
+
worktree_path: Path to the worktree containing metadata
|
|
440
|
+
|
|
441
|
+
Returns:
|
|
442
|
+
List of expected artifact paths, empty list if metadata not found
|
|
443
|
+
"""
|
|
444
|
+
metadata = read_skill_metadata(worktree_path)
|
|
445
|
+
if not metadata:
|
|
446
|
+
return []
|
|
447
|
+
|
|
448
|
+
workflow_context = metadata.get("workflow_context", {})
|
|
449
|
+
return workflow_context.get("expected_artifacts", [])
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
def write_structured_status_file(
|
|
453
|
+
status_file: Path,
|
|
454
|
+
status: str,
|
|
455
|
+
progress: dict[str, Any] | None = None,
|
|
456
|
+
partial_results: dict[str, Any] | None = None,
|
|
457
|
+
error: dict[str, Any] | None = None,
|
|
458
|
+
artifacts: list[str] | None = None,
|
|
459
|
+
output: str | None = None,
|
|
460
|
+
metadata: dict[str, Any] | None = None,
|
|
461
|
+
started_at: str | None = None,
|
|
462
|
+
completed_at: str | None = None,
|
|
463
|
+
) -> None:
|
|
464
|
+
"""
|
|
465
|
+
Write structured status file (Phase 4 - Enhanced format).
|
|
466
|
+
|
|
467
|
+
This function creates a structured status file that includes:
|
|
468
|
+
- Progress updates (percentage, current step, message)
|
|
469
|
+
- Partial results (artifacts, output)
|
|
470
|
+
- Error details (message, code, retryable, retry_count)
|
|
471
|
+
- Metadata (workflow_id, step_id, command)
|
|
472
|
+
|
|
473
|
+
Args:
|
|
474
|
+
status_file: Path to status file to write
|
|
475
|
+
status: Status string ("running", "completed", "failed", "pending")
|
|
476
|
+
progress: Optional progress information
|
|
477
|
+
partial_results: Optional partial results
|
|
478
|
+
error: Optional error information
|
|
479
|
+
artifacts: Optional list of artifact paths
|
|
480
|
+
output: Optional execution output
|
|
481
|
+
metadata: Optional metadata (workflow_id, step_id, command)
|
|
482
|
+
started_at: Optional ISO datetime string for start time
|
|
483
|
+
completed_at: Optional ISO datetime string for completion time
|
|
484
|
+
"""
|
|
485
|
+
status_data = {
|
|
486
|
+
"version": "1.0",
|
|
487
|
+
"status": status,
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
if started_at:
|
|
491
|
+
status_data["started_at"] = started_at
|
|
492
|
+
if completed_at:
|
|
493
|
+
status_data["completed_at"] = completed_at
|
|
494
|
+
|
|
495
|
+
if progress:
|
|
496
|
+
status_data["progress"] = progress
|
|
497
|
+
|
|
498
|
+
if partial_results:
|
|
499
|
+
status_data["partial_results"] = partial_results
|
|
500
|
+
|
|
501
|
+
if error:
|
|
502
|
+
status_data["error"] = error
|
|
503
|
+
|
|
504
|
+
if artifacts:
|
|
505
|
+
status_data["artifacts"] = artifacts
|
|
506
|
+
|
|
507
|
+
if output:
|
|
508
|
+
status_data["output"] = output
|
|
509
|
+
|
|
510
|
+
if metadata:
|
|
511
|
+
status_data["metadata"] = metadata
|
|
512
|
+
|
|
513
|
+
status_file.write_text(
|
|
514
|
+
json.dumps(status_data, indent=2), encoding="utf-8"
|
|
515
|
+
)
|
|
516
|
+
|