claude-flow-novice 2.15.3 → 2.15.4
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.
- package/.claude/cfn-extras/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
- package/.claude/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
- package/.claude/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
- package/.claude/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
- package/.claude/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
- package/.claude/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
- package/.claude/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
- package/.claude/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
- package/.claude/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
- package/.claude/commands/cfn-loop-cli.md +16 -2
- package/.claude/commands/switch-api.md +31 -10
- package/.claude/hooks/cfn-lint-sql-injection.sh +61 -0
- package/.claude/hooks/cfn-post-edit-cfn-retrospective.sh +33 -2
- package/.claude/hooks/cfn-pre-edit-security-warning.sh +40 -0
- package/.claude/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
- package/.claude/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
- package/.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
- package/.claude/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
- package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
- package/.claude/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +184 -23
- package/.claude/skills/cfn-loop-orchestration/security_utils.sh +24 -0
- package/.claude/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
- package/.claude/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
- package/.claude/skills/cfn-redis-coordination/agent-log.sh +4 -0
- package/.claude/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
- package/.claude/skills/cfn-redis-coordination/agent-recovery.sh +2 -2
- package/.claude/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
- package/.claude/skills/cfn-redis-coordination/get-context.sh +33 -0
- package/.claude/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
- package/.claude/skills/cfn-redis-coordination/invoke-waiting-mode.sh +3 -0
- package/.claude/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
- package/.claude/skills/cfn-redis-coordination/redis-functions.sh +33 -0
- package/.claude/skills/cfn-redis-coordination/report-completion.sh +24 -31
- package/.claude/skills/cfn-redis-coordination/store-context.sh +4 -0
- package/.claude/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
- package/.claude/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
- package/.claude/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
- package/.claude/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
- package/.claude/skills/cfn-transparency-middleware/tests/input-validation.sh +15 -0
- package/README.md +116 -475
- package/claude-assets/agents/cfn-dev-team/README.md +103 -0
- package/claude-assets/agents/cfn-dev-team/architecture/goal-planner.md +1 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +77 -15
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +355 -6
- package/claude-assets/agents/cfn-dev-team/coordinators/consensus-builder.md +82 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +82 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/multi-sprint-coordinator.md +77 -15
- package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +99 -12
- package/claude-assets/agents/cfn-dev-team/dev-ops/github-commit-agent.md +1 -1
- package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +97 -0
- package/claude-assets/agents/cfn-dev-team/dev-ops/monitoring-specialist.md +20 -1
- package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +97 -0
- package/claude-assets/agents/cfn-dev-team/developers/backend-developer.md +110 -13
- package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +106 -15
- package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +115 -11
- package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +94 -7
- package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +87 -9
- package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +85 -7
- package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +160 -28
- package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +101 -19
- package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +108 -14
- package/claude-assets/agents/cfn-dev-team/reviewers/{reviewer.md → code-reviewer.md} +95 -8
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +107 -7
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +98 -7
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +95 -7
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +136 -9
- package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +108 -1
- package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +107 -13
- package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +737 -0
- package/claude-assets/agents/cfn-dev-team/testers/e2e/playwright-tester.md +1 -1
- package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +828 -0
- package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +106 -7
- package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +77 -0
- package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +684 -0
- package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +110 -1
- package/claude-assets/agents/cfn-dev-team/testers/tester.md +94 -7
- package/claude-assets/agents/cfn-dev-team/utility/code-booster.md +1 -3
- package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +87 -13
- package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +103 -7
- package/claude-assets/agents/cfn-dev-team/utility/researcher.md +1 -3
- package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +94 -7
- package/claude-assets/agents/docker-coordinators/cfn-docker-v3-coordinator.md +46 -0
- package/claude-assets/agents/project-only-agents/npm-package-specialist.md +1 -1
- package/claude-assets/cfn-extras/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
- package/claude-assets/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
- package/claude-assets/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
- package/claude-assets/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
- package/claude-assets/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
- package/claude-assets/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
- package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
- package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
- package/claude-assets/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
- package/claude-assets/commands/cfn-loop-cli.md +16 -2
- package/claude-assets/commands/switch-api.md +31 -10
- package/claude-assets/hooks/cfn-lint-sql-injection.sh +61 -0
- package/claude-assets/hooks/cfn-post-edit-cfn-retrospective.sh +33 -2
- package/claude-assets/hooks/cfn-pre-edit-security-warning.sh +40 -0
- package/claude-assets/hooks/detect-hardcoded-credentials.sh +212 -0
- package/claude-assets/skills/SKILL_TEMPLATE.md +774 -0
- package/claude-assets/skills/agent-lifecycle/execute-lifecycle-hook.sh +84 -113
- package/claude-assets/skills/agent-lifecycle/simple-audit.sh +33 -6
- package/claude-assets/skills/agent-template-generator/SKILL.md +440 -0
- package/claude-assets/skills/agent-template-generator/generate-agent.sh +405 -0
- package/claude-assets/skills/agent-validation-linter/SKILL.md +589 -0
- package/claude-assets/skills/agent-validation-linter/lint-agents.sh +271 -0
- package/claude-assets/skills/bootstrap/bash-fundamentals.md +786 -0
- package/claude-assets/skills/bootstrap/database-connection.md +464 -0
- package/claude-assets/skills/bootstrap/error-handling.md +580 -0
- package/claude-assets/skills/bootstrap/file-operations.md +699 -0
- package/claude-assets/skills/bootstrap/skill-loader.md +616 -0
- package/claude-assets/skills/bootstrap/sqlite-params.sh +287 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
- package/claude-assets/skills/cfn-automatic-memory-persistence/test-memory-persistence.sh +17 -16
- package/claude-assets/skills/cfn-deployment/SKILL.md +293 -0
- package/claude-assets/skills/cfn-deployment/execute.sh +21 -0
- package/claude-assets/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
- package/claude-assets/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
- package/claude-assets/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
- package/claude-assets/skills/cfn-environment-sanitization/sanitize-environment.sh +38 -0
- package/claude-assets/skills/cfn-error-batching-strategy/lib/core-functions.sh +47 -47
- package/claude-assets/skills/cfn-file-operations/SKILL.md +290 -0
- package/claude-assets/skills/cfn-file-operations/execute.sh +129 -0
- package/claude-assets/skills/cfn-file-operations/lib/atomic-write.sh +294 -0
- package/claude-assets/skills/cfn-file-operations/lib/lock.sh +361 -0
- package/claude-assets/skills/cfn-file-operations/test.sh +369 -0
- package/claude-assets/skills/cfn-log-operations/SKILL.md +308 -0
- package/claude-assets/skills/cfn-log-operations/execute.sh +420 -0
- package/claude-assets/skills/cfn-log-operations/lib/rotate.sh +406 -0
- package/claude-assets/skills/cfn-log-operations/lib/search.sh +448 -0
- package/claude-assets/skills/cfn-log-operations/test.sh +394 -0
- package/claude-assets/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
- package/claude-assets/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +184 -23
- package/claude-assets/skills/cfn-loop-orchestration/security_utils.sh +24 -0
- package/claude-assets/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
- package/claude-assets/skills/cfn-parameterized-queries/SKILL.md +339 -0
- package/claude-assets/skills/cfn-playbook/query-playbook.sh +19 -15
- package/claude-assets/skills/cfn-playbook/update-playbook.sh +25 -14
- package/claude-assets/skills/cfn-process-instrumentation/instrument-process.sh +44 -0
- package/claude-assets/skills/cfn-promotion/SKILL.md +305 -0
- package/claude-assets/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
- package/claude-assets/skills/cfn-redis-coordination/agent-log.sh +4 -0
- package/claude-assets/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
- package/claude-assets/skills/cfn-redis-coordination/agent-recovery.sh +2 -2
- package/claude-assets/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
- package/claude-assets/skills/cfn-redis-coordination/get-context.sh +33 -0
- package/claude-assets/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
- package/claude-assets/skills/cfn-redis-coordination/invoke-waiting-mode.sh +3 -0
- package/claude-assets/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
- package/claude-assets/skills/cfn-redis-coordination/redis-functions.sh +33 -0
- package/claude-assets/skills/cfn-redis-coordination/report-completion.sh +24 -31
- package/claude-assets/skills/cfn-redis-coordination/store-context.sh +4 -0
- package/claude-assets/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
- package/claude-assets/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
- package/claude-assets/skills/cfn-skill-loader/SKILL.md +466 -0
- package/claude-assets/skills/cfn-skill-loader/execute.sh +344 -0
- package/claude-assets/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
- package/claude-assets/skills/cfn-task-audit/get-audit-data.sh +42 -21
- package/claude-assets/skills/cfn-task-audit/store-task-audit.sh +17 -10
- package/claude-assets/skills/cfn-test-runner/detect-regressions.sh +17 -14
- package/claude-assets/skills/cfn-test-runner/detect-regressions.sh.backup-1763392821 +55 -0
- package/claude-assets/skills/cfn-test-runner/store-benchmarks.sh +17 -19
- package/claude-assets/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
- package/claude-assets/skills/cfn-transparency-middleware/tests/input-validation.sh +15 -0
- package/claude-assets/skills/cfn-utilities/SKILL.md +237 -0
- package/claude-assets/skills/cfn-utilities/execute.sh +32 -0
- package/claude-assets/skills/cfn-utilities/lib/errors.sh +56 -0
- package/claude-assets/skills/cfn-utilities/lib/file-ops.sh +164 -0
- package/claude-assets/skills/cfn-utilities/lib/logging.sh +77 -0
- package/claude-assets/skills/cfn-utilities/lib/retry.sh +127 -0
- package/claude-assets/skills/cfn-utilities/test.sh +317 -0
- package/claude-assets/skills/integration/agent-handoff.sh +62 -64
- package/claude-assets/skills/json-validation/SKILL.md +431 -0
- package/claude-assets/skills/json-validation/test-validate-success-criteria.sh +421 -0
- package/claude-assets/skills/json-validation/validate-success-criteria.sh +197 -0
- package/claude-assets/skills/redis-coordination/validate-parameters.sh +34 -0
- package/claude-assets/skills/workflow-codification/DEPLOY_QUICK_REFERENCE.md +106 -0
- package/claude-assets/skills/workflow-codification/PROPAGATE_UPDATE_QUICK_REFERENCE.md +366 -0
- package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh +481 -0
- package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh.backup-1763392820 +512 -0
- package/claude-assets/skills/workflow-codification/lib/security-utils.sh +204 -0
- package/claude-assets/skills/workflow-codification/propagate-skill-update.sh +648 -0
- package/claude-assets/skills/workflow-codification/propagate-skill-update.sh.backup-1763392820 +664 -0
- package/claude-assets/skills/workflow-codification/test-integration.sh +15 -0
- package/claude-assets/skills/workflow-codification/test-metadata-update.sh +350 -0
- package/claude-assets/skills/workflow-codification/track-cost-savings.sh +55 -14
- package/claude-assets/skills/workflow-codification/track-cost-savings.sh.backup-1763392821 +445 -0
- package/claude-assets/skills/workflow-codification/track-edge-case.sh +27 -60
- package/claude-assets/skills/workflow-codification/workflow-codification.db +0 -0
- package/dist/ace/ace-curator.js +10 -2
- package/dist/ace/ace-curator.js.map +1 -1
- package/dist/ace/ace-generator.js +4 -0
- package/dist/ace/ace-generator.js.map +1 -1
- package/dist/ace/ace-reflector.js +1 -1
- package/dist/ace/ace-reflector.js.map +1 -1
- package/dist/ace/context-injection.js +24 -2
- package/dist/ace/context-injection.js.map +1 -1
- package/dist/agents/agent-loader.js +146 -165
- package/dist/agents/agent-loader.js.map +1 -1
- package/dist/agents/task-agent-integration.js +1 -1
- package/dist/agents/task-agent-integration.js.map +1 -1
- package/dist/api/health-endpoints.js +390 -0
- package/dist/api/health-endpoints.js.map +1 -0
- package/dist/cli/agent-executor.js +4 -1
- package/dist/cli/agent-executor.js.map +1 -1
- package/dist/cli/agent-prompt-builder.js +89 -1
- package/dist/cli/agent-prompt-builder.js.map +1 -1
- package/dist/cli/agent-spawn.js +130 -37
- package/dist/cli/agent-spawn.js.map +1 -1
- package/dist/cli/skill-cache-validator.js +412 -0
- package/dist/cli/skill-cache-validator.js.map +1 -0
- package/dist/cli/skill-cli.js +991 -0
- package/dist/cli/skill-cli.js.map +1 -0
- package/dist/cli/skill-execution-logger.js +284 -0
- package/dist/cli/skill-execution-logger.js.map +1 -0
- package/dist/cli/skill-loader.js +457 -0
- package/dist/cli/skill-loader.js.map +1 -0
- package/dist/coordination/event-bus.js +2 -2
- package/dist/coordination/event-bus.js.map +1 -1
- package/dist/coordination/fleet-manager.js +1 -1
- package/dist/coordination/fleet-manager.js.map +1 -1
- package/dist/coordination/index.js +23 -9
- package/dist/coordination/index.js.map +1 -1
- package/dist/coordination/types/fleet-manager.types.js.map +1 -1
- package/dist/db/migration-manager.js +483 -0
- package/dist/db/migration-manager.js.map +1 -0
- package/dist/db/skills-query.js +535 -0
- package/dist/db/skills-query.js.map +1 -0
- package/dist/integration/DatabaseHandoff.js +1 -1
- package/dist/integration/DatabaseHandoff.js.map +1 -1
- package/dist/jobs/edge-case-analyzer.js +367 -0
- package/dist/jobs/edge-case-analyzer.js.map +1 -0
- package/dist/jobs/promotion-sla-enforcer.js +288 -0
- package/dist/jobs/promotion-sla-enforcer.js.map +1 -0
- package/dist/lib/agent-output-parser.js.map +1 -1
- package/dist/lib/agent-output-validator.js.map +1 -1
- package/dist/lib/agent-workspace.js +281 -0
- package/dist/lib/agent-workspace.js.map +1 -0
- package/dist/lib/atomic-file-writer.js +377 -0
- package/dist/lib/atomic-file-writer.js.map +1 -0
- package/dist/lib/backup-manager.js +779 -0
- package/dist/lib/backup-manager.js.map +1 -0
- package/dist/lib/checkpoint-manager.js +837 -0
- package/dist/lib/checkpoint-manager.js.map +1 -0
- package/dist/lib/circuit-breaker.js +340 -0
- package/dist/lib/circuit-breaker.js.map +1 -0
- package/dist/lib/completion-signal-handler.js +243 -0
- package/dist/lib/completion-signal-handler.js.map +1 -0
- package/dist/lib/config-manager.js +312 -0
- package/dist/lib/config-manager.js.map +1 -0
- package/dist/lib/config-migrator.js +386 -0
- package/dist/lib/config-migrator.js.map +1 -0
- package/dist/lib/config-validator.js.map +1 -1
- package/dist/lib/correlation-cache.js +311 -0
- package/dist/lib/correlation-cache.js.map +1 -0
- package/dist/lib/correlation.js +263 -0
- package/dist/lib/correlation.js.map +1 -0
- package/dist/lib/database-service/connection-pool-manager.js +520 -0
- package/dist/lib/database-service/connection-pool-manager.js.map +1 -0
- package/dist/lib/database-service/correlation.js +329 -0
- package/dist/lib/database-service/correlation.js.map +1 -0
- package/dist/lib/database-service/errors.js +120 -0
- package/dist/lib/database-service/errors.js.map +1 -0
- package/dist/lib/database-service/index.js +168 -0
- package/dist/lib/database-service/index.js.map +1 -0
- package/dist/lib/database-service/postgres-adapter.js +526 -0
- package/dist/lib/database-service/postgres-adapter.js.map +1 -0
- package/dist/lib/database-service/redis-adapter.js +360 -0
- package/dist/lib/database-service/redis-adapter.js.map +1 -0
- package/dist/lib/database-service/sqlite-adapter.js +544 -0
- package/dist/lib/database-service/sqlite-adapter.js.map +1 -0
- package/dist/lib/database-service/transaction-manager.js +773 -0
- package/dist/lib/database-service/transaction-manager.js.map +1 -0
- package/dist/lib/database-service/types.js +23 -0
- package/dist/lib/database-service/types.js.map +1 -0
- package/dist/lib/deadlock-resolver.js +292 -0
- package/dist/lib/deadlock-resolver.js.map +1 -0
- package/dist/lib/distributed-lock.js +451 -0
- package/dist/lib/distributed-lock.js.map +1 -0
- package/dist/lib/edge-case-deduplicator.js +227 -0
- package/dist/lib/edge-case-deduplicator.js.map +1 -0
- package/dist/lib/encryption-manager.js +322 -0
- package/dist/lib/encryption-manager.js.map +1 -0
- package/dist/lib/error-aggregator.js +234 -0
- package/dist/lib/error-aggregator.js.map +1 -0
- package/dist/lib/errors.js +287 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/file-lock-manager.js +578 -0
- package/dist/lib/file-lock-manager.js.map +1 -0
- package/dist/lib/file-operations.js +367 -0
- package/dist/lib/file-operations.js.map +1 -0
- package/dist/lib/idempotent-write.js +237 -0
- package/dist/lib/idempotent-write.js.map +1 -0
- package/dist/lib/integration-schema-validator.js +522 -0
- package/dist/lib/integration-schema-validator.js.map +1 -0
- package/dist/lib/lock-health-monitor.js +298 -0
- package/dist/lib/lock-health-monitor.js.map +1 -0
- package/dist/lib/log-shipper.js +422 -0
- package/dist/lib/log-shipper.js.map +1 -0
- package/dist/lib/logging.js +146 -0
- package/dist/lib/logging.js.map +1 -0
- package/dist/lib/message-deduplicator.js +439 -0
- package/dist/lib/message-deduplicator.js.map +1 -0
- package/dist/lib/multi-system-query.js +604 -0
- package/dist/lib/multi-system-query.js.map +1 -0
- package/dist/lib/orphan-detector.js +332 -0
- package/dist/lib/orphan-detector.js.map +1 -0
- package/dist/lib/password-generator.js +166 -0
- package/dist/lib/password-generator.js.map +1 -0
- package/dist/lib/path-validator.js +429 -0
- package/dist/lib/path-validator.js.map +1 -0
- package/dist/lib/query-translator.js +905 -0
- package/dist/lib/query-translator.js.map +1 -0
- package/dist/lib/queue-recovery.js +469 -0
- package/dist/lib/queue-recovery.js.map +1 -0
- package/dist/lib/redis-queue-manager.js +512 -0
- package/dist/lib/redis-queue-manager.js.map +1 -0
- package/dist/lib/reflection-archiver.js +272 -0
- package/dist/lib/reflection-archiver.js.map +1 -0
- package/dist/lib/retry-manager.js +453 -0
- package/dist/lib/retry-manager.js.map +1 -0
- package/dist/lib/retry.js +262 -0
- package/dist/lib/retry.js.map +1 -0
- package/dist/lib/schema-transform.js +695 -0
- package/dist/lib/schema-transform.js.map +1 -0
- package/dist/lib/schema-validator.js +491 -0
- package/dist/lib/schema-validator.js.map +1 -0
- package/dist/lib/skill-cache.js +297 -0
- package/dist/lib/skill-cache.js.map +1 -0
- package/dist/lib/skill-content-manager.js +337 -0
- package/dist/lib/skill-content-manager.js.map +1 -0
- package/dist/lib/skill-frontmatter-parser.js +237 -0
- package/dist/lib/skill-frontmatter-parser.js.map +1 -0
- package/dist/lib/skill-git-integration.js +275 -0
- package/dist/lib/skill-git-integration.js.map +1 -0
- package/dist/lib/skill-markdown-validator.js +396 -0
- package/dist/lib/skill-markdown-validator.js.map +1 -0
- package/dist/lib/skill-output-parser.js +312 -0
- package/dist/lib/skill-output-parser.js.map +1 -0
- package/dist/lib/unified-query-api.js +467 -0
- package/dist/lib/unified-query-api.js.map +1 -0
- package/dist/middleware/auth-middleware.js +350 -0
- package/dist/middleware/auth-middleware.js.map +1 -0
- package/dist/middleware/schema-validation.js +347 -0
- package/dist/middleware/schema-validation.js.map +1 -0
- package/dist/providers/anthropic-provider.js +1 -1
- package/dist/providers/anthropic-provider.js.map +1 -1
- package/dist/providers/provider-factory.js +2 -2
- package/dist/providers/provider-factory.js.map +1 -1
- package/dist/services/edge-case-analyzer.js +321 -0
- package/dist/services/edge-case-analyzer.js.map +1 -0
- package/dist/services/edge-case-deduplicator.js +266 -0
- package/dist/services/edge-case-deduplicator.js.map +1 -0
- package/dist/services/edge-case-detector.js +337 -0
- package/dist/services/edge-case-detector.js.map +1 -0
- package/dist/services/edge-case-tracker.js +547 -0
- package/dist/services/edge-case-tracker.js.map +1 -0
- package/dist/services/health-check-system.js +586 -0
- package/dist/services/health-check-system.js.map +1 -0
- package/dist/services/metrics-logger.js +412 -0
- package/dist/services/metrics-logger.js.map +1 -0
- package/dist/services/patch-generator.js +378 -0
- package/dist/services/patch-generator.js.map +1 -0
- package/dist/services/patch-validator.js +337 -0
- package/dist/services/patch-validator.js.map +1 -0
- package/dist/services/performance-monitor.js +811 -0
- package/dist/services/performance-monitor.js.map +1 -0
- package/dist/services/promotion-pipeline.js +918 -0
- package/dist/services/promotion-pipeline.js.map +1 -0
- package/dist/services/promotion-validator.js +394 -0
- package/dist/services/promotion-validator.js.map +1 -0
- package/dist/services/reflection-logger.js +388 -0
- package/dist/services/reflection-logger.js.map +1 -0
- package/dist/services/skill-deployment.js +472 -0
- package/dist/services/skill-deployment.js.map +1 -0
- package/dist/services/skill-loader.js +427 -0
- package/dist/services/skill-loader.js.map +1 -0
- package/dist/services/skill-promotion.js +372 -0
- package/dist/services/skill-promotion.js.map +1 -0
- package/dist/services/skill-validator.js +454 -0
- package/dist/services/skill-validator.js.map +1 -0
- package/dist/services/skill-versioning.js +244 -0
- package/dist/services/skill-versioning.js.map +1 -0
- package/dist/services/workspace-supervisor.js +597 -0
- package/dist/services/workspace-supervisor.js.map +1 -0
- package/dist/types/edge-case.js +45 -0
- package/dist/types/edge-case.js.map +1 -0
- package/package.json +201 -177
- package/readme/README.md +19 -4
- package/scripts/backup-cleanup.sh +627 -0
- package/scripts/cleanup-workspaces.sh +412 -0
- package/scripts/cleanup-yaml-configs.sh +141 -0
- package/scripts/deploy-approved-skills.sh +263 -0
- package/scripts/health-check.sh +447 -0
- package/scripts/log-aggregator.sh +554 -0
- package/scripts/log-monitor.sh +629 -0
- package/scripts/manage-agent-workspaces.sh +434 -0
- package/scripts/migrate-schema.sh +533 -0
- package/scripts/promote-staged-skills.sh +423 -0
- package/scripts/verify-no-secrets.sh +88 -35
- package/.claude/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
- package/.claude/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
- package/.claude/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
- package/.claude/skills/agent-lifecycle/SKILL.md +0 -60
- package/.claude/skills/agent-lifecycle/execute-lifecycle-hook.sh +0 -573
- package/.claude/skills/agent-lifecycle/simple-audit.sh +0 -31
- package/.claude/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
- package/README.md.backup_before_replace +0 -781
- package/claude-assets/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
- package/claude-assets/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
- package/claude-assets/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry and Backoff Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides retry logic with exponential backoff for transient failures.
|
|
5
|
+
* Part of Task 0.5: Implementation Tooling & Utilities (Foundation)
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* const result = await withRetry(
|
|
9
|
+
* async () => fetchData(),
|
|
10
|
+
* { maxAttempts: 3, baseDelayMs: 1000, exponential: true }
|
|
11
|
+
* );
|
|
12
|
+
*/ import { createRetryExhaustedError, isRetryableError } from './errors.js';
|
|
13
|
+
import { createLogger } from './logging.js';
|
|
14
|
+
const logger = createLogger('retry-utility');
|
|
15
|
+
/**
|
|
16
|
+
* Default retry options
|
|
17
|
+
*/ const DEFAULT_RETRY_OPTIONS = {
|
|
18
|
+
maxAttempts: 3,
|
|
19
|
+
baseDelayMs: 1000,
|
|
20
|
+
maxDelayMs: 30000,
|
|
21
|
+
exponential: true,
|
|
22
|
+
jitter: true
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Execute a function with retry logic
|
|
26
|
+
*
|
|
27
|
+
* @param fn - Async function to execute
|
|
28
|
+
* @param options - Retry options
|
|
29
|
+
* @returns Result of the function
|
|
30
|
+
* @throws RetryExhaustedError if all attempts fail
|
|
31
|
+
*/ export async function withRetry(fn, options = {}) {
|
|
32
|
+
const opts = {
|
|
33
|
+
...DEFAULT_RETRY_OPTIONS,
|
|
34
|
+
...options
|
|
35
|
+
};
|
|
36
|
+
const errors = [];
|
|
37
|
+
const delays = [];
|
|
38
|
+
const startTime = Date.now();
|
|
39
|
+
let attempt = 0;
|
|
40
|
+
while(attempt < opts.maxAttempts){
|
|
41
|
+
attempt++;
|
|
42
|
+
try {
|
|
43
|
+
logger.debug('Retry attempt', {
|
|
44
|
+
attempt,
|
|
45
|
+
maxAttempts: opts.maxAttempts
|
|
46
|
+
});
|
|
47
|
+
const result = await fn();
|
|
48
|
+
// Success!
|
|
49
|
+
if (attempt > 1) {
|
|
50
|
+
logger.info('Operation succeeded after retry', {
|
|
51
|
+
attempt,
|
|
52
|
+
totalAttempts: attempt,
|
|
53
|
+
totalTimeMs: Date.now() - startTime
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
59
|
+
errors.push(err);
|
|
60
|
+
// Check if we should retry
|
|
61
|
+
const shouldRetry = options.shouldRetry ? options.shouldRetry(err) : isRetryableError(err);
|
|
62
|
+
if (!shouldRetry) {
|
|
63
|
+
logger.warn('Error is not retryable', {
|
|
64
|
+
error: err.message,
|
|
65
|
+
attempt
|
|
66
|
+
});
|
|
67
|
+
throw err;
|
|
68
|
+
}
|
|
69
|
+
// Check if we have attempts remaining
|
|
70
|
+
if (attempt >= opts.maxAttempts) {
|
|
71
|
+
logger.error('Retry attempts exhausted', {
|
|
72
|
+
totalAttempts: attempt,
|
|
73
|
+
errors: errors.map((e)=>e.message),
|
|
74
|
+
totalTimeMs: Date.now() - startTime
|
|
75
|
+
});
|
|
76
|
+
throw createRetryExhaustedError(attempt, err);
|
|
77
|
+
}
|
|
78
|
+
// Calculate delay for next attempt
|
|
79
|
+
const delayMs = calculateDelay(attempt, opts);
|
|
80
|
+
delays.push(delayMs);
|
|
81
|
+
logger.debug('Retrying after delay', {
|
|
82
|
+
attempt,
|
|
83
|
+
delayMs,
|
|
84
|
+
error: err.message
|
|
85
|
+
});
|
|
86
|
+
// Invoke retry callback if provided
|
|
87
|
+
if (options.onRetry) {
|
|
88
|
+
options.onRetry(attempt, err, delayMs);
|
|
89
|
+
}
|
|
90
|
+
// Wait before next attempt
|
|
91
|
+
await sleep(delayMs);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// This should never be reached due to the throw above, but TypeScript needs it
|
|
95
|
+
throw createRetryExhaustedError(attempt, errors[errors.length - 1]);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Calculate delay for retry attempt
|
|
99
|
+
*
|
|
100
|
+
* @param attempt - Current attempt number (1-based)
|
|
101
|
+
* @param options - Retry options
|
|
102
|
+
* @returns Delay in milliseconds
|
|
103
|
+
*/ function calculateDelay(attempt, options) {
|
|
104
|
+
let delay;
|
|
105
|
+
if (options.exponential) {
|
|
106
|
+
// Exponential backoff: baseDelay * 2^(attempt - 1)
|
|
107
|
+
delay = options.baseDelayMs * Math.pow(2, attempt - 1);
|
|
108
|
+
} else {
|
|
109
|
+
// Linear backoff
|
|
110
|
+
delay = options.baseDelayMs * attempt;
|
|
111
|
+
}
|
|
112
|
+
// Cap at max delay
|
|
113
|
+
delay = Math.min(delay, options.maxDelayMs);
|
|
114
|
+
// Add jitter to prevent thundering herd
|
|
115
|
+
if (options.jitter) {
|
|
116
|
+
const jitterFactor = 0.1; // +/- 10%
|
|
117
|
+
const jitterRange = delay * jitterFactor;
|
|
118
|
+
const jitter = (Math.random() * 2 - 1) * jitterRange;
|
|
119
|
+
delay = Math.max(0, delay + jitter);
|
|
120
|
+
}
|
|
121
|
+
return Math.floor(delay);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Sleep for specified duration
|
|
125
|
+
*
|
|
126
|
+
* @param ms - Duration in milliseconds
|
|
127
|
+
* @returns Promise that resolves after duration
|
|
128
|
+
*/ export function sleep(ms) {
|
|
129
|
+
return new Promise((resolve)=>setTimeout(resolve, ms));
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Execute a function with retry and collect statistics
|
|
133
|
+
*
|
|
134
|
+
* @param fn - Async function to execute
|
|
135
|
+
* @param options - Retry options
|
|
136
|
+
* @returns Object with result and statistics
|
|
137
|
+
*/ export async function withRetryStats(fn, options = {}) {
|
|
138
|
+
const opts = {
|
|
139
|
+
...DEFAULT_RETRY_OPTIONS,
|
|
140
|
+
...options
|
|
141
|
+
};
|
|
142
|
+
const errors = [];
|
|
143
|
+
const delays = [];
|
|
144
|
+
const startTime = Date.now();
|
|
145
|
+
let attempt = 0;
|
|
146
|
+
let succeeded = false;
|
|
147
|
+
let result;
|
|
148
|
+
const customOnRetry = (attemptNum, error, delayMs)=>{
|
|
149
|
+
errors.push(error);
|
|
150
|
+
delays.push(delayMs);
|
|
151
|
+
if (options.onRetry) {
|
|
152
|
+
options.onRetry(attemptNum, error, delayMs);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
try {
|
|
156
|
+
result = await withRetry(fn, {
|
|
157
|
+
...options,
|
|
158
|
+
onRetry: customOnRetry
|
|
159
|
+
});
|
|
160
|
+
succeeded = true;
|
|
161
|
+
attempt = errors.length + 1;
|
|
162
|
+
} catch (error) {
|
|
163
|
+
attempt = errors.length + 1;
|
|
164
|
+
throw error;
|
|
165
|
+
} finally{
|
|
166
|
+
const totalTimeMs = Date.now() - startTime;
|
|
167
|
+
if (!succeeded) {
|
|
168
|
+
logger.info('Retry statistics (failed)', {
|
|
169
|
+
totalAttempts: attempt,
|
|
170
|
+
succeeded,
|
|
171
|
+
totalTimeMs,
|
|
172
|
+
errorCount: errors.length
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const stats = {
|
|
177
|
+
totalAttempts: attempt,
|
|
178
|
+
succeeded,
|
|
179
|
+
totalTimeMs: Date.now() - startTime,
|
|
180
|
+
delays,
|
|
181
|
+
errors
|
|
182
|
+
};
|
|
183
|
+
return {
|
|
184
|
+
result: result,
|
|
185
|
+
stats
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Retry a function with linear backoff
|
|
190
|
+
*
|
|
191
|
+
* @param fn - Async function to execute
|
|
192
|
+
* @param maxAttempts - Maximum number of attempts
|
|
193
|
+
* @param delayMs - Delay between attempts in milliseconds
|
|
194
|
+
* @returns Result of the function
|
|
195
|
+
*/ export async function withLinearRetry(fn, maxAttempts = 3, delayMs = 1000) {
|
|
196
|
+
return withRetry(fn, {
|
|
197
|
+
maxAttempts,
|
|
198
|
+
baseDelayMs: delayMs,
|
|
199
|
+
exponential: false,
|
|
200
|
+
jitter: false
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Retry a function with exponential backoff
|
|
205
|
+
*
|
|
206
|
+
* @param fn - Async function to execute
|
|
207
|
+
* @param maxAttempts - Maximum number of attempts
|
|
208
|
+
* @param baseDelayMs - Base delay in milliseconds
|
|
209
|
+
* @returns Result of the function
|
|
210
|
+
*/ export async function withExponentialRetry(fn, maxAttempts = 3, baseDelayMs = 1000) {
|
|
211
|
+
return withRetry(fn, {
|
|
212
|
+
maxAttempts,
|
|
213
|
+
baseDelayMs,
|
|
214
|
+
exponential: true,
|
|
215
|
+
jitter: true
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Create a retryable version of an async function
|
|
220
|
+
*
|
|
221
|
+
* @param fn - Async function to make retryable
|
|
222
|
+
* @param options - Retry options
|
|
223
|
+
* @returns Retryable function
|
|
224
|
+
*/ export function retryable(fn, options = {}) {
|
|
225
|
+
return async (...args)=>{
|
|
226
|
+
return withRetry(()=>fn(...args), options);
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Retry an operation until a condition is met
|
|
231
|
+
*
|
|
232
|
+
* @param fn - Async function to execute
|
|
233
|
+
* @param condition - Condition function (returns true to stop retrying)
|
|
234
|
+
* @param options - Retry options
|
|
235
|
+
* @returns Result when condition is met
|
|
236
|
+
* @throws RetryExhaustedError if max attempts reached
|
|
237
|
+
*/ export async function retryUntil(fn, condition, options = {}) {
|
|
238
|
+
const opts = {
|
|
239
|
+
...DEFAULT_RETRY_OPTIONS,
|
|
240
|
+
...options
|
|
241
|
+
};
|
|
242
|
+
let attempt = 0;
|
|
243
|
+
while(attempt < opts.maxAttempts){
|
|
244
|
+
attempt++;
|
|
245
|
+
const result = await fn();
|
|
246
|
+
if (condition(result)) {
|
|
247
|
+
return result;
|
|
248
|
+
}
|
|
249
|
+
if (attempt >= opts.maxAttempts) {
|
|
250
|
+
throw createRetryExhaustedError(attempt);
|
|
251
|
+
}
|
|
252
|
+
const delayMs = calculateDelay(attempt, opts);
|
|
253
|
+
logger.debug('Condition not met, retrying', {
|
|
254
|
+
attempt,
|
|
255
|
+
delayMs
|
|
256
|
+
});
|
|
257
|
+
await sleep(delayMs);
|
|
258
|
+
}
|
|
259
|
+
throw createRetryExhaustedError(attempt);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/retry.ts"],"sourcesContent":["/**\r\n * Retry and Backoff Utilities\r\n *\r\n * Provides retry logic with exponential backoff for transient failures.\r\n * Part of Task 0.5: Implementation Tooling & Utilities (Foundation)\r\n *\r\n * Usage:\r\n * const result = await withRetry(\r\n * async () => fetchData(),\r\n * { maxAttempts: 3, baseDelayMs: 1000, exponential: true }\r\n * );\r\n */\r\n\r\nimport { createRetryExhaustedError, isRetryableError } from './errors.js';\r\nimport { createLogger } from './logging.js';\r\n\r\nconst logger = createLogger('retry-utility');\r\n\r\n/**\r\n * Retry options\r\n */\r\nexport interface RetryOptions {\r\n /** Maximum number of retry attempts (default: 3) */\r\n maxAttempts?: number;\r\n /** Base delay in milliseconds (default: 1000) */\r\n baseDelayMs?: number;\r\n /** Maximum delay in milliseconds (default: 30000) */\r\n maxDelayMs?: number;\r\n /** Use exponential backoff (default: true) */\r\n exponential?: boolean;\r\n /** Custom function to determine if error is retryable (optional) */\r\n shouldRetry?: (error: Error) => boolean;\r\n /** Callback invoked before each retry attempt (optional) */\r\n onRetry?: (attempt: number, error: Error, delayMs: number) => void;\r\n /** Add random jitter to delay (default: true) */\r\n jitter?: boolean;\r\n}\r\n\r\n/**\r\n * Retry statistics\r\n */\r\nexport interface RetryStats {\r\n /** Total attempts made */\r\n totalAttempts: number;\r\n /** Whether operation succeeded */\r\n succeeded: boolean;\r\n /** Total time spent (including delays) in milliseconds */\r\n totalTimeMs: number;\r\n /** Delays between attempts */\r\n delays: number[];\r\n /** Errors encountered */\r\n errors: Error[];\r\n}\r\n\r\n/**\r\n * Default retry options\r\n */\r\nconst DEFAULT_RETRY_OPTIONS: Required<Omit<RetryOptions, 'shouldRetry' | 'onRetry'>> = {\r\n maxAttempts: 3,\r\n baseDelayMs: 1000,\r\n maxDelayMs: 30000,\r\n exponential: true,\r\n jitter: true,\r\n};\r\n\r\n/**\r\n * Execute a function with retry logic\r\n *\r\n * @param fn - Async function to execute\r\n * @param options - Retry options\r\n * @returns Result of the function\r\n * @throws RetryExhaustedError if all attempts fail\r\n */\r\nexport async function withRetry<T>(\r\n fn: () => Promise<T>,\r\n options: RetryOptions = {}\r\n): Promise<T> {\r\n const opts = { ...DEFAULT_RETRY_OPTIONS, ...options };\r\n const errors: Error[] = [];\r\n const delays: number[] = [];\r\n const startTime = Date.now();\r\n\r\n let attempt = 0;\r\n\r\n while (attempt < opts.maxAttempts) {\r\n attempt++;\r\n\r\n try {\r\n logger.debug('Retry attempt', { attempt, maxAttempts: opts.maxAttempts });\r\n const result = await fn();\r\n\r\n // Success!\r\n if (attempt > 1) {\r\n logger.info('Operation succeeded after retry', {\r\n attempt,\r\n totalAttempts: attempt,\r\n totalTimeMs: Date.now() - startTime,\r\n });\r\n }\r\n\r\n return result;\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error));\r\n errors.push(err);\r\n\r\n // Check if we should retry\r\n const shouldRetry = options.shouldRetry\r\n ? options.shouldRetry(err)\r\n : isRetryableError(err);\r\n\r\n if (!shouldRetry) {\r\n logger.warn('Error is not retryable', { error: err.message, attempt });\r\n throw err;\r\n }\r\n\r\n // Check if we have attempts remaining\r\n if (attempt >= opts.maxAttempts) {\r\n logger.error('Retry attempts exhausted', {\r\n totalAttempts: attempt,\r\n errors: errors.map((e) => e.message),\r\n totalTimeMs: Date.now() - startTime,\r\n });\r\n throw createRetryExhaustedError(attempt, err);\r\n }\r\n\r\n // Calculate delay for next attempt\r\n const delayMs = calculateDelay(attempt, opts);\r\n delays.push(delayMs);\r\n\r\n logger.debug('Retrying after delay', {\r\n attempt,\r\n delayMs,\r\n error: err.message,\r\n });\r\n\r\n // Invoke retry callback if provided\r\n if (options.onRetry) {\r\n options.onRetry(attempt, err, delayMs);\r\n }\r\n\r\n // Wait before next attempt\r\n await sleep(delayMs);\r\n }\r\n }\r\n\r\n // This should never be reached due to the throw above, but TypeScript needs it\r\n throw createRetryExhaustedError(attempt, errors[errors.length - 1]);\r\n}\r\n\r\n/**\r\n * Calculate delay for retry attempt\r\n *\r\n * @param attempt - Current attempt number (1-based)\r\n * @param options - Retry options\r\n * @returns Delay in milliseconds\r\n */\r\nfunction calculateDelay(attempt: number, options: Required<Omit<RetryOptions, 'shouldRetry' | 'onRetry'>>): number {\r\n let delay: number;\r\n\r\n if (options.exponential) {\r\n // Exponential backoff: baseDelay * 2^(attempt - 1)\r\n delay = options.baseDelayMs * Math.pow(2, attempt - 1);\r\n } else {\r\n // Linear backoff\r\n delay = options.baseDelayMs * attempt;\r\n }\r\n\r\n // Cap at max delay\r\n delay = Math.min(delay, options.maxDelayMs);\r\n\r\n // Add jitter to prevent thundering herd\r\n if (options.jitter) {\r\n const jitterFactor = 0.1; // +/- 10%\r\n const jitterRange = delay * jitterFactor;\r\n const jitter = (Math.random() * 2 - 1) * jitterRange;\r\n delay = Math.max(0, delay + jitter);\r\n }\r\n\r\n return Math.floor(delay);\r\n}\r\n\r\n/**\r\n * Sleep for specified duration\r\n *\r\n * @param ms - Duration in milliseconds\r\n * @returns Promise that resolves after duration\r\n */\r\nexport function sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\n/**\r\n * Execute a function with retry and collect statistics\r\n *\r\n * @param fn - Async function to execute\r\n * @param options - Retry options\r\n * @returns Object with result and statistics\r\n */\r\nexport async function withRetryStats<T>(\r\n fn: () => Promise<T>,\r\n options: RetryOptions = {}\r\n): Promise<{ result: T; stats: RetryStats }> {\r\n const opts = { ...DEFAULT_RETRY_OPTIONS, ...options };\r\n const errors: Error[] = [];\r\n const delays: number[] = [];\r\n const startTime = Date.now();\r\n\r\n let attempt = 0;\r\n let succeeded = false;\r\n let result: T | undefined;\r\n\r\n const customOnRetry = (attemptNum: number, error: Error, delayMs: number) => {\r\n errors.push(error);\r\n delays.push(delayMs);\r\n if (options.onRetry) {\r\n options.onRetry(attemptNum, error, delayMs);\r\n }\r\n };\r\n\r\n try {\r\n result = await withRetry(fn, { ...options, onRetry: customOnRetry });\r\n succeeded = true;\r\n attempt = errors.length + 1;\r\n } catch (error) {\r\n attempt = errors.length + 1;\r\n throw error;\r\n } finally {\r\n const totalTimeMs = Date.now() - startTime;\r\n\r\n if (!succeeded) {\r\n logger.info('Retry statistics (failed)', {\r\n totalAttempts: attempt,\r\n succeeded,\r\n totalTimeMs,\r\n errorCount: errors.length,\r\n });\r\n }\r\n }\r\n\r\n const stats: RetryStats = {\r\n totalAttempts: attempt,\r\n succeeded,\r\n totalTimeMs: Date.now() - startTime,\r\n delays,\r\n errors,\r\n };\r\n\r\n return { result: result as T, stats };\r\n}\r\n\r\n/**\r\n * Retry a function with linear backoff\r\n *\r\n * @param fn - Async function to execute\r\n * @param maxAttempts - Maximum number of attempts\r\n * @param delayMs - Delay between attempts in milliseconds\r\n * @returns Result of the function\r\n */\r\nexport async function withLinearRetry<T>(\r\n fn: () => Promise<T>,\r\n maxAttempts: number = 3,\r\n delayMs: number = 1000\r\n): Promise<T> {\r\n return withRetry(fn, {\r\n maxAttempts,\r\n baseDelayMs: delayMs,\r\n exponential: false,\r\n jitter: false,\r\n });\r\n}\r\n\r\n/**\r\n * Retry a function with exponential backoff\r\n *\r\n * @param fn - Async function to execute\r\n * @param maxAttempts - Maximum number of attempts\r\n * @param baseDelayMs - Base delay in milliseconds\r\n * @returns Result of the function\r\n */\r\nexport async function withExponentialRetry<T>(\r\n fn: () => Promise<T>,\r\n maxAttempts: number = 3,\r\n baseDelayMs: number = 1000\r\n): Promise<T> {\r\n return withRetry(fn, {\r\n maxAttempts,\r\n baseDelayMs,\r\n exponential: true,\r\n jitter: true,\r\n });\r\n}\r\n\r\n/**\r\n * Create a retryable version of an async function\r\n *\r\n * @param fn - Async function to make retryable\r\n * @param options - Retry options\r\n * @returns Retryable function\r\n */\r\nexport function retryable<TArgs extends any[], TResult>(\r\n fn: (...args: TArgs) => Promise<TResult>,\r\n options: RetryOptions = {}\r\n): (...args: TArgs) => Promise<TResult> {\r\n return async (...args: TArgs): Promise<TResult> => {\r\n return withRetry(() => fn(...args), options);\r\n };\r\n}\r\n\r\n/**\r\n * Retry an operation until a condition is met\r\n *\r\n * @param fn - Async function to execute\r\n * @param condition - Condition function (returns true to stop retrying)\r\n * @param options - Retry options\r\n * @returns Result when condition is met\r\n * @throws RetryExhaustedError if max attempts reached\r\n */\r\nexport async function retryUntil<T>(\r\n fn: () => Promise<T>,\r\n condition: (result: T) => boolean,\r\n options: RetryOptions = {}\r\n): Promise<T> {\r\n const opts = { ...DEFAULT_RETRY_OPTIONS, ...options };\r\n let attempt = 0;\r\n\r\n while (attempt < opts.maxAttempts) {\r\n attempt++;\r\n\r\n const result = await fn();\r\n\r\n if (condition(result)) {\r\n return result;\r\n }\r\n\r\n if (attempt >= opts.maxAttempts) {\r\n throw createRetryExhaustedError(attempt);\r\n }\r\n\r\n const delayMs = calculateDelay(attempt, opts);\r\n logger.debug('Condition not met, retrying', { attempt, delayMs });\r\n await sleep(delayMs);\r\n }\r\n\r\n throw createRetryExhaustedError(attempt);\r\n}\r\n"],"names":["createRetryExhaustedError","isRetryableError","createLogger","logger","DEFAULT_RETRY_OPTIONS","maxAttempts","baseDelayMs","maxDelayMs","exponential","jitter","withRetry","fn","options","opts","errors","delays","startTime","Date","now","attempt","debug","result","info","totalAttempts","totalTimeMs","error","err","Error","String","push","shouldRetry","warn","message","map","e","delayMs","calculateDelay","onRetry","sleep","length","delay","Math","pow","min","jitterFactor","jitterRange","random","max","floor","ms","Promise","resolve","setTimeout","withRetryStats","succeeded","customOnRetry","attemptNum","errorCount","stats","withLinearRetry","withExponentialRetry","retryable","args","retryUntil","condition"],"mappings":"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"}
|