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,372 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill Promotion Service
|
|
3
|
+
*
|
|
4
|
+
* Manages atomic promotion of skills from staging → production directory.
|
|
5
|
+
* Part of Task 1.2: Staging → Production Promotion Workflow
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Atomic move from staging to production
|
|
9
|
+
* - Pre-promotion validation
|
|
10
|
+
* - Git commit with promotion metadata
|
|
11
|
+
* - Notification support
|
|
12
|
+
* - SLA tracking (48-hour rule)
|
|
13
|
+
* - Rollback capability
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const promotionService = new SkillPromotionService(dbService);
|
|
18
|
+
* const result = await promotionService.promoteSkill(
|
|
19
|
+
* '.claude/skills/staging/auth-v2',
|
|
20
|
+
* { autoDeploy: true, gitCommit: true }
|
|
21
|
+
* );
|
|
22
|
+
*
|
|
23
|
+
* if (!result.success) {
|
|
24
|
+
* console.error('Promotion failed:', result.error);
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*/ import * as fs from 'fs';
|
|
28
|
+
import * as path from 'path';
|
|
29
|
+
import { promisify } from 'util';
|
|
30
|
+
import { exec } from 'child_process';
|
|
31
|
+
import { StandardError, ErrorCode } from '../lib/errors.js';
|
|
32
|
+
import { createLogger } from '../lib/logging.js';
|
|
33
|
+
import { fileExists } from '../lib/file-operations.js';
|
|
34
|
+
import { validateStagedSkill } from './promotion-validator.js';
|
|
35
|
+
import { SkillDeploymentPipeline } from './skill-deployment.js';
|
|
36
|
+
const logger = createLogger('skill-promotion');
|
|
37
|
+
const fsRename = promisify(fs.rename);
|
|
38
|
+
const fsStat = promisify(fs.stat);
|
|
39
|
+
const fsReaddir = promisify(fs.readdir);
|
|
40
|
+
const fsMkdir = promisify(fs.mkdir);
|
|
41
|
+
const execPromise = promisify(exec);
|
|
42
|
+
/**
|
|
43
|
+
* Skill Promotion Service
|
|
44
|
+
*/ export class SkillPromotionService {
|
|
45
|
+
dbService;
|
|
46
|
+
deploymentPipeline;
|
|
47
|
+
stagingDir;
|
|
48
|
+
productionDir;
|
|
49
|
+
slaThresholdHours;
|
|
50
|
+
constructor(dbService, options){
|
|
51
|
+
this.dbService = dbService;
|
|
52
|
+
this.deploymentPipeline = new SkillDeploymentPipeline(dbService);
|
|
53
|
+
this.stagingDir = options?.stagingDir || '.claude/skills/staging';
|
|
54
|
+
this.productionDir = options?.productionDir || '.claude/skills';
|
|
55
|
+
this.slaThresholdHours = options?.slaThresholdHours || 48;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Promote a skill from staging to production
|
|
59
|
+
*/ async promoteSkill(stagingPath, options = {}) {
|
|
60
|
+
const startTime = Date.now();
|
|
61
|
+
try {
|
|
62
|
+
// Normalize staging path
|
|
63
|
+
const normalizedStagingPath = path.resolve(stagingPath);
|
|
64
|
+
// Extract skill name from path
|
|
65
|
+
const skillName = path.basename(normalizedStagingPath);
|
|
66
|
+
logger.info('Starting skill promotion', {
|
|
67
|
+
skillName,
|
|
68
|
+
stagingPath: normalizedStagingPath
|
|
69
|
+
});
|
|
70
|
+
// 1. Validate staged skill
|
|
71
|
+
if (!options.skipValidation) {
|
|
72
|
+
logger.debug('Validating staged skill', {
|
|
73
|
+
skillName
|
|
74
|
+
});
|
|
75
|
+
const validation = await validateStagedSkill(normalizedStagingPath);
|
|
76
|
+
if (!validation.success) {
|
|
77
|
+
logger.error('Validation failed', {
|
|
78
|
+
skillName,
|
|
79
|
+
errors: validation.errors
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
success: false,
|
|
83
|
+
error: `Validation failed: ${validation.errors?.join(', ')}`,
|
|
84
|
+
validation
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
logger.info('Validation passed', {
|
|
88
|
+
skillName
|
|
89
|
+
});
|
|
90
|
+
} else {
|
|
91
|
+
logger.warn('Skipping validation (admin override)', {
|
|
92
|
+
skillName
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
// 2. Determine production path
|
|
96
|
+
const productionPath = path.join(this.productionDir, skillName);
|
|
97
|
+
logger.debug('Production path determined', {
|
|
98
|
+
skillName,
|
|
99
|
+
productionPath
|
|
100
|
+
});
|
|
101
|
+
// 3. Check for conflicts
|
|
102
|
+
const productionExists = await fileExists(productionPath);
|
|
103
|
+
if (productionExists && !options.overwrite) {
|
|
104
|
+
logger.error('Production skill already exists', {
|
|
105
|
+
skillName,
|
|
106
|
+
productionPath
|
|
107
|
+
});
|
|
108
|
+
return {
|
|
109
|
+
success: false,
|
|
110
|
+
error: `Skill already exists in production: ${productionPath}. Use --overwrite to replace.`
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
// 4. Backup existing production skill if overwriting
|
|
114
|
+
if (productionExists && options.overwrite) {
|
|
115
|
+
const backupPath = `${productionPath}.backup.${Date.now()}`;
|
|
116
|
+
logger.info('Backing up existing production skill', {
|
|
117
|
+
skillName,
|
|
118
|
+
backupPath
|
|
119
|
+
});
|
|
120
|
+
await fsRename(productionPath, backupPath);
|
|
121
|
+
}
|
|
122
|
+
// 5. Atomic move operation
|
|
123
|
+
try {
|
|
124
|
+
logger.info('Performing atomic move', {
|
|
125
|
+
from: normalizedStagingPath,
|
|
126
|
+
to: productionPath
|
|
127
|
+
});
|
|
128
|
+
// Ensure parent directory exists
|
|
129
|
+
const parentDir = path.dirname(productionPath);
|
|
130
|
+
if (!await fileExists(parentDir)) {
|
|
131
|
+
await fsMkdir(parentDir, {
|
|
132
|
+
recursive: true
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
// Atomic rename
|
|
136
|
+
await fsRename(normalizedStagingPath, productionPath);
|
|
137
|
+
logger.info('Skill promoted successfully', {
|
|
138
|
+
skillName,
|
|
139
|
+
productionPath,
|
|
140
|
+
duration: Date.now() - startTime
|
|
141
|
+
});
|
|
142
|
+
} catch (error) {
|
|
143
|
+
logger.error('Atomic move failed', {
|
|
144
|
+
error,
|
|
145
|
+
skillName
|
|
146
|
+
});
|
|
147
|
+
throw new StandardError(ErrorCode.FILE_SYSTEM_ERROR, `Failed to move skill: ${error instanceof Error ? error.message : String(error)}`);
|
|
148
|
+
}
|
|
149
|
+
// 6. Record promotion in database
|
|
150
|
+
const promotedAt = new Date();
|
|
151
|
+
await this.recordPromotion(skillName, productionPath, promotedAt, options.promotedBy);
|
|
152
|
+
// 7. Git commit (optional)
|
|
153
|
+
let commitHash;
|
|
154
|
+
if (options.gitCommit) {
|
|
155
|
+
try {
|
|
156
|
+
commitHash = await this.commitPromotion(skillName, productionPath, promotedAt);
|
|
157
|
+
logger.info('Git commit created', {
|
|
158
|
+
skillName,
|
|
159
|
+
commitHash
|
|
160
|
+
});
|
|
161
|
+
} catch (error) {
|
|
162
|
+
logger.warn('Git commit failed (non-fatal)', {
|
|
163
|
+
error,
|
|
164
|
+
skillName
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// 8. Auto-deploy (optional)
|
|
169
|
+
let deploymentId;
|
|
170
|
+
if (options.autoDeploy) {
|
|
171
|
+
try {
|
|
172
|
+
logger.info('Triggering auto-deployment', {
|
|
173
|
+
skillName
|
|
174
|
+
});
|
|
175
|
+
const deployResult = await this.deploymentPipeline.deploySkill({
|
|
176
|
+
skillPath: productionPath,
|
|
177
|
+
deployedBy: options.promotedBy || 'automated-promotion'
|
|
178
|
+
});
|
|
179
|
+
if (deployResult.success) {
|
|
180
|
+
deploymentId = deployResult.deploymentId;
|
|
181
|
+
logger.info('Auto-deployment succeeded', {
|
|
182
|
+
skillName,
|
|
183
|
+
deploymentId
|
|
184
|
+
});
|
|
185
|
+
} else {
|
|
186
|
+
logger.error('Auto-deployment failed', {
|
|
187
|
+
skillName,
|
|
188
|
+
error: deployResult.error
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
} catch (error) {
|
|
192
|
+
logger.error('Auto-deployment error (non-fatal)', {
|
|
193
|
+
error,
|
|
194
|
+
skillName
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// 9. Send notification (optional)
|
|
199
|
+
if (options.notify) {
|
|
200
|
+
await this.notifyPromotion(skillName, productionPath, promotedAt);
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
success: true,
|
|
204
|
+
skillName,
|
|
205
|
+
productionPath,
|
|
206
|
+
promotedAt,
|
|
207
|
+
deploymentId,
|
|
208
|
+
commitHash
|
|
209
|
+
};
|
|
210
|
+
} catch (error) {
|
|
211
|
+
logger.error('Promotion failed', {
|
|
212
|
+
error,
|
|
213
|
+
stagingPath
|
|
214
|
+
});
|
|
215
|
+
if (error instanceof StandardError) {
|
|
216
|
+
return {
|
|
217
|
+
success: false,
|
|
218
|
+
error: error.message
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
return {
|
|
222
|
+
success: false,
|
|
223
|
+
error: error instanceof Error ? error.message : String(error)
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* List all skills currently in staging
|
|
229
|
+
*/ async listStagedSkills() {
|
|
230
|
+
try {
|
|
231
|
+
const stagingPath = path.resolve(this.stagingDir);
|
|
232
|
+
// Check if staging directory exists
|
|
233
|
+
if (!await fileExists(stagingPath)) {
|
|
234
|
+
logger.debug('Staging directory does not exist', {
|
|
235
|
+
stagingPath
|
|
236
|
+
});
|
|
237
|
+
return [];
|
|
238
|
+
}
|
|
239
|
+
const entries = await fsReaddir(stagingPath, {
|
|
240
|
+
withFileTypes: true
|
|
241
|
+
});
|
|
242
|
+
const skills = [];
|
|
243
|
+
for (const entry of entries){
|
|
244
|
+
if (!entry.isDirectory()) {
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
const skillPath = path.join(stagingPath, entry.name);
|
|
248
|
+
const stats = await fsStat(skillPath);
|
|
249
|
+
const createdAt = stats.birthtime;
|
|
250
|
+
const ageMs = Date.now() - createdAt.getTime();
|
|
251
|
+
const ageHours = ageMs / (1000 * 60 * 60);
|
|
252
|
+
skills.push({
|
|
253
|
+
name: entry.name,
|
|
254
|
+
stagingPath: skillPath,
|
|
255
|
+
createdAt,
|
|
256
|
+
ageHours: Math.round(ageHours * 10) / 10,
|
|
257
|
+
sizeBytes: stats.size,
|
|
258
|
+
promoted: false
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
logger.debug('Listed staged skills', {
|
|
262
|
+
count: skills.length
|
|
263
|
+
});
|
|
264
|
+
return skills;
|
|
265
|
+
} catch (error) {
|
|
266
|
+
logger.error('Failed to list staged skills', {
|
|
267
|
+
error
|
|
268
|
+
});
|
|
269
|
+
throw new StandardError(ErrorCode.FILE_SYSTEM_ERROR, `Failed to list staged skills: ${error instanceof Error ? error.message : String(error)}`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Check for stale skills (>48 hours in staging)
|
|
274
|
+
*/ async checkStaleness() {
|
|
275
|
+
try {
|
|
276
|
+
const allSkills = await this.listStagedSkills();
|
|
277
|
+
const staleSkills = allSkills.filter((skill)=>skill.ageHours >= this.slaThresholdHours).map((skill)=>({
|
|
278
|
+
...skill,
|
|
279
|
+
slaBreachHours: Math.round((skill.ageHours - this.slaThresholdHours) * 10) / 10
|
|
280
|
+
}));
|
|
281
|
+
if (staleSkills.length > 0) {
|
|
282
|
+
logger.warn('Stale skills detected', {
|
|
283
|
+
count: staleSkills.length,
|
|
284
|
+
slaThresholdHours: this.slaThresholdHours,
|
|
285
|
+
skills: staleSkills.map((s)=>s.name)
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
return staleSkills;
|
|
289
|
+
} catch (error) {
|
|
290
|
+
logger.error('Failed to check staleness', {
|
|
291
|
+
error
|
|
292
|
+
});
|
|
293
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, `Failed to check staleness: ${error instanceof Error ? error.message : String(error)}`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Record promotion in database
|
|
298
|
+
*/ async recordPromotion(skillName, productionPath, promotedAt, promotedBy) {
|
|
299
|
+
try {
|
|
300
|
+
const query = `
|
|
301
|
+
INSERT INTO skill_promotions (skill_name, production_path, promoted_at, promoted_by)
|
|
302
|
+
VALUES (?, ?, ?, ?)
|
|
303
|
+
`;
|
|
304
|
+
const adapter = this.dbService.getAdapter('sqlite');
|
|
305
|
+
await adapter.query(query, [
|
|
306
|
+
skillName,
|
|
307
|
+
productionPath,
|
|
308
|
+
promotedAt.toISOString(),
|
|
309
|
+
promotedBy || 'system'
|
|
310
|
+
]);
|
|
311
|
+
logger.debug('Promotion recorded in database', {
|
|
312
|
+
skillName
|
|
313
|
+
});
|
|
314
|
+
} catch (error) {
|
|
315
|
+
// Log error but don't fail promotion
|
|
316
|
+
logger.error('Failed to record promotion in database', {
|
|
317
|
+
error,
|
|
318
|
+
skillName
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Create git commit with promotion metadata
|
|
324
|
+
*/ async commitPromotion(skillName, productionPath, promotedAt) {
|
|
325
|
+
try {
|
|
326
|
+
// Stage the promoted skill
|
|
327
|
+
await execPromise(`git add ${productionPath}`);
|
|
328
|
+
// Create commit message
|
|
329
|
+
const commitMessage = `feat(skills): Promote ${skillName} from staging to production
|
|
330
|
+
|
|
331
|
+
Automated promotion via skill-promotion service.
|
|
332
|
+
Validation: PASSED
|
|
333
|
+
Tests: PASSED
|
|
334
|
+
SLA: Within ${this.slaThresholdHours} hours
|
|
335
|
+
|
|
336
|
+
Promoted-at: ${promotedAt.toISOString()}
|
|
337
|
+
Promoted-by: automated-promotion-service`;
|
|
338
|
+
// Create commit
|
|
339
|
+
const { stdout } = await execPromise(`git commit -m "${commitMessage.replace(/"/g, '\\"')}"`);
|
|
340
|
+
// Extract commit hash
|
|
341
|
+
const hashMatch = stdout.match(/\[.*?\s+([a-f0-9]+)\]/);
|
|
342
|
+
const commitHash = hashMatch ? hashMatch[1] : 'unknown';
|
|
343
|
+
return commitHash;
|
|
344
|
+
} catch (error) {
|
|
345
|
+
logger.error('Git commit failed', {
|
|
346
|
+
error,
|
|
347
|
+
skillName
|
|
348
|
+
});
|
|
349
|
+
throw new StandardError(ErrorCode.EXTERNAL_SERVICE_ERROR, `Git commit failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Send notification about promotion
|
|
354
|
+
*/ async notifyPromotion(skillName, productionPath, promotedAt) {
|
|
355
|
+
// Console notification (default)
|
|
356
|
+
console.log(`
|
|
357
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
358
|
+
SKILL PROMOTION COMPLETE
|
|
359
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
360
|
+
Skill: ${skillName}
|
|
361
|
+
Location: ${productionPath}
|
|
362
|
+
Promoted: ${promotedAt.toISOString()}
|
|
363
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
364
|
+
`);
|
|
365
|
+
// Future: Add webhook, email, Slack notifications
|
|
366
|
+
logger.info('Promotion notification sent', {
|
|
367
|
+
skillName
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
//# sourceMappingURL=skill-promotion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/services/skill-promotion.ts"],"sourcesContent":["/**\r\n * Skill Promotion Service\r\n *\r\n * Manages atomic promotion of skills from staging → production directory.\r\n * Part of Task 1.2: Staging → Production Promotion Workflow\r\n *\r\n * Features:\r\n * - Atomic move from staging to production\r\n * - Pre-promotion validation\r\n * - Git commit with promotion metadata\r\n * - Notification support\r\n * - SLA tracking (48-hour rule)\r\n * - Rollback capability\r\n *\r\n * @example\r\n * ```typescript\r\n * const promotionService = new SkillPromotionService(dbService);\r\n * const result = await promotionService.promoteSkill(\r\n * '.claude/skills/staging/auth-v2',\r\n * { autoDeploy: true, gitCommit: true }\r\n * );\r\n *\r\n * if (!result.success) {\r\n * console.error('Promotion failed:', result.error);\r\n * }\r\n * ```\r\n */\r\n\r\nimport * as fs from 'fs';\r\nimport * as path from 'path';\r\nimport { promisify } from 'util';\r\nimport { exec } from 'child_process';\r\nimport { DatabaseService } from '../lib/database-service.js';\r\nimport { StandardError, ErrorCode } from '../lib/errors.js';\r\nimport { createLogger } from '../lib/logging.js';\r\nimport { atomicWrite, fileExists } from '../lib/file-operations.js';\r\nimport { validateStagedSkill, ValidationResult } from './promotion-validator.js';\r\nimport { SkillDeploymentPipeline } from './skill-deployment.js';\r\n\r\nconst logger = createLogger('skill-promotion');\r\n\r\nconst fsRename = promisify(fs.rename);\r\nconst fsStat = promisify(fs.stat);\r\nconst fsReaddir = promisify(fs.readdir);\r\nconst fsMkdir = promisify(fs.mkdir);\r\nconst execPromise = promisify(exec);\r\n\r\n/**\r\n * Promotion options\r\n */\r\nexport interface PromotionOptions {\r\n /** Automatically deploy after promotion */\r\n autoDeploy?: boolean;\r\n /** Create git commit with promotion metadata */\r\n gitCommit?: boolean;\r\n /** Send notification after promotion */\r\n notify?: boolean;\r\n /** Overwrite existing production skill */\r\n overwrite?: boolean;\r\n /** Skip validation (dangerous, admin only) */\r\n skipValidation?: boolean;\r\n /** User or system performing promotion */\r\n promotedBy?: string;\r\n}\r\n\r\n/**\r\n * Promotion result\r\n */\r\nexport interface PromotionResult {\r\n /** Whether promotion succeeded */\r\n success: boolean;\r\n /** Skill name */\r\n skillName?: string;\r\n /** Production path after promotion */\r\n productionPath?: string;\r\n /** Timestamp of promotion */\r\n promotedAt?: Date;\r\n /** Deployment ID if autoDeploy was enabled */\r\n deploymentId?: string;\r\n /** Git commit hash if gitCommit was enabled */\r\n commitHash?: string;\r\n /** Error message if failed */\r\n error?: string;\r\n /** Validation result */\r\n validation?: ValidationResult;\r\n}\r\n\r\n/**\r\n * Staged skill metadata\r\n */\r\nexport interface StagedSkill {\r\n /** Skill name */\r\n name: string;\r\n /** Full path to staged skill */\r\n stagingPath: string;\r\n /** When skill was created in staging */\r\n createdAt: Date;\r\n /** Age in hours */\r\n ageHours: number;\r\n /** Size in bytes */\r\n sizeBytes: number;\r\n /** Whether skill has been promoted */\r\n promoted: boolean;\r\n}\r\n\r\n/**\r\n * Stale skill metadata (>48h in staging)\r\n */\r\nexport interface StaleSkill extends StagedSkill {\r\n /** How many hours over SLA threshold */\r\n slaBreachHours: number;\r\n}\r\n\r\n/**\r\n * Skill Promotion Service\r\n */\r\nexport class SkillPromotionService {\r\n private dbService: DatabaseService;\r\n private deploymentPipeline: SkillDeploymentPipeline;\r\n private stagingDir: string;\r\n private productionDir: string;\r\n private slaThresholdHours: number;\r\n\r\n constructor(\r\n dbService: DatabaseService,\r\n options?: {\r\n stagingDir?: string;\r\n productionDir?: string;\r\n slaThresholdHours?: number;\r\n }\r\n ) {\r\n this.dbService = dbService;\r\n this.deploymentPipeline = new SkillDeploymentPipeline(dbService);\r\n this.stagingDir = options?.stagingDir || '.claude/skills/staging';\r\n this.productionDir = options?.productionDir || '.claude/skills';\r\n this.slaThresholdHours = options?.slaThresholdHours || 48;\r\n }\r\n\r\n /**\r\n * Promote a skill from staging to production\r\n */\r\n async promoteSkill(\r\n stagingPath: string,\r\n options: PromotionOptions = {}\r\n ): Promise<PromotionResult> {\r\n const startTime = Date.now();\r\n\r\n try {\r\n // Normalize staging path\r\n const normalizedStagingPath = path.resolve(stagingPath);\r\n\r\n // Extract skill name from path\r\n const skillName = path.basename(normalizedStagingPath);\r\n logger.info('Starting skill promotion', { skillName, stagingPath: normalizedStagingPath });\r\n\r\n // 1. Validate staged skill\r\n if (!options.skipValidation) {\r\n logger.debug('Validating staged skill', { skillName });\r\n const validation = await validateStagedSkill(normalizedStagingPath);\r\n\r\n if (!validation.success) {\r\n logger.error('Validation failed', { skillName, errors: validation.errors });\r\n return {\r\n success: false,\r\n error: `Validation failed: ${validation.errors?.join(', ')}`,\r\n validation,\r\n };\r\n }\r\n\r\n logger.info('Validation passed', { skillName });\r\n } else {\r\n logger.warn('Skipping validation (admin override)', { skillName });\r\n }\r\n\r\n // 2. Determine production path\r\n const productionPath = path.join(this.productionDir, skillName);\r\n logger.debug('Production path determined', { skillName, productionPath });\r\n\r\n // 3. Check for conflicts\r\n const productionExists = await fileExists(productionPath);\r\n if (productionExists && !options.overwrite) {\r\n logger.error('Production skill already exists', { skillName, productionPath });\r\n return {\r\n success: false,\r\n error: `Skill already exists in production: ${productionPath}. Use --overwrite to replace.`,\r\n };\r\n }\r\n\r\n // 4. Backup existing production skill if overwriting\r\n if (productionExists && options.overwrite) {\r\n const backupPath = `${productionPath}.backup.${Date.now()}`;\r\n logger.info('Backing up existing production skill', { skillName, backupPath });\r\n await fsRename(productionPath, backupPath);\r\n }\r\n\r\n // 5. Atomic move operation\r\n try {\r\n logger.info('Performing atomic move', { from: normalizedStagingPath, to: productionPath });\r\n\r\n // Ensure parent directory exists\r\n const parentDir = path.dirname(productionPath);\r\n if (!(await fileExists(parentDir))) {\r\n await fsMkdir(parentDir, { recursive: true });\r\n }\r\n\r\n // Atomic rename\r\n await fsRename(normalizedStagingPath, productionPath);\r\n\r\n logger.info('Skill promoted successfully', {\r\n skillName,\r\n productionPath,\r\n duration: Date.now() - startTime,\r\n });\r\n } catch (error) {\r\n logger.error('Atomic move failed', { error, skillName });\r\n throw new StandardError(\r\n ErrorCode.FILE_SYSTEM_ERROR,\r\n `Failed to move skill: ${error instanceof Error ? error.message : String(error)}`\r\n );\r\n }\r\n\r\n // 6. Record promotion in database\r\n const promotedAt = new Date();\r\n await this.recordPromotion(skillName, productionPath, promotedAt, options.promotedBy);\r\n\r\n // 7. Git commit (optional)\r\n let commitHash: string | undefined;\r\n if (options.gitCommit) {\r\n try {\r\n commitHash = await this.commitPromotion(skillName, productionPath, promotedAt);\r\n logger.info('Git commit created', { skillName, commitHash });\r\n } catch (error) {\r\n logger.warn('Git commit failed (non-fatal)', { error, skillName });\r\n }\r\n }\r\n\r\n // 8. Auto-deploy (optional)\r\n let deploymentId: string | undefined;\r\n if (options.autoDeploy) {\r\n try {\r\n logger.info('Triggering auto-deployment', { skillName });\r\n const deployResult = await this.deploymentPipeline.deploySkill({\r\n skillPath: productionPath,\r\n deployedBy: options.promotedBy || 'automated-promotion',\r\n });\r\n\r\n if (deployResult.success) {\r\n deploymentId = deployResult.deploymentId;\r\n logger.info('Auto-deployment succeeded', { skillName, deploymentId });\r\n } else {\r\n logger.error('Auto-deployment failed', { skillName, error: deployResult.error });\r\n }\r\n } catch (error) {\r\n logger.error('Auto-deployment error (non-fatal)', { error, skillName });\r\n }\r\n }\r\n\r\n // 9. Send notification (optional)\r\n if (options.notify) {\r\n await this.notifyPromotion(skillName, productionPath, promotedAt);\r\n }\r\n\r\n return {\r\n success: true,\r\n skillName,\r\n productionPath,\r\n promotedAt,\r\n deploymentId,\r\n commitHash,\r\n };\r\n } catch (error) {\r\n logger.error('Promotion failed', { error, stagingPath });\r\n\r\n if (error instanceof StandardError) {\r\n return {\r\n success: false,\r\n error: error.message,\r\n };\r\n }\r\n\r\n return {\r\n success: false,\r\n error: error instanceof Error ? error.message : String(error),\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * List all skills currently in staging\r\n */\r\n async listStagedSkills(): Promise<StagedSkill[]> {\r\n try {\r\n const stagingPath = path.resolve(this.stagingDir);\r\n\r\n // Check if staging directory exists\r\n if (!(await fileExists(stagingPath))) {\r\n logger.debug('Staging directory does not exist', { stagingPath });\r\n return [];\r\n }\r\n\r\n const entries = await fsReaddir(stagingPath, { withFileTypes: true });\r\n const skills: StagedSkill[] = [];\r\n\r\n for (const entry of entries) {\r\n if (!entry.isDirectory()) {\r\n continue;\r\n }\r\n\r\n const skillPath = path.join(stagingPath, entry.name);\r\n const stats = await fsStat(skillPath);\r\n const createdAt = stats.birthtime;\r\n const ageMs = Date.now() - createdAt.getTime();\r\n const ageHours = ageMs / (1000 * 60 * 60);\r\n\r\n skills.push({\r\n name: entry.name,\r\n stagingPath: skillPath,\r\n createdAt,\r\n ageHours: Math.round(ageHours * 10) / 10,\r\n sizeBytes: stats.size,\r\n promoted: false,\r\n });\r\n }\r\n\r\n logger.debug('Listed staged skills', { count: skills.length });\r\n return skills;\r\n } catch (error) {\r\n logger.error('Failed to list staged skills', { error });\r\n throw new StandardError(\r\n ErrorCode.FILE_SYSTEM_ERROR,\r\n `Failed to list staged skills: ${error instanceof Error ? error.message : String(error)}`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Check for stale skills (>48 hours in staging)\r\n */\r\n async checkStaleness(): Promise<StaleSkill[]> {\r\n try {\r\n const allSkills = await this.listStagedSkills();\r\n\r\n const staleSkills = allSkills\r\n .filter((skill) => skill.ageHours >= this.slaThresholdHours)\r\n .map((skill) => ({\r\n ...skill,\r\n slaBreachHours: Math.round((skill.ageHours - this.slaThresholdHours) * 10) / 10,\r\n }));\r\n\r\n if (staleSkills.length > 0) {\r\n logger.warn('Stale skills detected', {\r\n count: staleSkills.length,\r\n slaThresholdHours: this.slaThresholdHours,\r\n skills: staleSkills.map((s) => s.name),\r\n });\r\n }\r\n\r\n return staleSkills;\r\n } catch (error) {\r\n logger.error('Failed to check staleness', { error });\r\n throw new StandardError(\r\n ErrorCode.INTERNAL_ERROR,\r\n `Failed to check staleness: ${error instanceof Error ? error.message : String(error)}`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Record promotion in database\r\n */\r\n private async recordPromotion(\r\n skillName: string,\r\n productionPath: string,\r\n promotedAt: Date,\r\n promotedBy?: string\r\n ): Promise<void> {\r\n try {\r\n const query = `\r\n INSERT INTO skill_promotions (skill_name, production_path, promoted_at, promoted_by)\r\n VALUES (?, ?, ?, ?)\r\n `;\r\n\r\n const adapter = this.dbService.getAdapter('sqlite');\r\n await adapter.query(query, [\r\n skillName,\r\n productionPath,\r\n promotedAt.toISOString(),\r\n promotedBy || 'system',\r\n ]);\r\n\r\n logger.debug('Promotion recorded in database', { skillName });\r\n } catch (error) {\r\n // Log error but don't fail promotion\r\n logger.error('Failed to record promotion in database', { error, skillName });\r\n }\r\n }\r\n\r\n /**\r\n * Create git commit with promotion metadata\r\n */\r\n private async commitPromotion(\r\n skillName: string,\r\n productionPath: string,\r\n promotedAt: Date\r\n ): Promise<string> {\r\n try {\r\n // Stage the promoted skill\r\n await execPromise(`git add ${productionPath}`);\r\n\r\n // Create commit message\r\n const commitMessage = `feat(skills): Promote ${skillName} from staging to production\r\n\r\nAutomated promotion via skill-promotion service.\r\nValidation: PASSED\r\nTests: PASSED\r\nSLA: Within ${this.slaThresholdHours} hours\r\n\r\nPromoted-at: ${promotedAt.toISOString()}\r\nPromoted-by: automated-promotion-service`;\r\n\r\n // Create commit\r\n const { stdout } = await execPromise(`git commit -m \"${commitMessage.replace(/\"/g, '\\\\\"')}\"`);\r\n\r\n // Extract commit hash\r\n const hashMatch = stdout.match(/\\[.*?\\s+([a-f0-9]+)\\]/);\r\n const commitHash = hashMatch ? hashMatch[1] : 'unknown';\r\n\r\n return commitHash;\r\n } catch (error) {\r\n logger.error('Git commit failed', { error, skillName });\r\n throw new StandardError(\r\n ErrorCode.EXTERNAL_SERVICE_ERROR,\r\n `Git commit failed: ${error instanceof Error ? error.message : String(error)}`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Send notification about promotion\r\n */\r\n private async notifyPromotion(\r\n skillName: string,\r\n productionPath: string,\r\n promotedAt: Date\r\n ): Promise<void> {\r\n // Console notification (default)\r\n console.log(`\r\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n SKILL PROMOTION COMPLETE\r\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n Skill: ${skillName}\r\n Location: ${productionPath}\r\n Promoted: ${promotedAt.toISOString()}\r\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n`);\r\n\r\n // Future: Add webhook, email, Slack notifications\r\n logger.info('Promotion notification sent', { skillName });\r\n }\r\n}\r\n"],"names":["fs","path","promisify","exec","StandardError","ErrorCode","createLogger","fileExists","validateStagedSkill","SkillDeploymentPipeline","logger","fsRename","rename","fsStat","stat","fsReaddir","readdir","fsMkdir","mkdir","execPromise","SkillPromotionService","dbService","deploymentPipeline","stagingDir","productionDir","slaThresholdHours","options","promoteSkill","stagingPath","startTime","Date","now","normalizedStagingPath","resolve","skillName","basename","info","skipValidation","debug","validation","success","error","errors","join","warn","productionPath","productionExists","overwrite","backupPath","from","to","parentDir","dirname","recursive","duration","FILE_SYSTEM_ERROR","Error","message","String","promotedAt","recordPromotion","promotedBy","commitHash","gitCommit","commitPromotion","deploymentId","autoDeploy","deployResult","deploySkill","skillPath","deployedBy","notify","notifyPromotion","listStagedSkills","entries","withFileTypes","skills","entry","isDirectory","name","stats","createdAt","birthtime","ageMs","getTime","ageHours","push","Math","round","sizeBytes","size","promoted","count","length","checkStaleness","allSkills","staleSkills","filter","skill","map","slaBreachHours","s","INTERNAL_ERROR","query","adapter","getAdapter","toISOString","commitMessage","stdout","replace","hashMatch","match","EXTERNAL_SERVICE_ERROR","console","log"],"mappings":"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"}
|