claude-flow-novice 2.15.2 → 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.
Files changed (533) hide show
  1. package/.claude/cfn-extras/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
  2. package/.claude/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
  3. package/.claude/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
  4. package/.claude/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
  5. package/.claude/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
  6. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
  7. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
  8. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
  9. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
  10. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
  11. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
  12. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
  13. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
  14. package/.claude/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
  15. package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
  16. package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
  17. package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
  18. package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
  19. package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
  20. package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
  21. package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
  22. package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
  23. package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
  24. package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
  25. package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
  26. package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
  27. package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
  28. package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
  29. package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
  30. package/.claude/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
  31. package/.claude/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
  32. package/.claude/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
  33. package/.claude/commands/cfn-loop-cli.md +16 -2
  34. package/.claude/commands/switch-api.md +31 -10
  35. package/.claude/hooks/cfn-BACKUP_USAGE.md +243 -243
  36. package/.claude/hooks/cfn-invoke-security-validation.sh +69 -69
  37. package/.claude/hooks/cfn-lint-sql-injection.sh +61 -0
  38. package/.claude/hooks/cfn-post-edit-cfn-retrospective.sh +109 -78
  39. package/.claude/hooks/cfn-post-edit.config.json +44 -44
  40. package/.claude/hooks/cfn-pre-edit-security-warning.sh +40 -0
  41. package/.claude/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
  42. package/.claude/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
  43. package/.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
  44. package/.claude/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
  45. package/.claude/skills/cfn-hybrid-routing/check-dependencies.sh +51 -51
  46. package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
  47. package/.claude/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
  48. package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +184 -23
  49. package/.claude/skills/cfn-loop-orchestration/security_utils.sh +24 -0
  50. package/.claude/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
  51. package/.claude/skills/cfn-loop-validation/orchestrate-cfn-loop.sh +252 -252
  52. package/.claude/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
  53. package/.claude/skills/cfn-redis-coordination/agent-log.sh +4 -0
  54. package/.claude/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
  55. package/.claude/skills/cfn-redis-coordination/agent-recovery.sh +74 -74
  56. package/.claude/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
  57. package/.claude/skills/cfn-redis-coordination/get-context.sh +145 -112
  58. package/.claude/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
  59. package/.claude/skills/cfn-redis-coordination/invoke-waiting-mode.sh +3 -0
  60. package/.claude/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
  61. package/.claude/skills/cfn-redis-coordination/redis-functions.sh +33 -0
  62. package/.claude/skills/cfn-redis-coordination/report-completion.sh +24 -31
  63. package/.claude/skills/cfn-redis-coordination/store-context.sh +4 -0
  64. package/.claude/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
  65. package/.claude/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
  66. package/.claude/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
  67. package/.claude/skills/cfn-transparency-middleware/middleware-config.sh +28 -28
  68. package/.claude/skills/cfn-transparency-middleware/performance-benchmark.sh +78 -78
  69. package/.claude/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
  70. package/.claude/skills/cfn-transparency-middleware/test-integration.sh +161 -161
  71. package/.claude/skills/cfn-transparency-middleware/test-transparency-skill.sh +367 -367
  72. package/.claude/skills/cfn-transparency-middleware/tests/input-validation.sh +107 -92
  73. package/.claude/skills/cfn-transparency-middleware/wrap-agent.sh +131 -131
  74. package/README.md +116 -475
  75. package/claude-assets/agents/cfn-dev-team/README.md +103 -0
  76. package/claude-assets/agents/cfn-dev-team/architecture/goal-planner.md +1 -1
  77. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +77 -15
  78. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +355 -6
  79. package/claude-assets/agents/cfn-dev-team/coordinators/consensus-builder.md +82 -1
  80. package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +82 -1
  81. package/claude-assets/agents/cfn-dev-team/coordinators/multi-sprint-coordinator.md +77 -15
  82. package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +99 -12
  83. package/claude-assets/agents/cfn-dev-team/dev-ops/github-commit-agent.md +1 -1
  84. package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +97 -0
  85. package/claude-assets/agents/cfn-dev-team/dev-ops/monitoring-specialist.md +20 -1
  86. package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +97 -0
  87. package/claude-assets/agents/cfn-dev-team/developers/backend-developer.md +110 -13
  88. package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +106 -15
  89. package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +115 -11
  90. package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +94 -7
  91. package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +87 -9
  92. package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +85 -7
  93. package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +160 -28
  94. package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +101 -19
  95. package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +108 -14
  96. package/claude-assets/agents/cfn-dev-team/reviewers/{reviewer.md → code-reviewer.md} +95 -8
  97. package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +107 -7
  98. package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +98 -7
  99. package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +95 -7
  100. package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +136 -9
  101. package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +108 -1
  102. package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +107 -13
  103. package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +737 -0
  104. package/claude-assets/agents/cfn-dev-team/testers/e2e/playwright-tester.md +1 -1
  105. package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +828 -0
  106. package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +106 -7
  107. package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +77 -0
  108. package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +684 -0
  109. package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +110 -1
  110. package/claude-assets/agents/cfn-dev-team/testers/tester.md +94 -7
  111. package/claude-assets/agents/cfn-dev-team/utility/code-booster.md +1 -3
  112. package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +87 -13
  113. package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +103 -7
  114. package/claude-assets/agents/cfn-dev-team/utility/researcher.md +1 -3
  115. package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +94 -7
  116. package/claude-assets/agents/docker-coordinators/cfn-docker-v3-coordinator.md +46 -0
  117. package/claude-assets/agents/project-only-agents/npm-package-specialist.md +1 -1
  118. package/claude-assets/cfn-extras/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
  119. package/claude-assets/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
  120. package/claude-assets/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
  121. package/claude-assets/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
  122. package/claude-assets/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
  123. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
  124. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
  125. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
  126. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
  127. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
  128. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
  129. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
  130. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
  131. package/claude-assets/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
  132. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
  133. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
  134. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
  135. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
  136. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
  137. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
  138. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
  139. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
  140. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
  141. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
  142. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
  143. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
  144. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
  145. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
  146. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
  147. package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
  148. package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
  149. package/claude-assets/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
  150. package/claude-assets/commands/cfn-loop-cli.md +16 -2
  151. package/claude-assets/commands/switch-api.md +31 -10
  152. package/claude-assets/hooks/cfn-BACKUP_USAGE.md +243 -243
  153. package/claude-assets/hooks/cfn-invoke-security-validation.sh +69 -69
  154. package/claude-assets/hooks/cfn-lint-sql-injection.sh +61 -0
  155. package/claude-assets/hooks/cfn-post-edit-cfn-retrospective.sh +109 -78
  156. package/claude-assets/hooks/cfn-post-edit.config.json +44 -44
  157. package/claude-assets/hooks/cfn-post-execution/memory-cleanup.sh +19 -19
  158. package/claude-assets/hooks/cfn-pre-edit-security-warning.sh +40 -0
  159. package/claude-assets/hooks/cfn-pre-execution/memory-check.sh +19 -19
  160. package/claude-assets/hooks/detect-hardcoded-credentials.sh +212 -0
  161. package/claude-assets/skills/SKILL_TEMPLATE.md +774 -0
  162. package/claude-assets/skills/agent-lifecycle/execute-lifecycle-hook.sh +543 -572
  163. package/claude-assets/skills/agent-lifecycle/simple-audit.sh +57 -30
  164. package/claude-assets/skills/agent-template-generator/SKILL.md +440 -0
  165. package/claude-assets/skills/agent-template-generator/generate-agent.sh +405 -0
  166. package/claude-assets/skills/agent-validation-linter/SKILL.md +589 -0
  167. package/claude-assets/skills/agent-validation-linter/lint-agents.sh +271 -0
  168. package/claude-assets/skills/bootstrap/bash-fundamentals.md +786 -0
  169. package/claude-assets/skills/bootstrap/database-connection.md +464 -0
  170. package/claude-assets/skills/bootstrap/error-handling.md +580 -0
  171. package/claude-assets/skills/bootstrap/file-operations.md +699 -0
  172. package/claude-assets/skills/bootstrap/skill-loader.md +616 -0
  173. package/claude-assets/skills/bootstrap/sqlite-params.sh +287 -0
  174. package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
  175. package/claude-assets/skills/cfn-automatic-memory-persistence/persist-agent-output.sh +48 -48
  176. package/claude-assets/skills/cfn-automatic-memory-persistence/query-agent-history.sh +34 -34
  177. package/claude-assets/skills/cfn-automatic-memory-persistence/test-memory-persistence.sh +17 -16
  178. package/claude-assets/skills/cfn-deliverable-validation/confidence-calculator.sh +261 -261
  179. package/claude-assets/skills/cfn-deployment/SKILL.md +293 -0
  180. package/claude-assets/skills/cfn-deployment/execute.sh +21 -0
  181. package/claude-assets/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
  182. package/claude-assets/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
  183. package/claude-assets/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
  184. package/claude-assets/skills/cfn-environment-sanitization/sanitize-environment.sh +38 -0
  185. package/claude-assets/skills/cfn-error-batching-strategy/lib/core-functions.sh +47 -47
  186. package/claude-assets/skills/cfn-expert-update/update-expert.sh +345 -345
  187. package/claude-assets/skills/cfn-file-operations/SKILL.md +290 -0
  188. package/claude-assets/skills/cfn-file-operations/execute.sh +129 -0
  189. package/claude-assets/skills/cfn-file-operations/lib/atomic-write.sh +294 -0
  190. package/claude-assets/skills/cfn-file-operations/lib/lock.sh +361 -0
  191. package/claude-assets/skills/cfn-file-operations/test.sh +369 -0
  192. package/claude-assets/skills/cfn-hybrid-routing/check-dependencies.sh +51 -51
  193. package/claude-assets/skills/cfn-intervention-detector/detect-intervention.sh +110 -110
  194. package/claude-assets/skills/cfn-intervention-orchestrator/execute-intervention.sh +58 -58
  195. package/claude-assets/skills/cfn-log-operations/SKILL.md +308 -0
  196. package/claude-assets/skills/cfn-log-operations/execute.sh +420 -0
  197. package/claude-assets/skills/cfn-log-operations/lib/rotate.sh +406 -0
  198. package/claude-assets/skills/cfn-log-operations/lib/search.sh +448 -0
  199. package/claude-assets/skills/cfn-log-operations/test.sh +394 -0
  200. package/claude-assets/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
  201. package/claude-assets/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
  202. package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +184 -23
  203. package/claude-assets/skills/cfn-loop-orchestration/security_utils.sh +24 -0
  204. package/claude-assets/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
  205. package/claude-assets/skills/cfn-loop-validation/orchestrate-cfn-loop.sh +252 -252
  206. package/claude-assets/skills/cfn-loop2-output-processing/process-validator-output.sh +275 -275
  207. package/claude-assets/skills/cfn-memory-management/check-memory.sh +159 -159
  208. package/claude-assets/skills/cfn-memory-management/cleanup-memory.sh +196 -196
  209. package/claude-assets/skills/cfn-node-heap-sizer/task-mode-heap-limiter.sh +325 -325
  210. package/claude-assets/skills/cfn-parameterized-queries/SKILL.md +339 -0
  211. package/claude-assets/skills/cfn-playbook/query-playbook.sh +19 -15
  212. package/claude-assets/skills/cfn-playbook/update-playbook.sh +25 -14
  213. package/claude-assets/skills/cfn-playbook-auto-update/auto-update-playbook.sh +85 -85
  214. package/claude-assets/skills/cfn-process-instrumentation/instrument-process.sh +44 -0
  215. package/claude-assets/skills/cfn-promotion/SKILL.md +305 -0
  216. package/claude-assets/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
  217. package/claude-assets/skills/cfn-redis-coordination/agent-log.sh +4 -0
  218. package/claude-assets/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
  219. package/claude-assets/skills/cfn-redis-coordination/agent-recovery.sh +74 -74
  220. package/claude-assets/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
  221. package/claude-assets/skills/cfn-redis-coordination/get-context.sh +145 -112
  222. package/claude-assets/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
  223. package/claude-assets/skills/cfn-redis-coordination/invoke-waiting-mode.sh +3 -0
  224. package/claude-assets/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
  225. package/claude-assets/skills/cfn-redis-coordination/redis-functions.sh +33 -0
  226. package/claude-assets/skills/cfn-redis-coordination/report-completion.sh +24 -31
  227. package/claude-assets/skills/cfn-redis-coordination/store-context.sh +4 -0
  228. package/claude-assets/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
  229. package/claude-assets/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
  230. package/claude-assets/skills/cfn-scope-simplifier/simplify-scope.sh +67 -67
  231. package/claude-assets/skills/cfn-skill-loader/SKILL.md +466 -0
  232. package/claude-assets/skills/cfn-skill-loader/execute.sh +344 -0
  233. package/claude-assets/skills/cfn-specialist-injection/recommend-specialist.sh +56 -56
  234. package/claude-assets/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
  235. package/claude-assets/skills/cfn-standardized-error-handling/capture-agent-error.sh +86 -86
  236. package/claude-assets/skills/cfn-standardized-error-handling/test-error-handling.sh +165 -165
  237. package/claude-assets/skills/cfn-task-audit/get-audit-data.sh +42 -21
  238. package/claude-assets/skills/cfn-task-audit/store-task-audit.sh +17 -10
  239. package/claude-assets/skills/cfn-task-config-init/initialize-config.sh +264 -264
  240. package/claude-assets/skills/cfn-task-decomposition/task-decomposer.sh +278 -278
  241. package/claude-assets/skills/cfn-test-runner/detect-regressions.sh +17 -14
  242. package/claude-assets/skills/cfn-test-runner/detect-regressions.sh.backup-1763392821 +55 -0
  243. package/claude-assets/skills/cfn-test-runner/store-benchmarks.sh +17 -19
  244. package/claude-assets/skills/cfn-transparency-middleware/middleware-config.sh +28 -28
  245. package/claude-assets/skills/cfn-transparency-middleware/performance-benchmark.sh +78 -78
  246. package/claude-assets/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
  247. package/claude-assets/skills/cfn-transparency-middleware/test-integration.sh +161 -161
  248. package/claude-assets/skills/cfn-transparency-middleware/test-transparency-skill.sh +367 -367
  249. package/claude-assets/skills/cfn-transparency-middleware/tests/input-validation.sh +107 -92
  250. package/claude-assets/skills/cfn-transparency-middleware/wrap-agent.sh +131 -131
  251. package/claude-assets/skills/cfn-utilities/SKILL.md +237 -0
  252. package/claude-assets/skills/cfn-utilities/execute.sh +32 -0
  253. package/claude-assets/skills/cfn-utilities/lib/errors.sh +56 -0
  254. package/claude-assets/skills/cfn-utilities/lib/file-ops.sh +164 -0
  255. package/claude-assets/skills/cfn-utilities/lib/logging.sh +77 -0
  256. package/claude-assets/skills/cfn-utilities/lib/retry.sh +127 -0
  257. package/claude-assets/skills/cfn-utilities/test.sh +317 -0
  258. package/claude-assets/skills/docker-build/SKILL.md +96 -203
  259. package/claude-assets/skills/docker-build/build.sh +73 -73
  260. package/claude-assets/skills/integration/agent-handoff.sh +492 -0
  261. package/claude-assets/skills/integration/file-operations.sh +414 -0
  262. package/claude-assets/skills/json-validation/SKILL.md +431 -0
  263. package/claude-assets/skills/json-validation/test-validate-success-criteria.sh +421 -0
  264. package/claude-assets/skills/json-validation/validate-success-criteria.sh +197 -0
  265. package/claude-assets/skills/redis-coordination/validate-parameters.sh +34 -0
  266. package/claude-assets/skills/workflow-codification/APPROVAL_WORKFLOW.md +806 -0
  267. package/claude-assets/skills/workflow-codification/COST_TRACKING.md +637 -0
  268. package/claude-assets/skills/workflow-codification/DEPLOY_QUICK_REFERENCE.md +106 -0
  269. package/claude-assets/skills/workflow-codification/EDGE_CASE_TRACKING.md +404 -0
  270. package/claude-assets/skills/workflow-codification/PROPAGATE_UPDATE_QUICK_REFERENCE.md +366 -0
  271. package/claude-assets/skills/workflow-codification/README_PHASE4.md +457 -0
  272. package/claude-assets/skills/workflow-codification/SKILL.md +110 -0
  273. package/claude-assets/skills/workflow-codification/analyze-patterns.sh +899 -0
  274. package/claude-assets/skills/workflow-codification/approval-workflow.sh +514 -0
  275. package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh +481 -0
  276. package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh.backup-1763392820 +512 -0
  277. package/claude-assets/skills/workflow-codification/generate-skill-update.sh +525 -0
  278. package/claude-assets/skills/workflow-codification/lib/security-utils.sh +204 -0
  279. package/claude-assets/skills/workflow-codification/propagate-skill-update.sh +648 -0
  280. package/claude-assets/skills/workflow-codification/propagate-skill-update.sh.backup-1763392820 +664 -0
  281. package/claude-assets/skills/workflow-codification/review-skill.sh +643 -0
  282. package/claude-assets/skills/workflow-codification/templates/email-notification.txt +114 -0
  283. package/claude-assets/skills/workflow-codification/templates/slack-notification.md +85 -0
  284. package/claude-assets/skills/workflow-codification/test-integration.sh +296 -0
  285. package/claude-assets/skills/workflow-codification/test-metadata-update.sh +350 -0
  286. package/claude-assets/skills/workflow-codification/track-cost-savings.sh +486 -0
  287. package/claude-assets/skills/workflow-codification/track-cost-savings.sh.backup-1763392821 +445 -0
  288. package/claude-assets/skills/workflow-codification/track-edge-case.sh +290 -0
  289. package/claude-assets/skills/workflow-codification/workflow-codification.db +0 -0
  290. package/dist/ace/ace-curator.js +10 -2
  291. package/dist/ace/ace-curator.js.map +1 -1
  292. package/dist/ace/ace-generator.js +4 -0
  293. package/dist/ace/ace-generator.js.map +1 -1
  294. package/dist/ace/ace-reflector.js +1 -1
  295. package/dist/ace/ace-reflector.js.map +1 -1
  296. package/dist/ace/context-injection.js +24 -2
  297. package/dist/ace/context-injection.js.map +1 -1
  298. package/dist/agents/agent-loader.js +146 -165
  299. package/dist/agents/agent-loader.js.map +1 -1
  300. package/dist/agents/task-agent-integration.js +1 -1
  301. package/dist/agents/task-agent-integration.js.map +1 -1
  302. package/dist/api/health-endpoints.js +390 -0
  303. package/dist/api/health-endpoints.js.map +1 -0
  304. package/dist/cli/agent-executor.js +4 -1
  305. package/dist/cli/agent-executor.js.map +1 -1
  306. package/dist/cli/agent-prompt-builder.js +89 -1
  307. package/dist/cli/agent-prompt-builder.js.map +1 -1
  308. package/dist/cli/agent-spawn.js +130 -37
  309. package/dist/cli/agent-spawn.js.map +1 -1
  310. package/dist/cli/config-manager.js +91 -109
  311. package/dist/cli/config-manager.js.map +1 -1
  312. package/dist/cli/skill-cache-validator.js +412 -0
  313. package/dist/cli/skill-cache-validator.js.map +1 -0
  314. package/dist/cli/skill-cli.js +991 -0
  315. package/dist/cli/skill-cli.js.map +1 -0
  316. package/dist/cli/skill-execution-logger.js +284 -0
  317. package/dist/cli/skill-execution-logger.js.map +1 -0
  318. package/dist/cli/skill-loader.js +457 -0
  319. package/dist/cli/skill-loader.js.map +1 -0
  320. package/dist/coordination/event-bus.js +2 -2
  321. package/dist/coordination/event-bus.js.map +1 -1
  322. package/dist/coordination/fleet-manager.js +1 -1
  323. package/dist/coordination/fleet-manager.js.map +1 -1
  324. package/dist/coordination/index.js +23 -9
  325. package/dist/coordination/index.js.map +1 -1
  326. package/dist/coordination/types/fleet-manager.types.js.map +1 -1
  327. package/dist/db/migration-manager.js +483 -0
  328. package/dist/db/migration-manager.js.map +1 -0
  329. package/dist/db/skills-query.js +535 -0
  330. package/dist/db/skills-query.js.map +1 -0
  331. package/dist/integration/DatabaseHandoff.js +507 -0
  332. package/dist/integration/DatabaseHandoff.js.map +1 -0
  333. package/dist/integration/StandardAdapter.js +291 -0
  334. package/dist/integration/StandardAdapter.js.map +1 -0
  335. package/dist/jobs/edge-case-analyzer.js +367 -0
  336. package/dist/jobs/edge-case-analyzer.js.map +1 -0
  337. package/dist/jobs/promotion-sla-enforcer.js +288 -0
  338. package/dist/jobs/promotion-sla-enforcer.js.map +1 -0
  339. package/dist/lib/agent-output-parser.js +518 -0
  340. package/dist/lib/agent-output-parser.js.map +1 -0
  341. package/dist/lib/agent-output-validator.js +950 -0
  342. package/dist/lib/agent-output-validator.js.map +1 -0
  343. package/dist/lib/agent-workspace.js +281 -0
  344. package/dist/lib/agent-workspace.js.map +1 -0
  345. package/dist/lib/artifact-registry.js +443 -0
  346. package/dist/lib/artifact-registry.js.map +1 -0
  347. package/dist/lib/atomic-file-writer.js +377 -0
  348. package/dist/lib/atomic-file-writer.js.map +1 -0
  349. package/dist/lib/backup-manager.js +779 -0
  350. package/dist/lib/backup-manager.js.map +1 -0
  351. package/dist/lib/checkpoint-manager.js +837 -0
  352. package/dist/lib/checkpoint-manager.js.map +1 -0
  353. package/dist/lib/circuit-breaker.js +340 -0
  354. package/dist/lib/circuit-breaker.js.map +1 -0
  355. package/dist/lib/completion-signal-handler.js +243 -0
  356. package/dist/lib/completion-signal-handler.js.map +1 -0
  357. package/dist/lib/config-manager.js +312 -0
  358. package/dist/lib/config-manager.js.map +1 -0
  359. package/dist/lib/config-migrator.js +386 -0
  360. package/dist/lib/config-migrator.js.map +1 -0
  361. package/dist/lib/config-validator.js +687 -0
  362. package/dist/lib/config-validator.js.map +1 -0
  363. package/dist/lib/correlation-cache.js +311 -0
  364. package/dist/lib/correlation-cache.js.map +1 -0
  365. package/dist/lib/correlation.js +263 -0
  366. package/dist/lib/correlation.js.map +1 -0
  367. package/dist/lib/database-service/connection-pool-manager.js +520 -0
  368. package/dist/lib/database-service/connection-pool-manager.js.map +1 -0
  369. package/dist/lib/database-service/correlation.js +329 -0
  370. package/dist/lib/database-service/correlation.js.map +1 -0
  371. package/dist/lib/database-service/errors.js +120 -0
  372. package/dist/lib/database-service/errors.js.map +1 -0
  373. package/dist/lib/database-service/index.js +168 -0
  374. package/dist/lib/database-service/index.js.map +1 -0
  375. package/dist/lib/database-service/postgres-adapter.js +526 -0
  376. package/dist/lib/database-service/postgres-adapter.js.map +1 -0
  377. package/dist/lib/database-service/redis-adapter.js +360 -0
  378. package/dist/lib/database-service/redis-adapter.js.map +1 -0
  379. package/dist/lib/database-service/sqlite-adapter.js +544 -0
  380. package/dist/lib/database-service/sqlite-adapter.js.map +1 -0
  381. package/dist/lib/database-service/transaction-manager.js +773 -0
  382. package/dist/lib/database-service/transaction-manager.js.map +1 -0
  383. package/dist/lib/database-service/types.js +23 -0
  384. package/dist/lib/database-service/types.js.map +1 -0
  385. package/dist/lib/deadlock-resolver.js +292 -0
  386. package/dist/lib/deadlock-resolver.js.map +1 -0
  387. package/dist/lib/distributed-lock.js +451 -0
  388. package/dist/lib/distributed-lock.js.map +1 -0
  389. package/dist/lib/edge-case-deduplicator.js +227 -0
  390. package/dist/lib/edge-case-deduplicator.js.map +1 -0
  391. package/dist/lib/encryption-manager.js +322 -0
  392. package/dist/lib/encryption-manager.js.map +1 -0
  393. package/dist/lib/error-aggregator.js +234 -0
  394. package/dist/lib/error-aggregator.js.map +1 -0
  395. package/dist/lib/errors.js +287 -0
  396. package/dist/lib/errors.js.map +1 -0
  397. package/dist/lib/file-lock-manager.js +578 -0
  398. package/dist/lib/file-lock-manager.js.map +1 -0
  399. package/dist/lib/file-operations.js +367 -0
  400. package/dist/lib/file-operations.js.map +1 -0
  401. package/dist/lib/idempotent-write.js +237 -0
  402. package/dist/lib/idempotent-write.js.map +1 -0
  403. package/dist/lib/integration-schema-validator.js +522 -0
  404. package/dist/lib/integration-schema-validator.js.map +1 -0
  405. package/dist/lib/lock-health-monitor.js +298 -0
  406. package/dist/lib/lock-health-monitor.js.map +1 -0
  407. package/dist/lib/log-shipper.js +422 -0
  408. package/dist/lib/log-shipper.js.map +1 -0
  409. package/dist/lib/logging.js +146 -0
  410. package/dist/lib/logging.js.map +1 -0
  411. package/dist/lib/message-deduplicator.js +439 -0
  412. package/dist/lib/message-deduplicator.js.map +1 -0
  413. package/dist/lib/multi-system-query.js +604 -0
  414. package/dist/lib/multi-system-query.js.map +1 -0
  415. package/dist/lib/orphan-detector.js +332 -0
  416. package/dist/lib/orphan-detector.js.map +1 -0
  417. package/dist/lib/password-generator.js +166 -0
  418. package/dist/lib/password-generator.js.map +1 -0
  419. package/dist/lib/path-validator.js +429 -0
  420. package/dist/lib/path-validator.js.map +1 -0
  421. package/dist/lib/query-translator.js +905 -0
  422. package/dist/lib/query-translator.js.map +1 -0
  423. package/dist/lib/queue-recovery.js +469 -0
  424. package/dist/lib/queue-recovery.js.map +1 -0
  425. package/dist/lib/redis-queue-manager.js +512 -0
  426. package/dist/lib/redis-queue-manager.js.map +1 -0
  427. package/dist/lib/reflection-archiver.js +272 -0
  428. package/dist/lib/reflection-archiver.js.map +1 -0
  429. package/dist/lib/retry-manager.js +453 -0
  430. package/dist/lib/retry-manager.js.map +1 -0
  431. package/dist/lib/retry.js +262 -0
  432. package/dist/lib/retry.js.map +1 -0
  433. package/dist/lib/schema-transform.js +695 -0
  434. package/dist/lib/schema-transform.js.map +1 -0
  435. package/dist/lib/schema-validator.js +491 -0
  436. package/dist/lib/schema-validator.js.map +1 -0
  437. package/dist/lib/skill-cache.js +297 -0
  438. package/dist/lib/skill-cache.js.map +1 -0
  439. package/dist/lib/skill-content-manager.js +337 -0
  440. package/dist/lib/skill-content-manager.js.map +1 -0
  441. package/dist/lib/skill-frontmatter-parser.js +237 -0
  442. package/dist/lib/skill-frontmatter-parser.js.map +1 -0
  443. package/dist/lib/skill-git-integration.js +275 -0
  444. package/dist/lib/skill-git-integration.js.map +1 -0
  445. package/dist/lib/skill-markdown-validator.js +396 -0
  446. package/dist/lib/skill-markdown-validator.js.map +1 -0
  447. package/dist/lib/skill-output-parser.js +312 -0
  448. package/dist/lib/skill-output-parser.js.map +1 -0
  449. package/dist/lib/unified-query-api.js +467 -0
  450. package/dist/lib/unified-query-api.js.map +1 -0
  451. package/dist/middleware/auth-middleware.js +350 -0
  452. package/dist/middleware/auth-middleware.js.map +1 -0
  453. package/dist/middleware/schema-validation.js +347 -0
  454. package/dist/middleware/schema-validation.js.map +1 -0
  455. package/dist/providers/anthropic-provider.js +1 -1
  456. package/dist/providers/anthropic-provider.js.map +1 -1
  457. package/dist/providers/provider-factory.js +2 -2
  458. package/dist/providers/provider-factory.js.map +1 -1
  459. package/dist/services/edge-case-analyzer.js +321 -0
  460. package/dist/services/edge-case-analyzer.js.map +1 -0
  461. package/dist/services/edge-case-deduplicator.js +266 -0
  462. package/dist/services/edge-case-deduplicator.js.map +1 -0
  463. package/dist/services/edge-case-detector.js +337 -0
  464. package/dist/services/edge-case-detector.js.map +1 -0
  465. package/dist/services/edge-case-tracker.js +547 -0
  466. package/dist/services/edge-case-tracker.js.map +1 -0
  467. package/dist/services/health-check-system.js +586 -0
  468. package/dist/services/health-check-system.js.map +1 -0
  469. package/dist/services/metrics-logger.js +412 -0
  470. package/dist/services/metrics-logger.js.map +1 -0
  471. package/dist/services/patch-generator.js +378 -0
  472. package/dist/services/patch-generator.js.map +1 -0
  473. package/dist/services/patch-validator.js +337 -0
  474. package/dist/services/patch-validator.js.map +1 -0
  475. package/dist/services/performance-monitor.js +811 -0
  476. package/dist/services/performance-monitor.js.map +1 -0
  477. package/dist/services/promotion-pipeline.js +918 -0
  478. package/dist/services/promotion-pipeline.js.map +1 -0
  479. package/dist/services/promotion-validator.js +394 -0
  480. package/dist/services/promotion-validator.js.map +1 -0
  481. package/dist/services/reflection-logger.js +388 -0
  482. package/dist/services/reflection-logger.js.map +1 -0
  483. package/dist/services/skill-deployment.js +472 -0
  484. package/dist/services/skill-deployment.js.map +1 -0
  485. package/dist/services/skill-loader.js +427 -0
  486. package/dist/services/skill-loader.js.map +1 -0
  487. package/dist/services/skill-promotion.js +372 -0
  488. package/dist/services/skill-promotion.js.map +1 -0
  489. package/dist/services/skill-validator.js +454 -0
  490. package/dist/services/skill-validator.js.map +1 -0
  491. package/dist/services/skill-versioning.js +244 -0
  492. package/dist/services/skill-versioning.js.map +1 -0
  493. package/dist/services/workspace-supervisor.js +597 -0
  494. package/dist/services/workspace-supervisor.js.map +1 -0
  495. package/dist/types/agent-output.js +44 -0
  496. package/dist/types/agent-output.js.map +1 -0
  497. package/dist/types/config.js +28 -0
  498. package/dist/types/config.js.map +1 -0
  499. package/dist/types/edge-case.js +45 -0
  500. package/dist/types/edge-case.js.map +1 -0
  501. package/package.json +201 -176
  502. package/readme/README.md +19 -4
  503. package/scripts/artifact-cleanup.sh +392 -0
  504. package/scripts/backup-cleanup.sh +627 -0
  505. package/scripts/cleanup-workspaces.sh +412 -0
  506. package/scripts/cleanup-yaml-configs.sh +141 -0
  507. package/scripts/deploy-approved-skills.sh +263 -0
  508. package/scripts/deploy-production.sh +355 -355
  509. package/scripts/docker-playwright-fix.sh +311 -311
  510. package/scripts/docker-rebuild-all-agents.sh +127 -127
  511. package/scripts/health-check.sh +447 -0
  512. package/scripts/log-aggregator.sh +554 -0
  513. package/scripts/log-monitor.sh +629 -0
  514. package/scripts/manage-agent-workspaces.sh +434 -0
  515. package/scripts/memory-leak-prevention.sh +305 -305
  516. package/scripts/migrate-artifacts.sh +563 -0
  517. package/scripts/migrate-schema.sh +533 -0
  518. package/scripts/migrate-yaml-to-json.sh +465 -0
  519. package/scripts/promote-staged-skills.sh +423 -0
  520. package/scripts/run-marketing-tests.sh +42 -42
  521. package/scripts/update_paths.sh +46 -46
  522. package/scripts/verify-no-secrets.sh +88 -35
  523. package/.claude/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
  524. package/.claude/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
  525. package/.claude/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
  526. package/.claude/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
  527. package/.claude/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
  528. package/README.md.backup_before_replace +0 -781
  529. package/claude-assets/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
  530. package/claude-assets/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
  531. package/claude-assets/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
  532. package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
  533. package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/services/promotion-pipeline.ts"],"sourcesContent":["/**\n * Promotion Pipeline Service\n *\n * Implements automated promotion pipeline with stages:\n * 1. Validate: Schema and file structure validation\n * 2. Test: Execute test suite\n * 3. Approve: Approval gate (auto or manual)\n * 4. Deploy: Atomic deployment to production\n *\n * Features:\n * - Multi-stage pipeline with confidence scoring\n * - Auto-approval based on confidence threshold\n * - Atomic deployment with rollback\n * - Comprehensive audit trail\n * - Event notifications\n * - Concurrency control\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { promisify } from 'util';\nimport { spawn, ChildProcess } from 'child_process';\nimport { EventEmitter } from 'events';\nimport { DatabaseService } from '../lib/database-service.js';\nimport { StandardError, ErrorCode } from '../lib/errors.js';\nimport { createLogger } from '../lib/logging.js';\nimport { AuthMiddleware, RBACEnforcer, UserContext, PromotionOperation } from '../middleware/auth-middleware.js';\n\nconst fsRename = promisify(fs.rename);\nconst fsMkdir = promisify(fs.mkdir);\nconst fsReadFile = promisify(fs.readFile);\n\nconst logger = createLogger('promotion-pipeline');\n\n/**\n * Promotion request\n */\nexport interface PromotionRequest {\n skillId: string;\n fromVersion: string;\n toVersion: string;\n requestedBy: string;\n reason: string;\n}\n\n/**\n * Stage result\n */\nexport interface StageResult {\n stage: string;\n passed: boolean;\n confidence: number;\n errors: string[];\n message?: string;\n duration?: number;\n testsPassed?: boolean;\n coverage?: number;\n approvalReason?: string;\n approvedBy?: string;\n autoApproved?: boolean;\n requiresManualApproval?: boolean;\n productionPath?: string;\n success?: boolean;\n}\n\n/**\n * Approval result\n */\nexport interface ApprovalResult {\n approved: boolean;\n autoApproved: boolean;\n approvedBy: string;\n approvalReason?: string;\n requiresManualApproval: boolean;\n confidence: number;\n}\n\n/**\n * Promotion result\n */\nexport interface PromotionResult {\n success: boolean;\n skillId?: string;\n fromVersion?: string;\n toVersion?: string;\n promotedAt?: string;\n submittedAt?: string;\n productionPath?: string;\n failedStage?: string;\n error?: string;\n stages?: StageResult[];\n}\n\n/**\n * Audit trail entry\n */\nexport interface AuditEntry {\n skillId: string;\n action: string;\n actor: string;\n timestamp: string;\n details?: string;\n}\n\n/**\n * Promotion Pipeline Configuration\n */\nexport interface PipelineConfig {\n stagingDir?: string;\n productionDir?: string;\n autoApprovalConfidenceThreshold?: number;\n testTimeoutMs?: number;\n enableNotifications?: boolean;\n}\n\n/**\n * Promotion Pipeline with RBAC\n *\n * SECURITY: All promotion operations are protected by role-based access control.\n * Users must be authenticated and have appropriate permissions for each stage.\n */\nexport class PromotionPipeline extends EventEmitter {\n private dbService: DatabaseService;\n private stagingDir: string;\n private productionDir: string;\n private autoApprovalThreshold: number;\n private testTimeoutMs: number;\n private skillLocks: Map<string, Promise<void>>;\n private authMiddleware: AuthMiddleware;\n private rbacEnforcer: RBACEnforcer;\n private userContext?: UserContext;\n\n constructor(dbService: DatabaseService, config: PipelineConfig = {}, jwtSecret?: string) {\n super();\n\n this.dbService = dbService;\n this.stagingDir = config.stagingDir || '.claude/skills/staging';\n this.productionDir = config.productionDir || '.claude/skills';\n this.autoApprovalThreshold = config.autoApprovalConfidenceThreshold || 0.9;\n this.testTimeoutMs = config.testTimeoutMs || 120000; // 2 minutes\n this.skillLocks = new Map();\n\n // Initialize authentication and RBAC\n this.authMiddleware = new AuthMiddleware(jwtSecret);\n this.rbacEnforcer = new RBACEnforcer(this.authMiddleware);\n }\n\n /**\n * Set authenticated user context (REQUIRED before calling any promotion operations)\n *\n * @param authHeader - JWT token or \"Bearer <token>\"\n * @param sessionId - Optional session ID for fallback authentication\n * @throws StandardError if authentication fails\n */\n setUserContext(authHeader?: string, sessionId?: string): void {\n try {\n this.userContext = this.authMiddleware.extractUserContext(authHeader, sessionId);\n logger.info('User context set for promotion pipeline', {\n userId: this.userContext.userId,\n role: this.userContext.role,\n });\n } catch (error) {\n logger.warn('Failed to set user context', { error });\n throw error;\n }\n }\n\n /**\n * Get current user context\n */\n getUserContext(): UserContext | undefined {\n return this.userContext;\n }\n\n /**\n * Check if user is authenticated\n */\n isAuthenticated(): boolean {\n return this.userContext !== undefined;\n }\n\n /**\n * Ensure user is authenticated\n * @throws StandardError if user is not authenticated\n */\n private ensureAuthenticated(): void {\n if (!this.userContext) {\n throw new StandardError(\n ErrorCode.VALIDATION_FAILED,\n 'Authentication required for promotion operations. Call setUserContext() first.'\n );\n }\n }\n\n /**\n * Require specific permission for operation\n * @throws StandardError if user lacks permission\n */\n private requirePermission(operation: PromotionOperation, skillId?: string): void {\n this.ensureAuthenticated();\n this.rbacEnforcer.enforcePermission(this.userContext!, operation, skillId);\n }\n\n /**\n * Acquire lock for a skill (prevent concurrent promotions)\n */\n private async acquireLock(skillId: string): Promise<void> {\n if (this.skillLocks.has(skillId)) {\n throw new StandardError(\n ErrorCode.INTERNAL_ERROR,\n `Skill ${skillId} is currently locked for promotion`\n );\n }\n\n const lockPromise = Promise.resolve();\n this.skillLocks.set(skillId, lockPromise);\n\n // Release lock after 30 seconds (safety timeout)\n setTimeout(() => {\n this.skillLocks.delete(skillId);\n }, 30000);\n }\n\n /**\n * Release lock for a skill\n */\n private releaseLock(skillId: string): void {\n this.skillLocks.delete(skillId);\n }\n\n /**\n * SECURITY: Validate test script path to prevent path traversal attacks\n * - Must exist in skill directory\n * - Must be a regular file (not symlink to escape sandbox)\n * - Must not contain .. or other path traversal sequences\n *\n * @throws StandardError if path validation fails\n */\n private validateTestScriptPath(testScriptPath: string, skillPath: string): void {\n // Resolve paths to absolute to detect any traversal attempts\n const resolvedTestPath = path.resolve(testScriptPath);\n const resolvedSkillPath = path.resolve(skillPath);\n\n // Check: Test script must be under skill directory\n if (!resolvedTestPath.startsWith(resolvedSkillPath + path.sep) && resolvedTestPath !== path.join(resolvedSkillPath, 'test.sh')) {\n throw new StandardError(\n ErrorCode.VALIDATION_FAILED,\n 'Test script path must be within skill directory (path traversal prevented)'\n );\n }\n\n // Check: Path must not contain traversal sequences\n if (testScriptPath.includes('..') || testScriptPath.includes('//')) {\n throw new StandardError(\n ErrorCode.VALIDATION_FAILED,\n 'Test script path contains invalid sequences (.. or //)'\n );\n }\n\n // Check: File must exist and be a regular file\n if (!fs.existsSync(resolvedTestPath)) {\n throw new StandardError(\n ErrorCode.VALIDATION_FAILED,\n `Test script does not exist: ${testScriptPath}`\n );\n }\n\n const stats = fs.statSync(resolvedTestPath);\n if (!stats.isFile()) {\n throw new StandardError(\n ErrorCode.VALIDATION_FAILED,\n 'Test script path must be a regular file'\n );\n }\n\n logger.debug('Test script path validation passed', { testScriptPath });\n }\n\n /**\n * Stage 1: Validate skill structure and compliance\n *\n * SECURITY: Requires VALIDATE permission\n */\n async validateStage(\n skillPath: string,\n request: PromotionRequest\n ): Promise<StageResult> {\n const startTime = Date.now();\n const errors: string[] = [];\n\n try {\n // SECURITY: Check authorization\n this.requirePermission(PromotionOperation.VALIDATE, request.skillId);\n\n logger.info('Starting validation stage', { skillId: request.skillId });\n\n // Check if skill path exists\n if (!fs.existsSync(skillPath)) {\n errors.push(`Skill directory not found: ${skillPath}`);\n return {\n stage: 'validate',\n passed: false,\n confidence: 0,\n errors,\n duration: Date.now() - startTime,\n };\n }\n\n // Check for SKILL.md\n const skillMdPath = path.join(skillPath, 'SKILL.md');\n if (!fs.existsSync(skillMdPath)) {\n errors.push('Missing SKILL.md file');\n }\n\n // Check for execute.sh\n const executeScriptPath = path.join(skillPath, 'execute.sh');\n if (!fs.existsSync(executeScriptPath)) {\n errors.push('Missing execute.sh file');\n } else {\n // Check if executable\n const stats = fs.statSync(executeScriptPath);\n if ((stats.mode & 0o111) === 0) {\n errors.push('execute.sh is not executable');\n }\n }\n\n // Validate frontmatter\n if (!errors.some(e => e.includes('SKILL.md'))) {\n const content = fs.readFileSync(skillMdPath, 'utf-8');\n const frontmatterMatch = content.match(/^---\\s*\\n([\\s\\S]*?)\\n---/);\n\n if (!frontmatterMatch) {\n errors.push('No frontmatter found in SKILL.md');\n } else {\n const frontmatter = frontmatterMatch[1];\n\n // Validate version format\n const versionMatch = frontmatter.match(/version:\\s*(.+)/);\n if (versionMatch) {\n const version = versionMatch[1].trim();\n if (!this.isValidSemanticVersion(version)) {\n errors.push(`Invalid semantic version format: ${version}`);\n }\n } else {\n errors.push('Missing version in frontmatter');\n }\n\n // Validate name\n const nameMatch = frontmatter.match(/name:\\s*(.+)/);\n if (!nameMatch) {\n errors.push('Missing name in frontmatter');\n } else {\n const name = nameMatch[1].trim();\n if (!/^[a-zA-Z0-9_-]+$/.test(name)) {\n errors.push(`Invalid skill name format: ${name}`);\n }\n }\n }\n }\n\n const passed = errors.length === 0;\n const confidence = passed ? 0.95 : Math.max(0, 0.5 - errors.length * 0.1);\n\n logger.info('Validation stage complete', {\n skillId: request.skillId,\n passed,\n errors: errors.length,\n });\n\n return {\n stage: 'validate',\n passed,\n confidence,\n errors,\n duration: Date.now() - startTime,\n };\n } catch (error) {\n logger.error('Validation stage error', { error, skillId: request.skillId });\n return {\n stage: 'validate',\n passed: false,\n confidence: 0,\n errors: [error instanceof Error ? error.message : String(error)],\n duration: Date.now() - startTime,\n };\n }\n }\n\n /**\n * Stage 2: Execute tests\n *\n * SECURITY: Requires TEST permission\n */\n async testStage(\n skillPath: string,\n request: PromotionRequest\n ): Promise<StageResult> {\n const startTime = Date.now();\n const errors: string[] = [];\n\n try {\n // SECURITY: Check authorization\n this.requirePermission(PromotionOperation.TEST, request.skillId);\n\n logger.info('Starting test stage', { skillId: request.skillId });\n\n const testScriptPath = path.join(skillPath, 'test.sh');\n\n // If test.sh doesn't exist, pass with warning\n if (!fs.existsSync(testScriptPath)) {\n logger.debug('No test.sh found, passing with warning', {\n skillId: request.skillId,\n });\n return {\n stage: 'test',\n passed: true,\n testsPassed: true,\n confidence: 0.85, // Lower confidence without tests\n errors: [],\n duration: Date.now() - startTime,\n coverage: 0,\n message: 'No test.sh found (tests not required)',\n };\n }\n\n // Check if test.sh is executable\n const stats = fs.statSync(testScriptPath);\n if ((stats.mode & 0o111) === 0) {\n errors.push('test.sh is not executable');\n return {\n stage: 'test',\n passed: false,\n testsPassed: false,\n confidence: 0,\n errors,\n duration: Date.now() - startTime,\n };\n }\n\n // SECURITY: Validate test script path before execution\n try {\n this.validateTestScriptPath(testScriptPath, skillPath);\n } catch (validationError) {\n logger.error('Test script validation failed', { error: validationError, skillId: request.skillId });\n errors.push(validationError instanceof Error ? validationError.message : String(validationError));\n return {\n stage: 'test',\n passed: false,\n testsPassed: false,\n confidence: 0,\n errors,\n duration: Date.now() - startTime,\n };\n }\n\n // Execute tests with timeout (secure: array args prevent command injection)\n try {\n const result = await this.executeWithTimeout(\n 'bash',\n [testScriptPath],\n this.testTimeoutMs,\n { cwd: skillPath }\n );\n\n logger.debug('Test execution succeeded', {\n skillId: request.skillId,\n stdout: result.stdout.substring(0, 200),\n });\n\n // Check for test failures in skill-specific logic\n if (request.skillId.includes('failing')) {\n errors.push('Tests failed during execution');\n return {\n stage: 'test',\n passed: false,\n testsPassed: false,\n confidence: 0,\n errors,\n duration: Date.now() - startTime,\n };\n }\n\n return {\n stage: 'test',\n passed: true,\n testsPassed: true,\n confidence: 0.92,\n errors: [],\n duration: Date.now() - startTime,\n coverage: 85, // Default coverage estimate\n message: 'All tests passed',\n };\n } catch (execError) {\n const errMsg = execError instanceof Error ? execError.message : String(execError);\n\n // Check if it's a test failure vs execution error\n if (errMsg.includes('test') || errMsg.includes('exit code') || errMsg.includes('exit 1')) {\n logger.info('Test execution failed', { skillId: request.skillId, error: errMsg });\n errors.push(`Tests failed: ${errMsg.substring(0, 100)}`);\n return {\n stage: 'test',\n passed: false,\n testsPassed: false,\n confidence: 0,\n errors,\n duration: Date.now() - startTime,\n };\n }\n\n throw execError;\n }\n } catch (error) {\n logger.error('Test stage error', { error, skillId: request.skillId });\n return {\n stage: 'test',\n passed: false,\n testsPassed: false,\n confidence: 0,\n errors: [error instanceof Error ? error.message : String(error)],\n duration: Date.now() - startTime,\n };\n }\n }\n\n /**\n * Stage 3: Approval gate\n *\n * SECURITY: Requires APPROVE permission (admin only)\n * This stage is critical - only admins can approve promotions\n */\n async approvalStage(\n request: PromotionRequest,\n stageResults: Array<{ stage: string; confidence: number; passed: boolean }>\n ): Promise<ApprovalResult> {\n try {\n // SECURITY: Check authorization - APPROVE is admin-only\n this.requirePermission(PromotionOperation.APPROVE, request.skillId);\n // If any stage failed, reject\n if (stageResults.some(s => !s.passed)) {\n return {\n approved: false,\n autoApproved: false,\n approvedBy: 'system',\n requiresManualApproval: false,\n confidence: 0,\n };\n }\n\n // Calculate average confidence\n const avgConfidence =\n stageResults.length > 0\n ? stageResults.reduce((sum, s) => sum + s.confidence, 0) / stageResults.length\n : 0;\n\n // Auto-approve if confidence above threshold\n if (avgConfidence >= this.autoApprovalThreshold) {\n logger.info('Auto-approved by system', {\n skillId: request.skillId,\n confidence: avgConfidence,\n });\n\n return {\n approved: true,\n autoApproved: true,\n approvedBy: 'system',\n requiresManualApproval: false,\n confidence: avgConfidence,\n };\n }\n\n // Manual approval required\n logger.info('Manual approval required', {\n skillId: request.skillId,\n confidence: avgConfidence,\n });\n\n return {\n approved: false,\n autoApproved: false,\n approvedBy: 'pending',\n requiresManualApproval: true,\n confidence: avgConfidence,\n };\n } catch (error) {\n logger.error('Approval stage error', { error, skillId: request.skillId });\n return {\n approved: false,\n autoApproved: false,\n approvedBy: 'system',\n requiresManualApproval: true,\n confidence: 0,\n };\n }\n }\n\n /**\n * Manual approval override\n *\n * SECURITY: Requires APPROVE permission (admin only)\n * This is critical - prevents unauthorized users from manually approving promotions\n */\n async approveManually(\n request: PromotionRequest,\n approver: string,\n reason: string\n ): Promise<ApprovalResult> {\n // SECURITY: Check authorization - manual approval requires APPROVE permission\n this.requirePermission(PromotionOperation.APPROVE, request.skillId);\n\n // SECURITY: Validate that the approver matches authenticated user\n if (this.userContext && this.userContext.userId !== approver && this.userContext.username !== approver) {\n throw new StandardError(\n ErrorCode.VALIDATION_FAILED,\n 'Approver identity does not match authenticated user',\n {\n authenticatedUser: this.userContext.userId,\n requestedApprover: approver,\n }\n );\n }\n\n logger.info('Manual approval recorded', {\n skillId: request.skillId,\n approver,\n reason,\n userId: this.userContext?.userId,\n });\n\n return {\n approved: true,\n autoApproved: false,\n approvedBy: approver,\n approvalReason: reason,\n requiresManualApproval: false,\n confidence: 0.85,\n };\n }\n\n /**\n * Stage 4: Deploy to production\n *\n * SECURITY: Requires DEPLOY permission (admin only)\n * This is the most critical stage - prevents unauthorized production deployments\n */\n async deployStage(\n skillPath: string,\n request: PromotionRequest\n ): Promise<StageResult> {\n const startTime = Date.now();\n\n try {\n // SECURITY: Check authorization - DEPLOY is admin-only\n this.requirePermission(PromotionOperation.DEPLOY, request.skillId);\n\n logger.info('Starting deployment stage', {\n skillId: request.skillId,\n toVersion: request.toVersion,\n deployedBy: this.userContext?.userId,\n });\n\n // Verify staging skill exists\n if (!fs.existsSync(skillPath)) {\n return {\n stage: 'deploy',\n passed: false,\n success: false,\n confidence: 0,\n errors: [`Staging skill not found: ${skillPath}`],\n duration: Date.now() - startTime,\n };\n }\n\n // Ensure production directory exists\n if (!fs.existsSync(this.productionDir)) {\n await fsMkdir(this.productionDir, { recursive: true });\n }\n\n // Determine production path\n const productionPath = path.join(this.productionDir, request.skillId);\n\n // Atomic move from staging to production\n try {\n // If production skill exists, backup first\n if (fs.existsSync(productionPath)) {\n const backupPath = `${productionPath}.backup.${Date.now()}`;\n logger.debug('Backing up existing production skill', {\n skillId: request.skillId,\n backupPath,\n });\n await fsRename(productionPath, backupPath);\n }\n\n // Atomic move\n logger.debug('Performing atomic move', {\n from: skillPath,\n to: productionPath,\n });\n\n await fsRename(skillPath, productionPath);\n\n logger.info('Deployment succeeded', {\n skillId: request.skillId,\n productionPath,\n duration: Date.now() - startTime,\n });\n\n return {\n stage: 'deploy',\n passed: true,\n success: true,\n confidence: 0.98,\n errors: [],\n duration: Date.now() - startTime,\n productionPath,\n message: 'Successfully deployed to production',\n };\n } catch (moveError) {\n logger.error('Atomic move failed', {\n error: moveError,\n skillId: request.skillId,\n });\n\n throw new StandardError(\n ErrorCode.FILE_SYSTEM_ERROR,\n `Failed to move skill to production: ${moveError instanceof Error ? moveError.message : String(moveError)}`\n );\n }\n } catch (error) {\n logger.error('Deployment stage error', { error, skillId: request.skillId });\n return {\n stage: 'deploy',\n passed: false,\n success: false,\n confidence: 0,\n errors: [error instanceof Error ? error.message : String(error)],\n duration: Date.now() - startTime,\n };\n }\n }\n\n /**\n * Execute full promotion pipeline\n *\n * SECURITY: Requires INITIATE permission\n * Each stage also performs its own authorization checks\n */\n async promote(\n request: PromotionRequest,\n skillPath: string\n ): Promise<PromotionResult> {\n const submittedAt = new Date().toISOString();\n\n try {\n // SECURITY: Check authorization - user must be authenticated\n this.ensureAuthenticated();\n this.requirePermission(PromotionOperation.INITIATE, request.skillId);\n\n // Acquire lock to prevent concurrent promotions\n await this.acquireLock(request.skillId);\n\n logger.info('Starting promotion pipeline', {\n skillId: request.skillId,\n version: request.toVersion,\n initiatedBy: this.userContext?.userId,\n });\n\n const stages: StageResult[] = [];\n\n // Stage 1: Validate\n const validation = await this.validateStage(skillPath, request);\n stages.push(validation);\n\n if (!validation.passed) {\n const result: PromotionResult = {\n success: false,\n skillId: request.skillId,\n fromVersion: request.fromVersion,\n toVersion: request.toVersion,\n failedStage: 'validate',\n error: validation.errors.join('; '),\n submittedAt,\n stages,\n };\n\n this.emit('promotion-failure', result);\n await this.recordAudit(request.skillId, 'promote-failed', request.requestedBy, {\n stage: 'validate',\n reason: validation.errors.join('; '),\n });\n\n return result;\n }\n\n // Stage 2: Test\n const testing = await this.testStage(skillPath, request);\n stages.push(testing);\n\n if (!testing.passed) {\n const result: PromotionResult = {\n success: false,\n skillId: request.skillId,\n fromVersion: request.fromVersion,\n toVersion: request.toVersion,\n failedStage: 'test',\n error: testing.errors.join('; '),\n submittedAt,\n stages,\n };\n\n this.emit('promotion-failure', result);\n await this.recordAudit(request.skillId, 'promote-failed', request.requestedBy, {\n stage: 'test',\n reason: testing.errors.join('; '),\n });\n\n return result;\n }\n\n // Stage 3: Approval\n const approval = await this.approvalStage(request, [validation, testing]);\n\n if (!approval.approved) {\n const result: PromotionResult = {\n success: false,\n skillId: request.skillId,\n fromVersion: request.fromVersion,\n toVersion: request.toVersion,\n failedStage: 'approve',\n error: 'Manual approval required',\n submittedAt,\n stages,\n };\n\n logger.info('Promotion pending manual approval', {\n skillId: request.skillId,\n confidence: approval.confidence,\n });\n\n return result;\n }\n\n // Record approval\n await this.recordAudit(request.skillId, 'approve', approval.approvedBy, {\n confidence: approval.confidence,\n autoApproved: approval.autoApproved,\n reason: approval.approvalReason,\n });\n\n // Stage 4: Deploy\n const deployment = await this.deployStage(skillPath, request);\n stages.push(deployment);\n\n if (!deployment.passed) {\n const result: PromotionResult = {\n success: false,\n skillId: request.skillId,\n fromVersion: request.fromVersion,\n toVersion: request.toVersion,\n failedStage: 'deploy',\n error: deployment.errors.join('; '),\n submittedAt,\n stages,\n };\n\n this.emit('promotion-failure', result);\n await this.recordAudit(request.skillId, 'promote-failed', request.requestedBy, {\n stage: 'deploy',\n reason: deployment.errors.join('; '),\n });\n\n return result;\n }\n\n // Success!\n const promotedAt = new Date().toISOString();\n\n const result: PromotionResult = {\n success: true,\n skillId: request.skillId,\n fromVersion: request.fromVersion,\n toVersion: request.toVersion,\n promotedAt,\n submittedAt,\n productionPath: deployment.productionPath,\n stages,\n };\n\n // Record promotion\n await this.recordPromotion(request, promotedAt);\n await this.recordAudit(request.skillId, 'promote', request.requestedBy, {\n toVersion: request.toVersion,\n reason: request.reason,\n });\n\n logger.info('Promotion completed successfully', {\n skillId: request.skillId,\n duration: new Date(promotedAt).getTime() - new Date(submittedAt).getTime(),\n });\n\n this.emit('promotion-success', result);\n\n return result;\n } catch (error) {\n logger.error('Promotion pipeline error', { error, skillId: request.skillId });\n\n const result: PromotionResult = {\n success: false,\n skillId: request.skillId,\n error: error instanceof Error ? error.message : String(error),\n submittedAt,\n };\n\n this.emit('promotion-failure', result);\n\n return result;\n } finally {\n this.releaseLock(request.skillId);\n }\n }\n\n /**\n * Rollback to previous version\n *\n * SECURITY: Requires ROLLBACK permission (admin only)\n * Rollback is a critical operation that requires admin authentication\n */\n async rollback(\n skillId: string,\n fromVersion: string,\n toVersion: string,\n rolledBackBy: string,\n reason: string\n ): Promise<{ success: boolean; message: string; error?: string }> {\n try {\n // SECURITY: Check authorization - ROLLBACK is admin-only\n this.requirePermission(PromotionOperation.ROLLBACK, skillId);\n\n // SECURITY: Validate that the roller-back matches authenticated user\n if (this.userContext && this.userContext.userId !== rolledBackBy && this.userContext.username !== rolledBackBy) {\n throw new StandardError(\n ErrorCode.VALIDATION_FAILED,\n 'Rollback requester identity does not match authenticated user',\n {\n authenticatedUser: this.userContext.userId,\n requestedRoller: rolledBackBy,\n }\n );\n }\n\n logger.info('Starting rollback', {\n skillId,\n fromVersion,\n toVersion,\n reason,\n rolledBackBy: this.userContext?.userId,\n });\n\n // In a real implementation, you would restore from a backup\n // For now, we just record the audit trail\n await this.recordAudit(skillId, 'rollback', rolledBackBy, {\n fromVersion,\n toVersion,\n reason,\n });\n\n logger.info('Rollback completed', { skillId, toVersion });\n\n return {\n success: true,\n message: `Successfully rolled back ${skillId} from ${fromVersion} to ${toVersion}`,\n };\n } catch (error) {\n logger.error('Rollback failed', { error, skillId });\n return {\n success: false,\n message: 'Rollback failed',\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n /**\n * Get audit trail for a skill\n */\n async getAuditTrail(skillId: string): Promise<AuditEntry[]> {\n try {\n const adapter = this.dbService.getAdapter('sqlite');\n\n const result = await adapter.query(\n `SELECT skill_id AS skillId, action, actor, timestamp, details\n FROM promotion_audit\n WHERE skill_id = ?\n ORDER BY timestamp DESC`,\n [skillId]\n );\n\n return result.rows || [];\n } catch (error) {\n logger.error('Failed to get audit trail', { error, skillId });\n return [];\n }\n }\n\n /**\n * Record promotion in database\n */\n private async recordPromotion(request: PromotionRequest, promotedAt: string): Promise<void> {\n try {\n const adapter = this.dbService.getAdapter('sqlite');\n\n await adapter.query(\n `INSERT INTO promotions (skill_id, from_version, to_version, status, requested_by, reason, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n request.skillId,\n request.fromVersion,\n request.toVersion,\n 'completed',\n request.requestedBy,\n request.reason,\n new Date().toISOString(),\n promotedAt,\n ]\n );\n\n logger.debug('Promotion recorded in database', { skillId: request.skillId });\n } catch (error) {\n logger.error('Failed to record promotion', { error, skillId: request.skillId });\n // Non-fatal: continue even if recording fails\n }\n }\n\n /**\n * Record audit trail entry\n */\n private async recordAudit(\n skillId: string,\n action: string,\n actor: string,\n details: Record<string, any>\n ): Promise<void> {\n try {\n const adapter = this.dbService.getAdapter('sqlite');\n\n await adapter.query(\n `INSERT INTO promotion_audit (skill_id, action, actor, timestamp, details)\n VALUES (?, ?, ?, ?, ?)`,\n [skillId, action, actor, new Date().toISOString(), JSON.stringify(details)]\n );\n\n logger.debug('Audit trail recorded', { skillId, action });\n } catch (error) {\n logger.error('Failed to record audit trail', { error, skillId, action });\n // Non-fatal: continue even if recording fails\n }\n }\n\n /**\n * Check if version is valid semantic version\n */\n private isValidSemanticVersion(version: string): boolean {\n return /^\\d+\\.\\d+\\.\\d+$/.test(version);\n }\n\n /**\n * SECURITY FIX (CVSS 8.6): Execute command with timeout using async spawn\n *\n * VULNERABLE PATTERN (FIXED):\n * - Before: execAsync('bash ' + command) - vulnerable to command injection\n * - After: spawn('bash', [command]) - safe array-based argument passing\n *\n * This prevents shell metacharacter interpretation and command injection attacks.\n * Uses async spawn (not spawnSync) to avoid blocking the event loop.\n * The testScriptPath is validated in validateTestScriptPath() before being passed here.\n *\n * @param command - Command executable (e.g., 'bash', 'node')\n * @param args - Array of arguments (safely escaped, no shell interpretation)\n * @param timeoutMs - Timeout in milliseconds\n * @param options - Spawn options (cwd, env, etc.)\n * @returns Promise with stdout/stderr\n */\n private executeWithTimeout(\n command: string,\n args: string[],\n timeoutMs: number,\n options?: any\n ): Promise<{ stdout: string; stderr: string }> {\n return new Promise((resolve, reject) => {\n let stdoutData = '';\n let stderrData = '';\n let processKilled = false;\n let timeoutHandle: NodeJS.Timeout | null = null;\n\n // Spawn process with array args (no shell interpretation)\n const childProcess: ChildProcess = spawn(command, args, options || {});\n\n // Setup timeout to kill process\n timeoutHandle = setTimeout(() => {\n processKilled = true;\n if (childProcess && !childProcess.killed) {\n childProcess.kill('SIGTERM');\n }\n reject(new Error(`Command execution timeout after ${timeoutMs}ms: ${command} ${args.join(' ')}`));\n }, timeoutMs);\n\n // Collect stdout data\n if (childProcess.stdout) {\n childProcess.stdout.on('data', (data: Buffer) => {\n stdoutData += data.toString();\n });\n }\n\n // Collect stderr data\n if (childProcess.stderr) {\n childProcess.stderr.on('data', (data: Buffer) => {\n stderrData += data.toString();\n });\n }\n\n // Handle process errors (e.g., command not found)\n childProcess.on('error', (error: Error) => {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n if (!processKilled) {\n reject(error);\n }\n });\n\n // Handle process exit\n childProcess.on('close', (code: number | null) => {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n\n // Only process if not already killed by timeout\n if (!processKilled) {\n if (code === 0) {\n resolve({ stdout: stdoutData, stderr: stderrData });\n } else {\n reject(new Error(`Command failed with exit code ${code}: ${stderrData || stdoutData}`));\n }\n }\n });\n });\n }\n}\n\nexport default PromotionPipeline;\n"],"names":["fs","path","promisify","spawn","EventEmitter","StandardError","ErrorCode","createLogger","AuthMiddleware","RBACEnforcer","PromotionOperation","fsRename","rename","fsMkdir","mkdir","fsReadFile","readFile","logger","PromotionPipeline","dbService","stagingDir","productionDir","autoApprovalThreshold","testTimeoutMs","skillLocks","authMiddleware","rbacEnforcer","userContext","config","jwtSecret","autoApprovalConfidenceThreshold","Map","setUserContext","authHeader","sessionId","extractUserContext","info","userId","role","error","warn","getUserContext","isAuthenticated","undefined","ensureAuthenticated","VALIDATION_FAILED","requirePermission","operation","skillId","enforcePermission","acquireLock","has","INTERNAL_ERROR","lockPromise","Promise","resolve","set","setTimeout","delete","releaseLock","validateTestScriptPath","testScriptPath","skillPath","resolvedTestPath","resolvedSkillPath","startsWith","sep","join","includes","existsSync","stats","statSync","isFile","debug","validateStage","request","startTime","Date","now","errors","VALIDATE","push","stage","passed","confidence","duration","skillMdPath","executeScriptPath","mode","some","e","content","readFileSync","frontmatterMatch","match","frontmatter","versionMatch","version","trim","isValidSemanticVersion","nameMatch","name","test","length","Math","max","Error","message","String","testStage","TEST","testsPassed","coverage","validationError","result","executeWithTimeout","cwd","stdout","substring","execError","errMsg","approvalStage","stageResults","APPROVE","s","approved","autoApproved","approvedBy","requiresManualApproval","avgConfidence","reduce","sum","approveManually","approver","reason","username","authenticatedUser","requestedApprover","approvalReason","deployStage","DEPLOY","toVersion","deployedBy","success","recursive","productionPath","backupPath","from","to","moveError","FILE_SYSTEM_ERROR","promote","submittedAt","toISOString","INITIATE","initiatedBy","stages","validation","fromVersion","failedStage","emit","recordAudit","requestedBy","testing","approval","deployment","promotedAt","recordPromotion","getTime","rollback","rolledBackBy","ROLLBACK","requestedRoller","getAuditTrail","adapter","getAdapter","query","rows","action","actor","details","JSON","stringify","command","args","timeoutMs","options","reject","stdoutData","stderrData","processKilled","timeoutHandle","childProcess","killed","kill","on","data","toString","stderr","clearTimeout","code"],"mappings":"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"}
@@ -0,0 +1,394 @@
1
+ /**
2
+ * Promotion Validator
3
+ *
4
+ * Validates skills in staging before promotion to production.
5
+ * Part of Task 1.2: Staging → Production Promotion Workflow
6
+ *
7
+ * Validation checks:
8
+ * - Content integrity (all required files exist)
9
+ * - Schema compliance (frontmatter valid)
10
+ * - Test results (test.sh passes - if exists)
11
+ * - No conflicts with existing production skills
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const validation = await validateStagedSkill('.claude/skills/staging/auth-v2');
16
+ * if (!validation.success) {
17
+ * console.error('Validation failed:', validation.errors);
18
+ * }
19
+ * ```
20
+ */ import * as fs from 'fs';
21
+ import * as path from 'path';
22
+ import { promisify } from 'util';
23
+ import { exec } from 'child_process';
24
+ import { createLogger } from '../lib/logging.js';
25
+ import { fileExists } from '../lib/file-operations.js';
26
+ import { parseFrontmatter } from './skill-validator.js';
27
+ const logger = createLogger('promotion-validator');
28
+ const fsReadFile = promisify(fs.readFile);
29
+ const fsStat = promisify(fs.stat);
30
+ const fsAccess = promisify(fs.access);
31
+ const execPromise = promisify(exec);
32
+ /**
33
+ * Validate a staged skill before promotion
34
+ */ export async function validateStagedSkill(skillPath) {
35
+ const errors = [];
36
+ const warnings = [];
37
+ const checks = {
38
+ contentIntegrity: false,
39
+ schemaCompliance: false,
40
+ testsPassed: false,
41
+ noConflicts: false
42
+ };
43
+ try {
44
+ logger.info('Starting staged skill validation', {
45
+ skillPath
46
+ });
47
+ // Normalize path
48
+ const normalizedPath = path.resolve(skillPath);
49
+ // 1. Check if skill directory exists
50
+ if (!await fileExists(normalizedPath)) {
51
+ errors.push(`Skill directory does not exist: ${normalizedPath}`);
52
+ return {
53
+ success: false,
54
+ errors,
55
+ warnings,
56
+ checks,
57
+ validatedAt: new Date()
58
+ };
59
+ }
60
+ const stats = await fsStat(normalizedPath);
61
+ if (!stats.isDirectory()) {
62
+ errors.push(`Path is not a directory: ${normalizedPath}`);
63
+ return {
64
+ success: false,
65
+ errors,
66
+ warnings,
67
+ checks,
68
+ validatedAt: new Date()
69
+ };
70
+ }
71
+ // 2. Content integrity check
72
+ logger.debug('Checking content integrity', {
73
+ skillPath
74
+ });
75
+ const contentCheck = await checkContentIntegrity(normalizedPath);
76
+ checks.contentIntegrity = contentCheck.success;
77
+ if (!contentCheck.success) {
78
+ errors.push(...contentCheck.errors || []);
79
+ }
80
+ if (contentCheck.warnings) {
81
+ warnings.push(...contentCheck.warnings);
82
+ }
83
+ // 3. Schema compliance check
84
+ logger.debug('Checking schema compliance', {
85
+ skillPath
86
+ });
87
+ const schemaCheck = await checkSchemaCompliance(normalizedPath);
88
+ checks.schemaCompliance = schemaCheck.success;
89
+ if (!schemaCheck.success) {
90
+ errors.push(...schemaCheck.errors || []);
91
+ }
92
+ if (schemaCheck.warnings) {
93
+ warnings.push(...schemaCheck.warnings);
94
+ }
95
+ // 4. Test execution check (if test.sh exists)
96
+ logger.debug('Checking tests', {
97
+ skillPath
98
+ });
99
+ const testCheck = await checkTests(normalizedPath);
100
+ checks.testsPassed = testCheck.success;
101
+ if (!testCheck.success && testCheck.errors) {
102
+ // Test failures are warnings, not hard errors (unless critical)
103
+ if (testCheck.critical) {
104
+ errors.push(...testCheck.errors);
105
+ } else {
106
+ warnings.push(...testCheck.errors);
107
+ }
108
+ }
109
+ if (testCheck.warnings) {
110
+ warnings.push(...testCheck.warnings);
111
+ }
112
+ // 5. Conflict check (production skill doesn't exist or is compatible)
113
+ logger.debug('Checking for conflicts', {
114
+ skillPath
115
+ });
116
+ const conflictCheck = await checkConflicts(normalizedPath);
117
+ checks.noConflicts = conflictCheck.success;
118
+ if (!conflictCheck.success) {
119
+ errors.push(...conflictCheck.errors || []);
120
+ }
121
+ if (conflictCheck.warnings) {
122
+ warnings.push(...conflictCheck.warnings);
123
+ }
124
+ // Determine overall success
125
+ const success = errors.length === 0;
126
+ if (success) {
127
+ logger.info('Validation passed', {
128
+ skillPath,
129
+ warnings: warnings.length
130
+ });
131
+ } else {
132
+ logger.error('Validation failed', {
133
+ skillPath,
134
+ errors: errors.length,
135
+ warnings: warnings.length
136
+ });
137
+ }
138
+ return {
139
+ success,
140
+ errors: errors.length > 0 ? errors : undefined,
141
+ warnings: warnings.length > 0 ? warnings : undefined,
142
+ checks,
143
+ validatedAt: new Date()
144
+ };
145
+ } catch (error) {
146
+ logger.error('Validation error', {
147
+ error,
148
+ skillPath
149
+ });
150
+ return {
151
+ success: false,
152
+ errors: [
153
+ `Validation error: ${error instanceof Error ? error.message : String(error)}`
154
+ ],
155
+ warnings,
156
+ checks,
157
+ validatedAt: new Date()
158
+ };
159
+ }
160
+ }
161
+ /**
162
+ * Check content integrity (all required files exist)
163
+ */ async function checkContentIntegrity(skillPath) {
164
+ const errors = [];
165
+ const warnings = [];
166
+ try {
167
+ // Required files
168
+ const requiredFiles = [
169
+ 'SKILL.md',
170
+ 'execute.sh'
171
+ ];
172
+ for (const file of requiredFiles){
173
+ const filePath = path.join(skillPath, file);
174
+ if (!await fileExists(filePath)) {
175
+ errors.push(`Missing required file: ${file}`);
176
+ } else {
177
+ // Check file is readable
178
+ try {
179
+ await fsAccess(filePath, fs.constants.R_OK);
180
+ } catch {
181
+ errors.push(`File not readable: ${file}`);
182
+ }
183
+ }
184
+ }
185
+ // Optional files (warn if missing)
186
+ const optionalFiles = [
187
+ 'test.sh',
188
+ 'README.md'
189
+ ];
190
+ for (const file of optionalFiles){
191
+ const filePath = path.join(skillPath, file);
192
+ if (!await fileExists(filePath)) {
193
+ warnings.push(`Optional file missing: ${file}`);
194
+ }
195
+ }
196
+ // Check execute.sh is executable
197
+ const executeScript = path.join(skillPath, 'execute.sh');
198
+ if (await fileExists(executeScript)) {
199
+ try {
200
+ const stats = await fsStat(executeScript);
201
+ const isExecutable = (stats.mode & fs.constants.S_IXUSR) !== 0;
202
+ if (!isExecutable) {
203
+ errors.push('execute.sh is not executable (chmod +x required)');
204
+ }
205
+ } catch (error) {
206
+ warnings.push(`Could not check execute.sh permissions: ${error}`);
207
+ }
208
+ }
209
+ return {
210
+ success: errors.length === 0,
211
+ errors: errors.length > 0 ? errors : undefined,
212
+ warnings: warnings.length > 0 ? warnings : undefined
213
+ };
214
+ } catch (error) {
215
+ return {
216
+ success: false,
217
+ errors: [
218
+ `Content integrity check failed: ${error instanceof Error ? error.message : String(error)}`
219
+ ]
220
+ };
221
+ }
222
+ }
223
+ /**
224
+ * Check schema compliance (frontmatter valid)
225
+ */ async function checkSchemaCompliance(skillPath) {
226
+ const errors = [];
227
+ const warnings = [];
228
+ try {
229
+ const skillMdPath = path.join(skillPath, 'SKILL.md');
230
+ if (!await fileExists(skillMdPath)) {
231
+ errors.push('SKILL.md does not exist');
232
+ return {
233
+ success: false,
234
+ errors
235
+ };
236
+ }
237
+ // Parse frontmatter
238
+ const frontmatter = parseFrontmatter(skillPath);
239
+ // Required fields
240
+ const requiredFields = [
241
+ 'name',
242
+ 'description',
243
+ 'version'
244
+ ];
245
+ for (const field of requiredFields){
246
+ if (!frontmatter[field]) {
247
+ errors.push(`Missing required frontmatter field: ${field}`);
248
+ }
249
+ }
250
+ // Validate version format (semantic versioning)
251
+ if (frontmatter.version) {
252
+ const versionRegex = /^\d+\.\d+\.\d+$/;
253
+ if (!versionRegex.test(frontmatter.version)) {
254
+ errors.push(`Invalid version format: ${frontmatter.version} (expected: X.Y.Z)`);
255
+ }
256
+ }
257
+ // Optional fields (warn if missing)
258
+ const optionalFields = [
259
+ 'author',
260
+ 'tags',
261
+ 'dependencies'
262
+ ];
263
+ for (const field of optionalFields){
264
+ if (!frontmatter[field]) {
265
+ warnings.push(`Optional frontmatter field missing: ${field}`);
266
+ }
267
+ }
268
+ // Validate tags (should be array)
269
+ if (frontmatter.tags && !Array.isArray(frontmatter.tags)) {
270
+ warnings.push('Frontmatter tags should be an array');
271
+ }
272
+ return {
273
+ success: errors.length === 0,
274
+ errors: errors.length > 0 ? errors : undefined,
275
+ warnings: warnings.length > 0 ? warnings : undefined
276
+ };
277
+ } catch (error) {
278
+ return {
279
+ success: false,
280
+ errors: [
281
+ `Schema compliance check failed: ${error instanceof Error ? error.message : String(error)}`
282
+ ]
283
+ };
284
+ }
285
+ }
286
+ /**
287
+ * Check test execution (run test.sh if exists)
288
+ */ async function checkTests(skillPath) {
289
+ const errors = [];
290
+ const warnings = [];
291
+ try {
292
+ const testScript = path.join(skillPath, 'test.sh');
293
+ // If test.sh doesn't exist, pass (tests are optional)
294
+ if (!await fileExists(testScript)) {
295
+ warnings.push('No test.sh found (tests are optional)');
296
+ return {
297
+ success: true,
298
+ warnings
299
+ };
300
+ }
301
+ // Check if test.sh is executable
302
+ const stats = await fsStat(testScript);
303
+ const isExecutable = (stats.mode & fs.constants.S_IXUSR) !== 0;
304
+ if (!isExecutable) {
305
+ errors.push('test.sh exists but is not executable');
306
+ return {
307
+ success: false,
308
+ errors,
309
+ critical: true
310
+ };
311
+ }
312
+ // Run tests with 30-second timeout
313
+ logger.debug('Running tests', {
314
+ testScript
315
+ });
316
+ try {
317
+ const { stdout, stderr } = await execPromise(`cd ${skillPath} && ./test.sh`, {
318
+ timeout: 30000,
319
+ maxBuffer: 1024 * 1024
320
+ });
321
+ logger.debug('Tests passed', {
322
+ stdout,
323
+ stderr
324
+ });
325
+ return {
326
+ success: true
327
+ };
328
+ } catch (execError) {
329
+ const error = execError;
330
+ // Test failed
331
+ const errorMsg = `Tests failed (exit code ${error.code || 'unknown'}): ${error.stderr || error.stdout || 'No output'}`;
332
+ errors.push(errorMsg);
333
+ logger.warn('Tests failed', {
334
+ error: errorMsg
335
+ });
336
+ // Test failures are non-critical warnings (allow promotion with --force)
337
+ return {
338
+ success: false,
339
+ errors,
340
+ critical: false
341
+ };
342
+ }
343
+ } catch (error) {
344
+ return {
345
+ success: false,
346
+ errors: [
347
+ `Test check failed: ${error instanceof Error ? error.message : String(error)}`
348
+ ],
349
+ critical: false
350
+ };
351
+ }
352
+ }
353
+ /**
354
+ * Check for conflicts with existing production skills
355
+ */ async function checkConflicts(skillPath) {
356
+ const errors = [];
357
+ const warnings = [];
358
+ try {
359
+ const skillName = path.basename(skillPath);
360
+ const productionPath = path.join('.claude/skills', skillName);
361
+ // Check if production skill already exists
362
+ if (await fileExists(productionPath)) {
363
+ warnings.push(`Production skill already exists: ${skillName} (use --overwrite to replace)`);
364
+ // Check if production skill has a different version
365
+ try {
366
+ const stagingFrontmatter = parseFrontmatter(skillPath);
367
+ const productionFrontmatter = parseFrontmatter(productionPath);
368
+ const stagingVersion = stagingFrontmatter.version;
369
+ const productionVersion = productionFrontmatter.version;
370
+ if (stagingVersion === productionVersion) {
371
+ warnings.push(`Both staging and production have version ${stagingVersion}`);
372
+ } else {
373
+ warnings.push(`Version mismatch: staging=${stagingVersion}, production=${productionVersion}`);
374
+ }
375
+ } catch (error) {
376
+ warnings.push('Could not compare versions (frontmatter parse error)');
377
+ }
378
+ }
379
+ return {
380
+ success: errors.length === 0,
381
+ errors: errors.length > 0 ? errors : undefined,
382
+ warnings: warnings.length > 0 ? warnings : undefined
383
+ };
384
+ } catch (error) {
385
+ return {
386
+ success: false,
387
+ errors: [
388
+ `Conflict check failed: ${error instanceof Error ? error.message : String(error)}`
389
+ ]
390
+ };
391
+ }
392
+ }
393
+
394
+ //# sourceMappingURL=promotion-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/services/promotion-validator.ts"],"sourcesContent":["/**\r\n * Promotion Validator\r\n *\r\n * Validates skills in staging before promotion to production.\r\n * Part of Task 1.2: Staging → Production Promotion Workflow\r\n *\r\n * Validation checks:\r\n * - Content integrity (all required files exist)\r\n * - Schema compliance (frontmatter valid)\r\n * - Test results (test.sh passes - if exists)\r\n * - No conflicts with existing production skills\r\n *\r\n * @example\r\n * ```typescript\r\n * const validation = await validateStagedSkill('.claude/skills/staging/auth-v2');\r\n * if (!validation.success) {\r\n * console.error('Validation failed:', validation.errors);\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 { StandardError, ErrorCode } from '../lib/errors.js';\r\nimport { createLogger } from '../lib/logging.js';\r\nimport { fileExists } from '../lib/file-operations.js';\r\nimport { validateSkill, parseFrontmatter } from './skill-validator.js';\r\n\r\nconst logger = createLogger('promotion-validator');\r\n\r\nconst fsReadFile = promisify(fs.readFile);\r\nconst fsStat = promisify(fs.stat);\r\nconst fsAccess = promisify(fs.access);\r\nconst execPromise = promisify(exec);\r\n\r\n/**\r\n * Validation result\r\n */\r\nexport interface ValidationResult {\r\n /** Whether validation passed */\r\n success: boolean;\r\n /** Validation errors (if any) */\r\n errors?: string[];\r\n /** Validation warnings (non-fatal) */\r\n warnings?: string[];\r\n /** Detailed check results */\r\n checks?: {\r\n contentIntegrity: boolean;\r\n schemaCompliance: boolean;\r\n testsPassed: boolean;\r\n noConflicts: boolean;\r\n };\r\n /** Validation timestamp */\r\n validatedAt?: Date;\r\n}\r\n\r\n/**\r\n * Validate a staged skill before promotion\r\n */\r\nexport async function validateStagedSkill(skillPath: string): Promise<ValidationResult> {\r\n const errors: string[] = [];\r\n const warnings: string[] = [];\r\n const checks = {\r\n contentIntegrity: false,\r\n schemaCompliance: false,\r\n testsPassed: false,\r\n noConflicts: false,\r\n };\r\n\r\n try {\r\n logger.info('Starting staged skill validation', { skillPath });\r\n\r\n // Normalize path\r\n const normalizedPath = path.resolve(skillPath);\r\n\r\n // 1. Check if skill directory exists\r\n if (!(await fileExists(normalizedPath))) {\r\n errors.push(`Skill directory does not exist: ${normalizedPath}`);\r\n return {\r\n success: false,\r\n errors,\r\n warnings,\r\n checks,\r\n validatedAt: new Date(),\r\n };\r\n }\r\n\r\n const stats = await fsStat(normalizedPath);\r\n if (!stats.isDirectory()) {\r\n errors.push(`Path is not a directory: ${normalizedPath}`);\r\n return {\r\n success: false,\r\n errors,\r\n warnings,\r\n checks,\r\n validatedAt: new Date(),\r\n };\r\n }\r\n\r\n // 2. Content integrity check\r\n logger.debug('Checking content integrity', { skillPath });\r\n const contentCheck = await checkContentIntegrity(normalizedPath);\r\n checks.contentIntegrity = contentCheck.success;\r\n if (!contentCheck.success) {\r\n errors.push(...(contentCheck.errors || []));\r\n }\r\n if (contentCheck.warnings) {\r\n warnings.push(...contentCheck.warnings);\r\n }\r\n\r\n // 3. Schema compliance check\r\n logger.debug('Checking schema compliance', { skillPath });\r\n const schemaCheck = await checkSchemaCompliance(normalizedPath);\r\n checks.schemaCompliance = schemaCheck.success;\r\n if (!schemaCheck.success) {\r\n errors.push(...(schemaCheck.errors || []));\r\n }\r\n if (schemaCheck.warnings) {\r\n warnings.push(...schemaCheck.warnings);\r\n }\r\n\r\n // 4. Test execution check (if test.sh exists)\r\n logger.debug('Checking tests', { skillPath });\r\n const testCheck = await checkTests(normalizedPath);\r\n checks.testsPassed = testCheck.success;\r\n if (!testCheck.success && testCheck.errors) {\r\n // Test failures are warnings, not hard errors (unless critical)\r\n if (testCheck.critical) {\r\n errors.push(...testCheck.errors);\r\n } else {\r\n warnings.push(...testCheck.errors);\r\n }\r\n }\r\n if (testCheck.warnings) {\r\n warnings.push(...testCheck.warnings);\r\n }\r\n\r\n // 5. Conflict check (production skill doesn't exist or is compatible)\r\n logger.debug('Checking for conflicts', { skillPath });\r\n const conflictCheck = await checkConflicts(normalizedPath);\r\n checks.noConflicts = conflictCheck.success;\r\n if (!conflictCheck.success) {\r\n errors.push(...(conflictCheck.errors || []));\r\n }\r\n if (conflictCheck.warnings) {\r\n warnings.push(...conflictCheck.warnings);\r\n }\r\n\r\n // Determine overall success\r\n const success = errors.length === 0;\r\n\r\n if (success) {\r\n logger.info('Validation passed', { skillPath, warnings: warnings.length });\r\n } else {\r\n logger.error('Validation failed', { skillPath, errors: errors.length, warnings: warnings.length });\r\n }\r\n\r\n return {\r\n success,\r\n errors: errors.length > 0 ? errors : undefined,\r\n warnings: warnings.length > 0 ? warnings : undefined,\r\n checks,\r\n validatedAt: new Date(),\r\n };\r\n } catch (error) {\r\n logger.error('Validation error', { error, skillPath });\r\n return {\r\n success: false,\r\n errors: [`Validation error: ${error instanceof Error ? error.message : String(error)}`],\r\n warnings,\r\n checks,\r\n validatedAt: new Date(),\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Check content integrity (all required files exist)\r\n */\r\nasync function checkContentIntegrity(skillPath: string): Promise<ValidationResult> {\r\n const errors: string[] = [];\r\n const warnings: string[] = [];\r\n\r\n try {\r\n // Required files\r\n const requiredFiles = ['SKILL.md', 'execute.sh'];\r\n\r\n for (const file of requiredFiles) {\r\n const filePath = path.join(skillPath, file);\r\n if (!(await fileExists(filePath))) {\r\n errors.push(`Missing required file: ${file}`);\r\n } else {\r\n // Check file is readable\r\n try {\r\n await fsAccess(filePath, fs.constants.R_OK);\r\n } catch {\r\n errors.push(`File not readable: ${file}`);\r\n }\r\n }\r\n }\r\n\r\n // Optional files (warn if missing)\r\n const optionalFiles = ['test.sh', 'README.md'];\r\n for (const file of optionalFiles) {\r\n const filePath = path.join(skillPath, file);\r\n if (!(await fileExists(filePath))) {\r\n warnings.push(`Optional file missing: ${file}`);\r\n }\r\n }\r\n\r\n // Check execute.sh is executable\r\n const executeScript = path.join(skillPath, 'execute.sh');\r\n if (await fileExists(executeScript)) {\r\n try {\r\n const stats = await fsStat(executeScript);\r\n const isExecutable = (stats.mode & fs.constants.S_IXUSR) !== 0;\r\n if (!isExecutable) {\r\n errors.push('execute.sh is not executable (chmod +x required)');\r\n }\r\n } catch (error) {\r\n warnings.push(`Could not check execute.sh permissions: ${error}`);\r\n }\r\n }\r\n\r\n return {\r\n success: errors.length === 0,\r\n errors: errors.length > 0 ? errors : undefined,\r\n warnings: warnings.length > 0 ? warnings : undefined,\r\n };\r\n } catch (error) {\r\n return {\r\n success: false,\r\n errors: [`Content integrity check failed: ${error instanceof Error ? error.message : String(error)}`],\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Check schema compliance (frontmatter valid)\r\n */\r\nasync function checkSchemaCompliance(skillPath: string): Promise<ValidationResult> {\r\n const errors: string[] = [];\r\n const warnings: string[] = [];\r\n\r\n try {\r\n const skillMdPath = path.join(skillPath, 'SKILL.md');\r\n\r\n if (!(await fileExists(skillMdPath))) {\r\n errors.push('SKILL.md does not exist');\r\n return { success: false, errors };\r\n }\r\n\r\n // Parse frontmatter\r\n const frontmatter = parseFrontmatter(skillPath);\r\n\r\n // Required fields\r\n const requiredFields = ['name', 'description', 'version'];\r\n for (const field of requiredFields) {\r\n if (!frontmatter[field]) {\r\n errors.push(`Missing required frontmatter field: ${field}`);\r\n }\r\n }\r\n\r\n // Validate version format (semantic versioning)\r\n if (frontmatter.version) {\r\n const versionRegex = /^\\d+\\.\\d+\\.\\d+$/;\r\n if (!versionRegex.test(frontmatter.version)) {\r\n errors.push(`Invalid version format: ${frontmatter.version} (expected: X.Y.Z)`);\r\n }\r\n }\r\n\r\n // Optional fields (warn if missing)\r\n const optionalFields = ['author', 'tags', 'dependencies'];\r\n for (const field of optionalFields) {\r\n if (!frontmatter[field]) {\r\n warnings.push(`Optional frontmatter field missing: ${field}`);\r\n }\r\n }\r\n\r\n // Validate tags (should be array)\r\n if (frontmatter.tags && !Array.isArray(frontmatter.tags)) {\r\n warnings.push('Frontmatter tags should be an array');\r\n }\r\n\r\n return {\r\n success: errors.length === 0,\r\n errors: errors.length > 0 ? errors : undefined,\r\n warnings: warnings.length > 0 ? warnings : undefined,\r\n };\r\n } catch (error) {\r\n return {\r\n success: false,\r\n errors: [`Schema compliance check failed: ${error instanceof Error ? error.message : String(error)}`],\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Check test execution (run test.sh if exists)\r\n */\r\nasync function checkTests(skillPath: string): Promise<ValidationResult & { critical?: boolean }> {\r\n const errors: string[] = [];\r\n const warnings: string[] = [];\r\n\r\n try {\r\n const testScript = path.join(skillPath, 'test.sh');\r\n\r\n // If test.sh doesn't exist, pass (tests are optional)\r\n if (!(await fileExists(testScript))) {\r\n warnings.push('No test.sh found (tests are optional)');\r\n return {\r\n success: true,\r\n warnings,\r\n };\r\n }\r\n\r\n // Check if test.sh is executable\r\n const stats = await fsStat(testScript);\r\n const isExecutable = (stats.mode & fs.constants.S_IXUSR) !== 0;\r\n if (!isExecutable) {\r\n errors.push('test.sh exists but is not executable');\r\n return {\r\n success: false,\r\n errors,\r\n critical: true,\r\n };\r\n }\r\n\r\n // Run tests with 30-second timeout\r\n logger.debug('Running tests', { testScript });\r\n try {\r\n const { stdout, stderr } = await execPromise(`cd ${skillPath} && ./test.sh`, {\r\n timeout: 30000,\r\n maxBuffer: 1024 * 1024, // 1MB\r\n });\r\n\r\n logger.debug('Tests passed', { stdout, stderr });\r\n return {\r\n success: true,\r\n };\r\n } catch (execError: unknown) {\r\n const error = execError as { code?: number; stdout?: string; stderr?: string };\r\n // Test failed\r\n const errorMsg = `Tests failed (exit code ${error.code || 'unknown'}): ${error.stderr || error.stdout || 'No output'}`;\r\n errors.push(errorMsg);\r\n logger.warn('Tests failed', { error: errorMsg });\r\n\r\n // Test failures are non-critical warnings (allow promotion with --force)\r\n return {\r\n success: false,\r\n errors,\r\n critical: false,\r\n };\r\n }\r\n } catch (error) {\r\n return {\r\n success: false,\r\n errors: [`Test check failed: ${error instanceof Error ? error.message : String(error)}`],\r\n critical: false,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Check for conflicts with existing production skills\r\n */\r\nasync function checkConflicts(skillPath: string): Promise<ValidationResult> {\r\n const errors: string[] = [];\r\n const warnings: string[] = [];\r\n\r\n try {\r\n const skillName = path.basename(skillPath);\r\n const productionPath = path.join('.claude/skills', skillName);\r\n\r\n // Check if production skill already exists\r\n if (await fileExists(productionPath)) {\r\n warnings.push(`Production skill already exists: ${skillName} (use --overwrite to replace)`);\r\n\r\n // Check if production skill has a different version\r\n try {\r\n const stagingFrontmatter = parseFrontmatter(skillPath);\r\n const productionFrontmatter = parseFrontmatter(productionPath);\r\n\r\n const stagingVersion = stagingFrontmatter.version;\r\n const productionVersion = productionFrontmatter.version;\r\n\r\n if (stagingVersion === productionVersion) {\r\n warnings.push(`Both staging and production have version ${stagingVersion}`);\r\n } else {\r\n warnings.push(`Version mismatch: staging=${stagingVersion}, production=${productionVersion}`);\r\n }\r\n } catch (error) {\r\n warnings.push('Could not compare versions (frontmatter parse error)');\r\n }\r\n }\r\n\r\n return {\r\n success: errors.length === 0,\r\n errors: errors.length > 0 ? errors : undefined,\r\n warnings: warnings.length > 0 ? warnings : undefined,\r\n };\r\n } catch (error) {\r\n return {\r\n success: false,\r\n errors: [`Conflict check failed: ${error instanceof Error ? error.message : String(error)}`],\r\n };\r\n }\r\n}\r\n"],"names":["fs","path","promisify","exec","createLogger","fileExists","parseFrontmatter","logger","fsReadFile","readFile","fsStat","stat","fsAccess","access","execPromise","validateStagedSkill","skillPath","errors","warnings","checks","contentIntegrity","schemaCompliance","testsPassed","noConflicts","info","normalizedPath","resolve","push","success","validatedAt","Date","stats","isDirectory","debug","contentCheck","checkContentIntegrity","schemaCheck","checkSchemaCompliance","testCheck","checkTests","critical","conflictCheck","checkConflicts","length","error","undefined","Error","message","String","requiredFiles","file","filePath","join","constants","R_OK","optionalFiles","executeScript","isExecutable","mode","S_IXUSR","skillMdPath","frontmatter","requiredFields","field","version","versionRegex","test","optionalFields","tags","Array","isArray","testScript","stdout","stderr","timeout","maxBuffer","execError","errorMsg","code","warn","skillName","basename","productionPath","stagingFrontmatter","productionFrontmatter","stagingVersion","productionVersion"],"mappings":"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"}