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,454 @@
1
+ /**
2
+ * Skill Validator Service
3
+ *
4
+ * Validates skill content, schema compliance, and deployment readiness.
5
+ * Part of Task 1.1: Automated Skill Deployment Pipeline
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const result = await validateSkill(dbService, '/path/to/skill');
10
+ * if (!result.valid) {
11
+ * console.error('Validation failed:', result.errors);
12
+ * }
13
+ * ```
14
+ */ import * as fs from 'fs';
15
+ import * as path from 'path';
16
+ import { StandardError, ErrorCode } from '../lib/errors.js';
17
+ import { createLogger } from '../lib/logging.js';
18
+ import { validateVersion } from './skill-versioning.js';
19
+ const logger = createLogger('skill-validator');
20
+ /**
21
+ * Parse frontmatter from SKILL.md file
22
+ *
23
+ * @param skillPath - Path to skill directory
24
+ * @returns Parsed frontmatter object
25
+ * @throws StandardError if frontmatter is invalid or missing
26
+ */ export function parseFrontmatter(skillPath) {
27
+ const skillMdPath = path.join(skillPath, 'SKILL.md');
28
+ if (!fs.existsSync(skillMdPath)) {
29
+ throw new StandardError(ErrorCode.FILE_NOT_FOUND, `SKILL.md not found in skill directory: ${skillPath}`, {
30
+ skillPath,
31
+ expectedFile: 'SKILL.md'
32
+ });
33
+ }
34
+ const content = fs.readFileSync(skillMdPath, 'utf-8');
35
+ // Extract frontmatter between --- markers
36
+ const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---/;
37
+ const match = content.match(frontmatterRegex);
38
+ if (!match) {
39
+ throw new StandardError(ErrorCode.PARSE_ERROR, 'No frontmatter found in SKILL.md', {
40
+ skillPath,
41
+ file: skillMdPath
42
+ });
43
+ }
44
+ try {
45
+ // Parse YAML-like frontmatter (simple key: value format)
46
+ const frontmatterText = match[1];
47
+ const lines = frontmatterText.split('\n').filter((line)=>line.trim());
48
+ const frontmatter = {};
49
+ for (const line of lines){
50
+ const colonIndex = line.indexOf(':');
51
+ if (colonIndex === -1) continue;
52
+ const key = line.substring(0, colonIndex).trim();
53
+ let value = line.substring(colonIndex + 1).trim();
54
+ // Parse arrays (format: [item1, item2, item3])
55
+ if (value.startsWith('[') && value.endsWith(']')) {
56
+ value = value.substring(1, value.length - 1).split(',').map((v)=>v.trim()).filter((v)=>v);
57
+ }
58
+ frontmatter[key] = value;
59
+ }
60
+ // Validate required fields
61
+ if (!frontmatter.name || typeof frontmatter.name !== 'string') {
62
+ throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Frontmatter missing required field: name', {
63
+ skillPath,
64
+ frontmatter
65
+ });
66
+ }
67
+ if (!frontmatter.version || typeof frontmatter.version !== 'string') {
68
+ throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Frontmatter missing required field: version', {
69
+ skillPath,
70
+ frontmatter
71
+ });
72
+ }
73
+ return frontmatter;
74
+ } catch (error) {
75
+ if (error instanceof StandardError) {
76
+ throw error;
77
+ }
78
+ throw new StandardError(ErrorCode.PARSE_ERROR, `Failed to parse frontmatter in SKILL.md: ${error.message}`, {
79
+ skillPath,
80
+ file: skillMdPath
81
+ }, error);
82
+ }
83
+ }
84
+ /**
85
+ * Validate skill content path exists and has required files
86
+ *
87
+ * @param skillPath - Path to skill directory
88
+ * @returns Validation errors (empty if valid)
89
+ */ export function validateContentPath(skillPath) {
90
+ const errors = [];
91
+ // Check if directory exists
92
+ if (!fs.existsSync(skillPath)) {
93
+ errors.push({
94
+ code: 'CONTENT_PATH_NOT_FOUND',
95
+ message: `Skill directory not found: ${skillPath}`,
96
+ context: {
97
+ skillPath
98
+ }
99
+ });
100
+ return errors;
101
+ }
102
+ // Check if it's a directory
103
+ const stats = fs.statSync(skillPath);
104
+ if (!stats.isDirectory()) {
105
+ errors.push({
106
+ code: 'CONTENT_PATH_NOT_DIRECTORY',
107
+ message: `Skill path is not a directory: ${skillPath}`,
108
+ context: {
109
+ skillPath
110
+ }
111
+ });
112
+ return errors;
113
+ }
114
+ // Check for required files
115
+ const requiredFiles = [
116
+ 'SKILL.md',
117
+ 'execute.sh'
118
+ ];
119
+ for (const file of requiredFiles){
120
+ const filePath = path.join(skillPath, file);
121
+ if (!fs.existsSync(filePath)) {
122
+ errors.push({
123
+ code: 'REQUIRED_FILE_MISSING',
124
+ message: `Required file missing: ${file}`,
125
+ context: {
126
+ skillPath,
127
+ file,
128
+ expectedPath: filePath
129
+ }
130
+ });
131
+ }
132
+ }
133
+ return errors;
134
+ }
135
+ /**
136
+ * Validate execute.sh is executable
137
+ *
138
+ * @param skillPath - Path to skill directory
139
+ * @returns Validation errors (empty if valid)
140
+ */ export function validateExecuteScript(skillPath) {
141
+ const errors = [];
142
+ const executePath = path.join(skillPath, 'execute.sh');
143
+ if (!fs.existsSync(executePath)) {
144
+ // Already caught by validateContentPath
145
+ return errors;
146
+ }
147
+ try {
148
+ const stats = fs.statSync(executePath);
149
+ // Check if file has execute permission (any execute bit set)
150
+ const isExecutable = (stats.mode & 0o111) !== 0;
151
+ if (!isExecutable) {
152
+ errors.push({
153
+ code: 'EXECUTE_SCRIPT_NOT_EXECUTABLE',
154
+ message: 'execute.sh is not executable',
155
+ context: {
156
+ skillPath,
157
+ file: executePath,
158
+ mode: stats.mode.toString(8)
159
+ }
160
+ });
161
+ }
162
+ } catch (error) {
163
+ errors.push({
164
+ code: 'EXECUTE_SCRIPT_CHECK_FAILED',
165
+ message: `Failed to check execute.sh permissions: ${error.message}`,
166
+ context: {
167
+ skillPath,
168
+ file: executePath
169
+ }
170
+ });
171
+ }
172
+ return errors;
173
+ }
174
+ /**
175
+ * Validate skill schema compliance (frontmatter structure)
176
+ *
177
+ * @param skillPath - Path to skill directory
178
+ * @returns Validation errors (empty if valid)
179
+ */ export function validateSchemaCompliance(skillPath) {
180
+ const errors = [];
181
+ try {
182
+ const frontmatter = parseFrontmatter(skillPath);
183
+ // Validate version format
184
+ if (!validateVersion(frontmatter.version)) {
185
+ errors.push({
186
+ code: 'INVALID_VERSION_FORMAT',
187
+ message: `Invalid semantic version format: ${frontmatter.version}`,
188
+ context: {
189
+ skillPath,
190
+ version: frontmatter.version,
191
+ expectedFormat: 'x.y.z'
192
+ }
193
+ });
194
+ }
195
+ // Validate name format (alphanumeric, hyphens, underscores only)
196
+ const nameRegex = /^[a-zA-Z0-9_-]+$/;
197
+ if (!nameRegex.test(frontmatter.name)) {
198
+ errors.push({
199
+ code: 'INVALID_NAME_FORMAT',
200
+ message: `Invalid skill name format: ${frontmatter.name}`,
201
+ context: {
202
+ skillPath,
203
+ name: frontmatter.name,
204
+ expectedFormat: 'alphanumeric, hyphens, and underscores only'
205
+ }
206
+ });
207
+ }
208
+ } catch (error) {
209
+ if (error instanceof StandardError) {
210
+ errors.push({
211
+ code: error.code,
212
+ message: error.message,
213
+ context: error.context
214
+ });
215
+ } else {
216
+ errors.push({
217
+ code: 'SCHEMA_VALIDATION_FAILED',
218
+ message: `Schema validation failed: ${error.message}`,
219
+ context: {
220
+ skillPath
221
+ }
222
+ });
223
+ }
224
+ }
225
+ return errors;
226
+ }
227
+ /**
228
+ * Check if skill name is unique (no existing skill with same name)
229
+ *
230
+ * @param dbService - Database service instance
231
+ * @param skillName - Name of the skill to check
232
+ * @param excludeSkillId - Optional skill ID to exclude from uniqueness check (for updates)
233
+ * @returns Validation errors (empty if unique)
234
+ */ export async function validateNameUniqueness(dbService, skillName, excludeSkillId) {
235
+ const errors = [];
236
+ try {
237
+ const adapter = dbService.getAdapter('sqlite');
238
+ let query = 'SELECT id, name FROM skills WHERE name = ?';
239
+ const params = [
240
+ skillName
241
+ ];
242
+ if (excludeSkillId) {
243
+ query += ' AND id != ?';
244
+ params.push(excludeSkillId);
245
+ }
246
+ const result = await adapter.query(query, params);
247
+ if (result.rows && result.rows.length > 0) {
248
+ errors.push({
249
+ code: 'NAME_NOT_UNIQUE',
250
+ message: `Skill name already exists: ${skillName}`,
251
+ context: {
252
+ skillName,
253
+ existingSkillId: result.rows[0].id
254
+ }
255
+ });
256
+ }
257
+ } catch (error) {
258
+ errors.push({
259
+ code: 'NAME_UNIQUENESS_CHECK_FAILED',
260
+ message: `Failed to check name uniqueness: ${error.message}`,
261
+ context: {
262
+ skillName
263
+ }
264
+ });
265
+ }
266
+ return errors;
267
+ }
268
+ /**
269
+ * Check for version conflicts (version already exists for this skill)
270
+ *
271
+ * @param dbService - Database service instance
272
+ * @param skillName - Name of the skill
273
+ * @param version - Version to check
274
+ * @returns Validation errors (empty if no conflict)
275
+ */ export async function validateVersionConflict(dbService, skillName, version) {
276
+ const errors = [];
277
+ try {
278
+ const adapter = dbService.getAdapter('sqlite');
279
+ const result = await adapter.query('SELECT id, version FROM skills WHERE name = ? AND version = ?', [
280
+ skillName,
281
+ version
282
+ ]);
283
+ if (result.rows && result.rows.length > 0) {
284
+ errors.push({
285
+ code: 'VERSION_CONFLICT',
286
+ message: `Version ${version} already exists for skill: ${skillName}`,
287
+ context: {
288
+ skillName,
289
+ version,
290
+ existingSkillId: result.rows[0].id
291
+ }
292
+ });
293
+ }
294
+ } catch (error) {
295
+ errors.push({
296
+ code: 'VERSION_CONFLICT_CHECK_FAILED',
297
+ message: `Failed to check version conflict: ${error.message}`,
298
+ context: {
299
+ skillName,
300
+ version
301
+ }
302
+ });
303
+ }
304
+ return errors;
305
+ }
306
+ /**
307
+ * Validate tests exist and pass (optional check)
308
+ *
309
+ * @param skillPath - Path to skill directory
310
+ * @returns Validation warnings (not errors, as tests are optional)
311
+ */ export function validateTests(skillPath) {
312
+ const warnings = [];
313
+ const testPath = path.join(skillPath, 'test.sh');
314
+ if (!fs.existsSync(testPath)) {
315
+ warnings.push({
316
+ code: 'TESTS_NOT_FOUND',
317
+ message: 'No test.sh found (tests are recommended but optional)',
318
+ context: {
319
+ skillPath,
320
+ expectedFile: testPath
321
+ }
322
+ });
323
+ return warnings;
324
+ }
325
+ // Check if test.sh is executable
326
+ try {
327
+ const stats = fs.statSync(testPath);
328
+ const isExecutable = (stats.mode & 0o111) !== 0;
329
+ if (!isExecutable) {
330
+ warnings.push({
331
+ code: 'TEST_SCRIPT_NOT_EXECUTABLE',
332
+ message: 'test.sh exists but is not executable',
333
+ context: {
334
+ skillPath,
335
+ file: testPath
336
+ }
337
+ });
338
+ }
339
+ } catch (error) {
340
+ warnings.push({
341
+ code: 'TEST_SCRIPT_CHECK_FAILED',
342
+ message: `Failed to check test.sh: ${error.message}`,
343
+ context: {
344
+ skillPath,
345
+ file: testPath
346
+ }
347
+ });
348
+ }
349
+ return warnings;
350
+ }
351
+ /**
352
+ * Comprehensive skill validation
353
+ *
354
+ * Runs all validation checks and returns aggregated results.
355
+ *
356
+ * @param dbService - Database service instance
357
+ * @param skillPath - Path to skill directory
358
+ * @param excludeSkillId - Optional skill ID to exclude from uniqueness check
359
+ * @returns Validation result with all errors and warnings
360
+ */ export async function validateSkill(dbService, skillPath, excludeSkillId) {
361
+ logger.info('Starting skill validation', {
362
+ skillPath
363
+ });
364
+ const errors = [];
365
+ const warnings = [];
366
+ let metadata = {};
367
+ // 1. Validate content path exists
368
+ const contentPathErrors = validateContentPath(skillPath);
369
+ errors.push(...contentPathErrors);
370
+ // If content path is invalid, stop here
371
+ if (contentPathErrors.length > 0) {
372
+ logger.warn('Skill validation failed: content path invalid', {
373
+ skillPath,
374
+ errorCount: errors.length
375
+ });
376
+ return {
377
+ valid: false,
378
+ errors,
379
+ warnings
380
+ };
381
+ }
382
+ // 2. Validate schema compliance
383
+ const schemaErrors = validateSchemaCompliance(skillPath);
384
+ errors.push(...schemaErrors);
385
+ // If schema is invalid, stop here
386
+ if (schemaErrors.length > 0) {
387
+ logger.warn('Skill validation failed: schema invalid', {
388
+ skillPath,
389
+ errorCount: errors.length
390
+ });
391
+ return {
392
+ valid: false,
393
+ errors,
394
+ warnings
395
+ };
396
+ }
397
+ // Parse frontmatter for subsequent checks
398
+ let frontmatter;
399
+ try {
400
+ frontmatter = parseFrontmatter(skillPath);
401
+ metadata = {
402
+ skillName: frontmatter.name,
403
+ version: frontmatter.version,
404
+ contentPath: skillPath
405
+ };
406
+ } catch (error) {
407
+ // Already handled in schema validation
408
+ logger.warn('Skill validation failed: frontmatter parsing error', {
409
+ skillPath,
410
+ error: error.message
411
+ });
412
+ return {
413
+ valid: false,
414
+ errors,
415
+ warnings,
416
+ metadata
417
+ };
418
+ }
419
+ // 3. Validate execute.sh is executable
420
+ const executeErrors = validateExecuteScript(skillPath);
421
+ errors.push(...executeErrors);
422
+ // 4. Validate name uniqueness
423
+ const nameErrors = await validateNameUniqueness(dbService, frontmatter.name, excludeSkillId);
424
+ errors.push(...nameErrors);
425
+ // 5. Validate version conflict
426
+ const versionErrors = await validateVersionConflict(dbService, frontmatter.name, frontmatter.version);
427
+ errors.push(...versionErrors);
428
+ // 6. Validate tests (warnings only)
429
+ const testWarnings = validateTests(skillPath);
430
+ warnings.push(...testWarnings);
431
+ const valid = errors.length === 0;
432
+ if (valid) {
433
+ logger.info('Skill validation passed', {
434
+ skillPath,
435
+ skillName: frontmatter.name,
436
+ version: frontmatter.version,
437
+ warningCount: warnings.length
438
+ });
439
+ } else {
440
+ logger.warn('Skill validation failed', {
441
+ skillPath,
442
+ errorCount: errors.length,
443
+ warningCount: warnings.length
444
+ });
445
+ }
446
+ return {
447
+ valid,
448
+ errors,
449
+ warnings,
450
+ metadata
451
+ };
452
+ }
453
+
454
+ //# sourceMappingURL=skill-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/services/skill-validator.ts"],"sourcesContent":["/**\r\n * Skill Validator Service\r\n *\r\n * Validates skill content, schema compliance, and deployment readiness.\r\n * Part of Task 1.1: Automated Skill Deployment Pipeline\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await validateSkill(dbService, '/path/to/skill');\r\n * if (!result.valid) {\r\n * console.error('Validation failed:', result.errors);\r\n * }\r\n * ```\r\n */\r\n\r\nimport * as fs from 'fs';\r\nimport * as path from 'path';\r\nimport { DatabaseService } from '../lib/database-service.js';\r\nimport { StandardError, ErrorCode } from '../lib/errors.js';\r\nimport { createLogger } from '../lib/logging.js';\r\nimport { validateVersion } from './skill-versioning.js';\r\n\r\nconst logger = createLogger('skill-validator');\r\n\r\n/**\r\n * Validation error detail\r\n */\r\nexport interface ValidationError {\r\n code: string;\r\n message: string;\r\n context?: Record<string, any>;\r\n}\r\n\r\n/**\r\n * Skill validation result\r\n */\r\nexport interface ValidationResult {\r\n valid: boolean;\r\n errors: ValidationError[];\r\n warnings: ValidationError[];\r\n metadata?: {\r\n skillName?: string;\r\n version?: string;\r\n contentPath?: string;\r\n };\r\n}\r\n\r\n/**\r\n * Skill frontmatter schema (parsed from SKILL.md)\r\n */\r\nexport interface SkillFrontmatter {\r\n name: string;\r\n version: string;\r\n description?: string;\r\n author?: string;\r\n dependencies?: string[];\r\n tags?: string[];\r\n [key: string]: any;\r\n}\r\n\r\n/**\r\n * Parse frontmatter from SKILL.md file\r\n *\r\n * @param skillPath - Path to skill directory\r\n * @returns Parsed frontmatter object\r\n * @throws StandardError if frontmatter is invalid or missing\r\n */\r\nexport function parseFrontmatter(skillPath: string): SkillFrontmatter {\r\n const skillMdPath = path.join(skillPath, 'SKILL.md');\r\n\r\n if (!fs.existsSync(skillMdPath)) {\r\n throw new StandardError(\r\n ErrorCode.FILE_NOT_FOUND,\r\n `SKILL.md not found in skill directory: ${skillPath}`,\r\n { skillPath, expectedFile: 'SKILL.md' }\r\n );\r\n }\r\n\r\n const content = fs.readFileSync(skillMdPath, 'utf-8');\r\n\r\n // Extract frontmatter between --- markers\r\n const frontmatterRegex = /^---\\s*\\n([\\s\\S]*?)\\n---/;\r\n const match = content.match(frontmatterRegex);\r\n\r\n if (!match) {\r\n throw new StandardError(\r\n ErrorCode.PARSE_ERROR,\r\n 'No frontmatter found in SKILL.md',\r\n { skillPath, file: skillMdPath }\r\n );\r\n }\r\n\r\n try {\r\n // Parse YAML-like frontmatter (simple key: value format)\r\n const frontmatterText = match[1];\r\n const lines = frontmatterText.split('\\n').filter(line => line.trim());\r\n const frontmatter: any = {};\r\n\r\n for (const line of lines) {\r\n const colonIndex = line.indexOf(':');\r\n if (colonIndex === -1) continue;\r\n\r\n const key = line.substring(0, colonIndex).trim();\r\n let value: any = line.substring(colonIndex + 1).trim();\r\n\r\n // Parse arrays (format: [item1, item2, item3])\r\n if (value.startsWith('[') && value.endsWith(']')) {\r\n value = value\r\n .substring(1, value.length - 1)\r\n .split(',')\r\n .map(v => v.trim())\r\n .filter(v => v);\r\n }\r\n\r\n frontmatter[key] = value;\r\n }\r\n\r\n // Validate required fields\r\n if (!frontmatter.name || typeof frontmatter.name !== 'string') {\r\n throw new StandardError(\r\n ErrorCode.VALIDATION_FAILED,\r\n 'Frontmatter missing required field: name',\r\n { skillPath, frontmatter }\r\n );\r\n }\r\n\r\n if (!frontmatter.version || typeof frontmatter.version !== 'string') {\r\n throw new StandardError(\r\n ErrorCode.VALIDATION_FAILED,\r\n 'Frontmatter missing required field: version',\r\n { skillPath, frontmatter }\r\n );\r\n }\r\n\r\n return frontmatter as SkillFrontmatter;\r\n } catch (error) {\r\n if (error instanceof StandardError) {\r\n throw error;\r\n }\r\n throw new StandardError(\r\n ErrorCode.PARSE_ERROR,\r\n `Failed to parse frontmatter in SKILL.md: ${(error as Error).message}`,\r\n { skillPath, file: skillMdPath },\r\n error as Error\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Validate skill content path exists and has required files\r\n *\r\n * @param skillPath - Path to skill directory\r\n * @returns Validation errors (empty if valid)\r\n */\r\nexport function validateContentPath(skillPath: string): ValidationError[] {\r\n const errors: ValidationError[] = [];\r\n\r\n // Check if directory exists\r\n if (!fs.existsSync(skillPath)) {\r\n errors.push({\r\n code: 'CONTENT_PATH_NOT_FOUND',\r\n message: `Skill directory not found: ${skillPath}`,\r\n context: { skillPath },\r\n });\r\n return errors;\r\n }\r\n\r\n // Check if it's a directory\r\n const stats = fs.statSync(skillPath);\r\n if (!stats.isDirectory()) {\r\n errors.push({\r\n code: 'CONTENT_PATH_NOT_DIRECTORY',\r\n message: `Skill path is not a directory: ${skillPath}`,\r\n context: { skillPath },\r\n });\r\n return errors;\r\n }\r\n\r\n // Check for required files\r\n const requiredFiles = ['SKILL.md', 'execute.sh'];\r\n for (const file of requiredFiles) {\r\n const filePath = path.join(skillPath, file);\r\n if (!fs.existsSync(filePath)) {\r\n errors.push({\r\n code: 'REQUIRED_FILE_MISSING',\r\n message: `Required file missing: ${file}`,\r\n context: { skillPath, file, expectedPath: filePath },\r\n });\r\n }\r\n }\r\n\r\n return errors;\r\n}\r\n\r\n/**\r\n * Validate execute.sh is executable\r\n *\r\n * @param skillPath - Path to skill directory\r\n * @returns Validation errors (empty if valid)\r\n */\r\nexport function validateExecuteScript(skillPath: string): ValidationError[] {\r\n const errors: ValidationError[] = [];\r\n const executePath = path.join(skillPath, 'execute.sh');\r\n\r\n if (!fs.existsSync(executePath)) {\r\n // Already caught by validateContentPath\r\n return errors;\r\n }\r\n\r\n try {\r\n const stats = fs.statSync(executePath);\r\n // Check if file has execute permission (any execute bit set)\r\n const isExecutable = (stats.mode & 0o111) !== 0;\r\n\r\n if (!isExecutable) {\r\n errors.push({\r\n code: 'EXECUTE_SCRIPT_NOT_EXECUTABLE',\r\n message: 'execute.sh is not executable',\r\n context: { skillPath, file: executePath, mode: stats.mode.toString(8) },\r\n });\r\n }\r\n } catch (error) {\r\n errors.push({\r\n code: 'EXECUTE_SCRIPT_CHECK_FAILED',\r\n message: `Failed to check execute.sh permissions: ${(error as Error).message}`,\r\n context: { skillPath, file: executePath },\r\n });\r\n }\r\n\r\n return errors;\r\n}\r\n\r\n/**\r\n * Validate skill schema compliance (frontmatter structure)\r\n *\r\n * @param skillPath - Path to skill directory\r\n * @returns Validation errors (empty if valid)\r\n */\r\nexport function validateSchemaCompliance(skillPath: string): ValidationError[] {\r\n const errors: ValidationError[] = [];\r\n\r\n try {\r\n const frontmatter = parseFrontmatter(skillPath);\r\n\r\n // Validate version format\r\n if (!validateVersion(frontmatter.version)) {\r\n errors.push({\r\n code: 'INVALID_VERSION_FORMAT',\r\n message: `Invalid semantic version format: ${frontmatter.version}`,\r\n context: {\r\n skillPath,\r\n version: frontmatter.version,\r\n expectedFormat: 'x.y.z',\r\n },\r\n });\r\n }\r\n\r\n // Validate name format (alphanumeric, hyphens, underscores only)\r\n const nameRegex = /^[a-zA-Z0-9_-]+$/;\r\n if (!nameRegex.test(frontmatter.name)) {\r\n errors.push({\r\n code: 'INVALID_NAME_FORMAT',\r\n message: `Invalid skill name format: ${frontmatter.name}`,\r\n context: {\r\n skillPath,\r\n name: frontmatter.name,\r\n expectedFormat: 'alphanumeric, hyphens, and underscores only',\r\n },\r\n });\r\n }\r\n } catch (error) {\r\n if (error instanceof StandardError) {\r\n errors.push({\r\n code: error.code,\r\n message: error.message,\r\n context: error.context,\r\n });\r\n } else {\r\n errors.push({\r\n code: 'SCHEMA_VALIDATION_FAILED',\r\n message: `Schema validation failed: ${(error as Error).message}`,\r\n context: { skillPath },\r\n });\r\n }\r\n }\r\n\r\n return errors;\r\n}\r\n\r\n/**\r\n * Check if skill name is unique (no existing skill with same name)\r\n *\r\n * @param dbService - Database service instance\r\n * @param skillName - Name of the skill to check\r\n * @param excludeSkillId - Optional skill ID to exclude from uniqueness check (for updates)\r\n * @returns Validation errors (empty if unique)\r\n */\r\nexport async function validateNameUniqueness(\r\n dbService: DatabaseService,\r\n skillName: string,\r\n excludeSkillId?: string\r\n): Promise<ValidationError[]> {\r\n const errors: ValidationError[] = [];\r\n\r\n try {\r\n const adapter = dbService.getAdapter('sqlite');\r\n\r\n let query = 'SELECT id, name FROM skills WHERE name = ?';\r\n const params: any[] = [skillName];\r\n\r\n if (excludeSkillId) {\r\n query += ' AND id != ?';\r\n params.push(excludeSkillId);\r\n }\r\n\r\n const result = await adapter.query(query, params);\r\n\r\n if (result.rows && result.rows.length > 0) {\r\n errors.push({\r\n code: 'NAME_NOT_UNIQUE',\r\n message: `Skill name already exists: ${skillName}`,\r\n context: {\r\n skillName,\r\n existingSkillId: result.rows[0].id,\r\n },\r\n });\r\n }\r\n } catch (error) {\r\n errors.push({\r\n code: 'NAME_UNIQUENESS_CHECK_FAILED',\r\n message: `Failed to check name uniqueness: ${(error as Error).message}`,\r\n context: { skillName },\r\n });\r\n }\r\n\r\n return errors;\r\n}\r\n\r\n/**\r\n * Check for version conflicts (version already exists for this skill)\r\n *\r\n * @param dbService - Database service instance\r\n * @param skillName - Name of the skill\r\n * @param version - Version to check\r\n * @returns Validation errors (empty if no conflict)\r\n */\r\nexport async function validateVersionConflict(\r\n dbService: DatabaseService,\r\n skillName: string,\r\n version: string\r\n): Promise<ValidationError[]> {\r\n const errors: ValidationError[] = [];\r\n\r\n try {\r\n const adapter = dbService.getAdapter('sqlite');\r\n\r\n const result = await adapter.query(\r\n 'SELECT id, version FROM skills WHERE name = ? AND version = ?',\r\n [skillName, version]\r\n );\r\n\r\n if (result.rows && result.rows.length > 0) {\r\n errors.push({\r\n code: 'VERSION_CONFLICT',\r\n message: `Version ${version} already exists for skill: ${skillName}`,\r\n context: {\r\n skillName,\r\n version,\r\n existingSkillId: result.rows[0].id,\r\n },\r\n });\r\n }\r\n } catch (error) {\r\n errors.push({\r\n code: 'VERSION_CONFLICT_CHECK_FAILED',\r\n message: `Failed to check version conflict: ${(error as Error).message}`,\r\n context: { skillName, version },\r\n });\r\n }\r\n\r\n return errors;\r\n}\r\n\r\n/**\r\n * Validate tests exist and pass (optional check)\r\n *\r\n * @param skillPath - Path to skill directory\r\n * @returns Validation warnings (not errors, as tests are optional)\r\n */\r\nexport function validateTests(skillPath: string): ValidationError[] {\r\n const warnings: ValidationError[] = [];\r\n const testPath = path.join(skillPath, 'test.sh');\r\n\r\n if (!fs.existsSync(testPath)) {\r\n warnings.push({\r\n code: 'TESTS_NOT_FOUND',\r\n message: 'No test.sh found (tests are recommended but optional)',\r\n context: { skillPath, expectedFile: testPath },\r\n });\r\n return warnings;\r\n }\r\n\r\n // Check if test.sh is executable\r\n try {\r\n const stats = fs.statSync(testPath);\r\n const isExecutable = (stats.mode & 0o111) !== 0;\r\n\r\n if (!isExecutable) {\r\n warnings.push({\r\n code: 'TEST_SCRIPT_NOT_EXECUTABLE',\r\n message: 'test.sh exists but is not executable',\r\n context: { skillPath, file: testPath },\r\n });\r\n }\r\n } catch (error) {\r\n warnings.push({\r\n code: 'TEST_SCRIPT_CHECK_FAILED',\r\n message: `Failed to check test.sh: ${(error as Error).message}`,\r\n context: { skillPath, file: testPath },\r\n });\r\n }\r\n\r\n return warnings;\r\n}\r\n\r\n/**\r\n * Comprehensive skill validation\r\n *\r\n * Runs all validation checks and returns aggregated results.\r\n *\r\n * @param dbService - Database service instance\r\n * @param skillPath - Path to skill directory\r\n * @param excludeSkillId - Optional skill ID to exclude from uniqueness check\r\n * @returns Validation result with all errors and warnings\r\n */\r\nexport async function validateSkill(\r\n dbService: DatabaseService,\r\n skillPath: string,\r\n excludeSkillId?: string\r\n): Promise<ValidationResult> {\r\n logger.info('Starting skill validation', { skillPath });\r\n\r\n const errors: ValidationError[] = [];\r\n const warnings: ValidationError[] = [];\r\n let metadata: ValidationResult['metadata'] = {};\r\n\r\n // 1. Validate content path exists\r\n const contentPathErrors = validateContentPath(skillPath);\r\n errors.push(...contentPathErrors);\r\n\r\n // If content path is invalid, stop here\r\n if (contentPathErrors.length > 0) {\r\n logger.warn('Skill validation failed: content path invalid', {\r\n skillPath,\r\n errorCount: errors.length,\r\n });\r\n return { valid: false, errors, warnings };\r\n }\r\n\r\n // 2. Validate schema compliance\r\n const schemaErrors = validateSchemaCompliance(skillPath);\r\n errors.push(...schemaErrors);\r\n\r\n // If schema is invalid, stop here\r\n if (schemaErrors.length > 0) {\r\n logger.warn('Skill validation failed: schema invalid', {\r\n skillPath,\r\n errorCount: errors.length,\r\n });\r\n return { valid: false, errors, warnings };\r\n }\r\n\r\n // Parse frontmatter for subsequent checks\r\n let frontmatter: SkillFrontmatter;\r\n try {\r\n frontmatter = parseFrontmatter(skillPath);\r\n metadata = {\r\n skillName: frontmatter.name,\r\n version: frontmatter.version,\r\n contentPath: skillPath,\r\n };\r\n } catch (error) {\r\n // Already handled in schema validation\r\n logger.warn('Skill validation failed: frontmatter parsing error', {\r\n skillPath,\r\n error: (error as Error).message,\r\n });\r\n return { valid: false, errors, warnings, metadata };\r\n }\r\n\r\n // 3. Validate execute.sh is executable\r\n const executeErrors = validateExecuteScript(skillPath);\r\n errors.push(...executeErrors);\r\n\r\n // 4. Validate name uniqueness\r\n const nameErrors = await validateNameUniqueness(\r\n dbService,\r\n frontmatter.name,\r\n excludeSkillId\r\n );\r\n errors.push(...nameErrors);\r\n\r\n // 5. Validate version conflict\r\n const versionErrors = await validateVersionConflict(\r\n dbService,\r\n frontmatter.name,\r\n frontmatter.version\r\n );\r\n errors.push(...versionErrors);\r\n\r\n // 6. Validate tests (warnings only)\r\n const testWarnings = validateTests(skillPath);\r\n warnings.push(...testWarnings);\r\n\r\n const valid = errors.length === 0;\r\n\r\n if (valid) {\r\n logger.info('Skill validation passed', {\r\n skillPath,\r\n skillName: frontmatter.name,\r\n version: frontmatter.version,\r\n warningCount: warnings.length,\r\n });\r\n } else {\r\n logger.warn('Skill validation failed', {\r\n skillPath,\r\n errorCount: errors.length,\r\n warningCount: warnings.length,\r\n });\r\n }\r\n\r\n return { valid, errors, warnings, metadata };\r\n}\r\n"],"names":["fs","path","StandardError","ErrorCode","createLogger","validateVersion","logger","parseFrontmatter","skillPath","skillMdPath","join","existsSync","FILE_NOT_FOUND","expectedFile","content","readFileSync","frontmatterRegex","match","PARSE_ERROR","file","frontmatterText","lines","split","filter","line","trim","frontmatter","colonIndex","indexOf","key","substring","value","startsWith","endsWith","length","map","v","name","VALIDATION_FAILED","version","error","message","validateContentPath","errors","push","code","context","stats","statSync","isDirectory","requiredFiles","filePath","expectedPath","validateExecuteScript","executePath","isExecutable","mode","toString","validateSchemaCompliance","expectedFormat","nameRegex","test","validateNameUniqueness","dbService","skillName","excludeSkillId","adapter","getAdapter","query","params","result","rows","existingSkillId","id","validateVersionConflict","validateTests","warnings","testPath","validateSkill","info","metadata","contentPathErrors","warn","errorCount","valid","schemaErrors","contentPath","executeErrors","nameErrors","versionErrors","testWarnings","warningCount"],"mappings":"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"}