claude-flow-novice 2.15.3 → 2.15.5

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 (473) 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 +29 -6
  34. package/.claude/commands/switch-api.md +31 -10
  35. package/.claude/hooks/cfn-lint-sql-injection.sh +61 -0
  36. package/.claude/hooks/cfn-post-edit-cfn-retrospective.sh +33 -2
  37. package/.claude/hooks/cfn-pre-edit-security-warning.sh +40 -0
  38. package/.claude/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
  39. package/.claude/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
  40. package/.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
  41. package/.claude/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
  42. package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
  43. package/.claude/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
  44. package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +238 -29
  45. package/.claude/skills/cfn-loop-orchestration/security_utils.sh +24 -0
  46. package/.claude/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
  47. package/.claude/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
  48. package/.claude/skills/cfn-redis-coordination/agent-log.sh +4 -0
  49. package/.claude/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
  50. package/.claude/skills/cfn-redis-coordination/agent-recovery.sh +2 -2
  51. package/.claude/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
  52. package/.claude/skills/cfn-redis-coordination/get-context.sh +33 -0
  53. package/.claude/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
  54. package/.claude/skills/cfn-redis-coordination/invoke-waiting-mode.sh +6 -2
  55. package/.claude/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
  56. package/.claude/skills/cfn-redis-coordination/redis-functions.sh +34 -0
  57. package/.claude/skills/cfn-redis-coordination/report-completion.sh +24 -31
  58. package/.claude/skills/cfn-redis-coordination/store-context.sh +4 -0
  59. package/.claude/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
  60. package/.claude/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
  61. package/.claude/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
  62. package/.claude/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
  63. package/.claude/skills/cfn-transparency-middleware/tests/input-validation.sh +15 -0
  64. package/README.md +116 -475
  65. package/claude-assets/agents/cfn-dev-team/README.md +103 -0
  66. package/claude-assets/agents/cfn-dev-team/architecture/goal-planner.md +1 -1
  67. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +77 -15
  68. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +355 -6
  69. package/claude-assets/agents/cfn-dev-team/coordinators/consensus-builder.md +82 -1
  70. package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +82 -1
  71. package/claude-assets/agents/cfn-dev-team/coordinators/multi-sprint-coordinator.md +77 -15
  72. package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +99 -12
  73. package/claude-assets/agents/cfn-dev-team/dev-ops/github-commit-agent.md +1 -1
  74. package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +97 -0
  75. package/claude-assets/agents/cfn-dev-team/dev-ops/monitoring-specialist.md +20 -1
  76. package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +97 -0
  77. package/claude-assets/agents/cfn-dev-team/developers/backend-developer.md +110 -13
  78. package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +106 -15
  79. package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +115 -11
  80. package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +94 -7
  81. package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +87 -9
  82. package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +85 -7
  83. package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +160 -28
  84. package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +101 -19
  85. package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +108 -14
  86. package/claude-assets/agents/cfn-dev-team/reviewers/{reviewer.md → code-reviewer.md} +95 -8
  87. package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +107 -7
  88. package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +98 -7
  89. package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +95 -7
  90. package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +136 -9
  91. package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +108 -1
  92. package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +107 -13
  93. package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +737 -0
  94. package/claude-assets/agents/cfn-dev-team/testers/e2e/playwright-tester.md +1 -1
  95. package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +828 -0
  96. package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +106 -7
  97. package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +77 -0
  98. package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +684 -0
  99. package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +110 -1
  100. package/claude-assets/agents/cfn-dev-team/testers/tester.md +94 -7
  101. package/claude-assets/agents/cfn-dev-team/utility/code-booster.md +1 -3
  102. package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +87 -13
  103. package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +103 -7
  104. package/claude-assets/agents/cfn-dev-team/utility/researcher.md +1 -3
  105. package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +94 -7
  106. package/claude-assets/agents/docker-coordinators/cfn-docker-v3-coordinator.md +46 -0
  107. package/claude-assets/agents/project-only-agents/npm-package-specialist.md +1 -1
  108. package/claude-assets/cfn-extras/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
  109. package/claude-assets/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
  110. package/claude-assets/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
  111. package/claude-assets/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
  112. package/claude-assets/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
  113. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
  114. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
  115. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
  116. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
  117. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
  118. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
  119. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
  120. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
  121. package/claude-assets/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
  122. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
  123. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
  124. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
  125. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
  126. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
  127. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
  128. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
  129. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
  130. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
  131. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
  132. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
  133. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
  134. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
  135. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
  136. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
  137. package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
  138. package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
  139. package/claude-assets/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
  140. package/claude-assets/commands/cfn-loop-cli.md +29 -6
  141. package/claude-assets/commands/switch-api.md +31 -10
  142. package/claude-assets/hooks/cfn-lint-sql-injection.sh +61 -0
  143. package/claude-assets/hooks/cfn-post-edit-cfn-retrospective.sh +33 -2
  144. package/claude-assets/hooks/cfn-pre-edit-security-warning.sh +40 -0
  145. package/claude-assets/hooks/detect-hardcoded-credentials.sh +212 -0
  146. package/claude-assets/skills/SKILL_TEMPLATE.md +774 -0
  147. package/claude-assets/skills/agent-lifecycle/execute-lifecycle-hook.sh +84 -113
  148. package/claude-assets/skills/agent-lifecycle/simple-audit.sh +33 -6
  149. package/claude-assets/skills/agent-template-generator/SKILL.md +440 -0
  150. package/claude-assets/skills/agent-template-generator/generate-agent.sh +405 -0
  151. package/claude-assets/skills/agent-validation-linter/SKILL.md +589 -0
  152. package/claude-assets/skills/agent-validation-linter/lint-agents.sh +271 -0
  153. package/claude-assets/skills/bootstrap/bash-fundamentals.md +786 -0
  154. package/claude-assets/skills/bootstrap/database-connection.md +464 -0
  155. package/claude-assets/skills/bootstrap/error-handling.md +580 -0
  156. package/claude-assets/skills/bootstrap/file-operations.md +699 -0
  157. package/claude-assets/skills/bootstrap/skill-loader.md +616 -0
  158. package/claude-assets/skills/bootstrap/sqlite-params.sh +287 -0
  159. package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
  160. package/claude-assets/skills/cfn-automatic-memory-persistence/test-memory-persistence.sh +17 -16
  161. package/claude-assets/skills/cfn-deployment/SKILL.md +293 -0
  162. package/claude-assets/skills/cfn-deployment/execute.sh +21 -0
  163. package/claude-assets/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
  164. package/claude-assets/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
  165. package/claude-assets/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
  166. package/claude-assets/skills/cfn-environment-sanitization/sanitize-environment.sh +38 -0
  167. package/claude-assets/skills/cfn-error-batching-strategy/lib/core-functions.sh +47 -47
  168. package/claude-assets/skills/cfn-file-operations/SKILL.md +290 -0
  169. package/claude-assets/skills/cfn-file-operations/execute.sh +129 -0
  170. package/claude-assets/skills/cfn-file-operations/lib/atomic-write.sh +294 -0
  171. package/claude-assets/skills/cfn-file-operations/lib/lock.sh +361 -0
  172. package/claude-assets/skills/cfn-file-operations/test.sh +369 -0
  173. package/claude-assets/skills/cfn-log-operations/SKILL.md +308 -0
  174. package/claude-assets/skills/cfn-log-operations/execute.sh +420 -0
  175. package/claude-assets/skills/cfn-log-operations/lib/rotate.sh +406 -0
  176. package/claude-assets/skills/cfn-log-operations/lib/search.sh +448 -0
  177. package/claude-assets/skills/cfn-log-operations/test.sh +394 -0
  178. package/claude-assets/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
  179. package/claude-assets/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
  180. package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +238 -29
  181. package/claude-assets/skills/cfn-loop-orchestration/security_utils.sh +24 -0
  182. package/claude-assets/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
  183. package/claude-assets/skills/cfn-parameterized-queries/SKILL.md +339 -0
  184. package/claude-assets/skills/cfn-playbook/query-playbook.sh +19 -15
  185. package/claude-assets/skills/cfn-playbook/update-playbook.sh +25 -14
  186. package/claude-assets/skills/cfn-process-instrumentation/instrument-process.sh +44 -0
  187. package/claude-assets/skills/cfn-promotion/SKILL.md +305 -0
  188. package/claude-assets/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
  189. package/claude-assets/skills/cfn-redis-coordination/agent-log.sh +4 -0
  190. package/claude-assets/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
  191. package/claude-assets/skills/cfn-redis-coordination/agent-recovery.sh +2 -2
  192. package/claude-assets/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
  193. package/claude-assets/skills/cfn-redis-coordination/get-context.sh +33 -0
  194. package/claude-assets/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
  195. package/claude-assets/skills/cfn-redis-coordination/invoke-waiting-mode.sh +6 -2
  196. package/claude-assets/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
  197. package/claude-assets/skills/cfn-redis-coordination/redis-functions.sh +34 -0
  198. package/claude-assets/skills/cfn-redis-coordination/report-completion.sh +24 -31
  199. package/claude-assets/skills/cfn-redis-coordination/store-context.sh +4 -0
  200. package/claude-assets/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
  201. package/claude-assets/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
  202. package/claude-assets/skills/cfn-skill-loader/SKILL.md +466 -0
  203. package/claude-assets/skills/cfn-skill-loader/execute.sh +344 -0
  204. package/claude-assets/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
  205. package/claude-assets/skills/cfn-task-audit/get-audit-data.sh +42 -21
  206. package/claude-assets/skills/cfn-task-audit/store-task-audit.sh +17 -10
  207. package/claude-assets/skills/cfn-test-runner/detect-regressions.sh +17 -14
  208. package/claude-assets/skills/cfn-test-runner/detect-regressions.sh.backup-1763392821 +55 -0
  209. package/claude-assets/skills/cfn-test-runner/store-benchmarks.sh +17 -19
  210. package/claude-assets/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
  211. package/claude-assets/skills/cfn-transparency-middleware/tests/input-validation.sh +15 -0
  212. package/claude-assets/skills/cfn-utilities/SKILL.md +237 -0
  213. package/claude-assets/skills/cfn-utilities/execute.sh +32 -0
  214. package/claude-assets/skills/cfn-utilities/lib/errors.sh +56 -0
  215. package/claude-assets/skills/cfn-utilities/lib/file-ops.sh +164 -0
  216. package/claude-assets/skills/cfn-utilities/lib/logging.sh +77 -0
  217. package/claude-assets/skills/cfn-utilities/lib/retry.sh +127 -0
  218. package/claude-assets/skills/cfn-utilities/test.sh +317 -0
  219. package/claude-assets/skills/integration/agent-handoff.sh +62 -64
  220. package/claude-assets/skills/json-validation/SKILL.md +431 -0
  221. package/claude-assets/skills/json-validation/test-validate-success-criteria.sh +421 -0
  222. package/claude-assets/skills/json-validation/validate-success-criteria.sh +197 -0
  223. package/claude-assets/skills/redis-coordination/validate-parameters.sh +34 -0
  224. package/claude-assets/skills/workflow-codification/DEPLOY_QUICK_REFERENCE.md +106 -0
  225. package/claude-assets/skills/workflow-codification/PROPAGATE_UPDATE_QUICK_REFERENCE.md +366 -0
  226. package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh +481 -0
  227. package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh.backup-1763392820 +512 -0
  228. package/claude-assets/skills/workflow-codification/lib/security-utils.sh +204 -0
  229. package/claude-assets/skills/workflow-codification/propagate-skill-update.sh +648 -0
  230. package/claude-assets/skills/workflow-codification/propagate-skill-update.sh.backup-1763392820 +664 -0
  231. package/claude-assets/skills/workflow-codification/test-integration.sh +15 -0
  232. package/claude-assets/skills/workflow-codification/test-metadata-update.sh +350 -0
  233. package/claude-assets/skills/workflow-codification/track-cost-savings.sh +55 -14
  234. package/claude-assets/skills/workflow-codification/track-cost-savings.sh.backup-1763392821 +445 -0
  235. package/claude-assets/skills/workflow-codification/track-edge-case.sh +27 -60
  236. package/claude-assets/skills/workflow-codification/workflow-codification.db +0 -0
  237. package/dist/ace/ace-curator.js +10 -2
  238. package/dist/ace/ace-curator.js.map +1 -1
  239. package/dist/ace/ace-generator.js +4 -0
  240. package/dist/ace/ace-generator.js.map +1 -1
  241. package/dist/ace/ace-reflector.js +1 -1
  242. package/dist/ace/ace-reflector.js.map +1 -1
  243. package/dist/ace/context-injection.js +24 -2
  244. package/dist/ace/context-injection.js.map +1 -1
  245. package/dist/agents/task-agent-integration.js +1 -1
  246. package/dist/agents/task-agent-integration.js.map +1 -1
  247. package/dist/api/health-endpoints.js +390 -0
  248. package/dist/api/health-endpoints.js.map +1 -0
  249. package/dist/cli/agent-executor.js +4 -1
  250. package/dist/cli/agent-executor.js.map +1 -1
  251. package/dist/cli/agent-prompt-builder.js +89 -1
  252. package/dist/cli/agent-prompt-builder.js.map +1 -1
  253. package/dist/cli/agent-spawn.js +130 -37
  254. package/dist/cli/agent-spawn.js.map +1 -1
  255. package/dist/cli/config-manager.js +109 -91
  256. package/dist/cli/config-manager.js.map +1 -1
  257. package/dist/cli/conversation-fork-cleanup.js +201 -0
  258. package/dist/cli/conversation-fork-cleanup.js.map +1 -0
  259. package/dist/cli/conversation-fork.js +16 -3
  260. package/dist/cli/conversation-fork.js.map +1 -1
  261. package/dist/cli/skill-cache-validator.js +412 -0
  262. package/dist/cli/skill-cache-validator.js.map +1 -0
  263. package/dist/cli/skill-cli.js +991 -0
  264. package/dist/cli/skill-cli.js.map +1 -0
  265. package/dist/cli/skill-execution-logger.js +284 -0
  266. package/dist/cli/skill-execution-logger.js.map +1 -0
  267. package/dist/cli/skill-loader.js +457 -0
  268. package/dist/cli/skill-loader.js.map +1 -0
  269. package/dist/coordination/event-bus.js +2 -2
  270. package/dist/coordination/event-bus.js.map +1 -1
  271. package/dist/coordination/fleet-manager.js +1 -1
  272. package/dist/coordination/fleet-manager.js.map +1 -1
  273. package/dist/coordination/index.js +23 -9
  274. package/dist/coordination/index.js.map +1 -1
  275. package/dist/coordination/types/fleet-manager.types.js.map +1 -1
  276. package/dist/db/migration-manager.js +483 -0
  277. package/dist/db/migration-manager.js.map +1 -0
  278. package/dist/db/skills-query.js +535 -0
  279. package/dist/db/skills-query.js.map +1 -0
  280. package/dist/integration/DatabaseHandoff.js +1 -1
  281. package/dist/integration/DatabaseHandoff.js.map +1 -1
  282. package/dist/jobs/edge-case-analyzer.js +367 -0
  283. package/dist/jobs/edge-case-analyzer.js.map +1 -0
  284. package/dist/jobs/promotion-sla-enforcer.js +288 -0
  285. package/dist/jobs/promotion-sla-enforcer.js.map +1 -0
  286. package/dist/lib/agent-output-parser.js.map +1 -1
  287. package/dist/lib/agent-output-validator.js.map +1 -1
  288. package/dist/lib/agent-workspace.js +281 -0
  289. package/dist/lib/agent-workspace.js.map +1 -0
  290. package/dist/lib/atomic-file-writer.js +377 -0
  291. package/dist/lib/atomic-file-writer.js.map +1 -0
  292. package/dist/lib/backup-manager.js +779 -0
  293. package/dist/lib/backup-manager.js.map +1 -0
  294. package/dist/lib/checkpoint-manager.js +837 -0
  295. package/dist/lib/checkpoint-manager.js.map +1 -0
  296. package/dist/lib/circuit-breaker.js +340 -0
  297. package/dist/lib/circuit-breaker.js.map +1 -0
  298. package/dist/lib/completion-signal-handler.js +243 -0
  299. package/dist/lib/completion-signal-handler.js.map +1 -0
  300. package/dist/lib/config-manager.js +312 -0
  301. package/dist/lib/config-manager.js.map +1 -0
  302. package/dist/lib/config-migrator.js +386 -0
  303. package/dist/lib/config-migrator.js.map +1 -0
  304. package/dist/lib/config-validator.js.map +1 -1
  305. package/dist/lib/correlation-cache.js +311 -0
  306. package/dist/lib/correlation-cache.js.map +1 -0
  307. package/dist/lib/correlation.js +263 -0
  308. package/dist/lib/correlation.js.map +1 -0
  309. package/dist/lib/database-service/connection-pool-manager.js +520 -0
  310. package/dist/lib/database-service/connection-pool-manager.js.map +1 -0
  311. package/dist/lib/database-service/correlation.js +329 -0
  312. package/dist/lib/database-service/correlation.js.map +1 -0
  313. package/dist/lib/database-service/errors.js +120 -0
  314. package/dist/lib/database-service/errors.js.map +1 -0
  315. package/dist/lib/database-service/index.js +168 -0
  316. package/dist/lib/database-service/index.js.map +1 -0
  317. package/dist/lib/database-service/postgres-adapter.js +526 -0
  318. package/dist/lib/database-service/postgres-adapter.js.map +1 -0
  319. package/dist/lib/database-service/redis-adapter.js +360 -0
  320. package/dist/lib/database-service/redis-adapter.js.map +1 -0
  321. package/dist/lib/database-service/sqlite-adapter.js +544 -0
  322. package/dist/lib/database-service/sqlite-adapter.js.map +1 -0
  323. package/dist/lib/database-service/transaction-manager.js +773 -0
  324. package/dist/lib/database-service/transaction-manager.js.map +1 -0
  325. package/dist/lib/database-service/types.js +23 -0
  326. package/dist/lib/database-service/types.js.map +1 -0
  327. package/dist/lib/deadlock-resolver.js +292 -0
  328. package/dist/lib/deadlock-resolver.js.map +1 -0
  329. package/dist/lib/distributed-lock.js +451 -0
  330. package/dist/lib/distributed-lock.js.map +1 -0
  331. package/dist/lib/edge-case-deduplicator.js +227 -0
  332. package/dist/lib/edge-case-deduplicator.js.map +1 -0
  333. package/dist/lib/encryption-manager.js +322 -0
  334. package/dist/lib/encryption-manager.js.map +1 -0
  335. package/dist/lib/error-aggregator.js +234 -0
  336. package/dist/lib/error-aggregator.js.map +1 -0
  337. package/dist/lib/errors.js +287 -0
  338. package/dist/lib/errors.js.map +1 -0
  339. package/dist/lib/file-lock-manager.js +578 -0
  340. package/dist/lib/file-lock-manager.js.map +1 -0
  341. package/dist/lib/file-operations.js +367 -0
  342. package/dist/lib/file-operations.js.map +1 -0
  343. package/dist/lib/idempotent-write.js +237 -0
  344. package/dist/lib/idempotent-write.js.map +1 -0
  345. package/dist/lib/integration-schema-validator.js +522 -0
  346. package/dist/lib/integration-schema-validator.js.map +1 -0
  347. package/dist/lib/lock-health-monitor.js +298 -0
  348. package/dist/lib/lock-health-monitor.js.map +1 -0
  349. package/dist/lib/log-shipper.js +422 -0
  350. package/dist/lib/log-shipper.js.map +1 -0
  351. package/dist/lib/logging.js +146 -0
  352. package/dist/lib/logging.js.map +1 -0
  353. package/dist/lib/message-deduplicator.js +439 -0
  354. package/dist/lib/message-deduplicator.js.map +1 -0
  355. package/dist/lib/multi-system-query.js +604 -0
  356. package/dist/lib/multi-system-query.js.map +1 -0
  357. package/dist/lib/orphan-detector.js +332 -0
  358. package/dist/lib/orphan-detector.js.map +1 -0
  359. package/dist/lib/password-generator.js +166 -0
  360. package/dist/lib/password-generator.js.map +1 -0
  361. package/dist/lib/path-validator.js +429 -0
  362. package/dist/lib/path-validator.js.map +1 -0
  363. package/dist/lib/query-translator.js +905 -0
  364. package/dist/lib/query-translator.js.map +1 -0
  365. package/dist/lib/queue-recovery.js +469 -0
  366. package/dist/lib/queue-recovery.js.map +1 -0
  367. package/dist/lib/redis-queue-manager.js +512 -0
  368. package/dist/lib/redis-queue-manager.js.map +1 -0
  369. package/dist/lib/reflection-archiver.js +272 -0
  370. package/dist/lib/reflection-archiver.js.map +1 -0
  371. package/dist/lib/retry-manager.js +453 -0
  372. package/dist/lib/retry-manager.js.map +1 -0
  373. package/dist/lib/retry.js +262 -0
  374. package/dist/lib/retry.js.map +1 -0
  375. package/dist/lib/schema-transform.js +695 -0
  376. package/dist/lib/schema-transform.js.map +1 -0
  377. package/dist/lib/schema-validator.js +491 -0
  378. package/dist/lib/schema-validator.js.map +1 -0
  379. package/dist/lib/skill-cache.js +297 -0
  380. package/dist/lib/skill-cache.js.map +1 -0
  381. package/dist/lib/skill-content-manager.js +337 -0
  382. package/dist/lib/skill-content-manager.js.map +1 -0
  383. package/dist/lib/skill-frontmatter-parser.js +237 -0
  384. package/dist/lib/skill-frontmatter-parser.js.map +1 -0
  385. package/dist/lib/skill-git-integration.js +275 -0
  386. package/dist/lib/skill-git-integration.js.map +1 -0
  387. package/dist/lib/skill-markdown-validator.js +396 -0
  388. package/dist/lib/skill-markdown-validator.js.map +1 -0
  389. package/dist/lib/skill-output-parser.js +312 -0
  390. package/dist/lib/skill-output-parser.js.map +1 -0
  391. package/dist/lib/unified-query-api.js +467 -0
  392. package/dist/lib/unified-query-api.js.map +1 -0
  393. package/dist/middleware/auth-middleware.js +350 -0
  394. package/dist/middleware/auth-middleware.js.map +1 -0
  395. package/dist/middleware/schema-validation.js +347 -0
  396. package/dist/middleware/schema-validation.js.map +1 -0
  397. package/dist/providers/anthropic-provider.js +1 -1
  398. package/dist/providers/anthropic-provider.js.map +1 -1
  399. package/dist/providers/provider-factory.js +2 -2
  400. package/dist/providers/provider-factory.js.map +1 -1
  401. package/dist/services/edge-case-analyzer.js +321 -0
  402. package/dist/services/edge-case-analyzer.js.map +1 -0
  403. package/dist/services/edge-case-deduplicator.js +266 -0
  404. package/dist/services/edge-case-deduplicator.js.map +1 -0
  405. package/dist/services/edge-case-detector.js +337 -0
  406. package/dist/services/edge-case-detector.js.map +1 -0
  407. package/dist/services/edge-case-tracker.js +547 -0
  408. package/dist/services/edge-case-tracker.js.map +1 -0
  409. package/dist/services/health-check-system.js +586 -0
  410. package/dist/services/health-check-system.js.map +1 -0
  411. package/dist/services/metrics-logger.js +412 -0
  412. package/dist/services/metrics-logger.js.map +1 -0
  413. package/dist/services/patch-generator.js +378 -0
  414. package/dist/services/patch-generator.js.map +1 -0
  415. package/dist/services/patch-validator.js +337 -0
  416. package/dist/services/patch-validator.js.map +1 -0
  417. package/dist/services/performance-monitor.js +811 -0
  418. package/dist/services/performance-monitor.js.map +1 -0
  419. package/dist/services/promotion-pipeline.js +918 -0
  420. package/dist/services/promotion-pipeline.js.map +1 -0
  421. package/dist/services/promotion-validator.js +394 -0
  422. package/dist/services/promotion-validator.js.map +1 -0
  423. package/dist/services/reflection-logger.js +388 -0
  424. package/dist/services/reflection-logger.js.map +1 -0
  425. package/dist/services/skill-deployment.js +472 -0
  426. package/dist/services/skill-deployment.js.map +1 -0
  427. package/dist/services/skill-loader.js +427 -0
  428. package/dist/services/skill-loader.js.map +1 -0
  429. package/dist/services/skill-promotion.js +372 -0
  430. package/dist/services/skill-promotion.js.map +1 -0
  431. package/dist/services/skill-validator.js +454 -0
  432. package/dist/services/skill-validator.js.map +1 -0
  433. package/dist/services/skill-versioning.js +244 -0
  434. package/dist/services/skill-versioning.js.map +1 -0
  435. package/dist/services/workspace-supervisor.js +597 -0
  436. package/dist/services/workspace-supervisor.js.map +1 -0
  437. package/dist/types/edge-case.js +45 -0
  438. package/dist/types/edge-case.js.map +1 -0
  439. package/docs/BUG_19_MEMORY_LEAK_TASK_MODE.md +405 -0
  440. package/docs/MEMORY_CLEANUP_GUIDE.md +358 -0
  441. package/docs/MEMORY_LEAK_FIX_SUMMARY.md +322 -0
  442. package/docs/REDIS_CLEANUP_EXECUTIVE_SUMMARY.md +319 -0
  443. package/docs/REDIS_CLEANUP_VERIFICATION_REPORT.md +574 -0
  444. package/package.json +35 -4
  445. package/readme/README.md +53 -5
  446. package/scripts/backup-cleanup.sh +627 -0
  447. package/scripts/cleanup-workspaces.sh +412 -0
  448. package/scripts/cleanup-yaml-configs.sh +141 -0
  449. package/scripts/deploy-approved-skills.sh +263 -0
  450. package/scripts/health-check.sh +447 -0
  451. package/scripts/log-aggregator.sh +554 -0
  452. package/scripts/log-monitor.sh +629 -0
  453. package/scripts/manage-agent-workspaces.sh +434 -0
  454. package/scripts/migrate-schema.sh +533 -0
  455. package/scripts/promote-staged-skills.sh +423 -0
  456. package/scripts/verify-no-secrets.sh +88 -35
  457. package/scripts/verify-redis-cleanup.sh +173 -0
  458. package/tests/README.md +84 -0
  459. package/tests/test-memory-leak-task-mode.sh +435 -0
  460. package/.claude/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
  461. package/.claude/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
  462. package/.claude/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
  463. package/.claude/skills/agent-lifecycle/SKILL.md +0 -60
  464. package/.claude/skills/agent-lifecycle/execute-lifecycle-hook.sh +0 -573
  465. package/.claude/skills/agent-lifecycle/simple-audit.sh +0 -31
  466. package/.claude/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
  467. package/.claude/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
  468. package/README.md.backup_before_replace +0 -781
  469. package/claude-assets/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
  470. package/claude-assets/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
  471. package/claude-assets/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
  472. package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
  473. package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/skill-content-manager.ts"],"sourcesContent":["/**\r\n * Skill Content Manager\r\n *\r\n * Manages standardized skill content storage, organization, and versioning\r\n * Enforces directory structure, validates required files, tracks versions\r\n *\r\n * @module skill-content-manager\r\n * @version 1.0.0\r\n */\r\n\r\nimport { join, basename, dirname } from 'path';\r\nimport { stat, readdir, access, chmod, readFile, writeFile, mkdir } from 'fs/promises';\r\nimport { constants } from 'fs';\r\nimport { StandardError } from './errors.js';\r\nimport {\r\n SkillFrontmatter,\r\n ParsedSkillDocument,\r\n parseFrontmatter,\r\n validateFrontmatter,\r\n parseAndValidate,\r\n updateFrontmatter,\r\n createSkillDocument\r\n} from './skill-frontmatter-parser.js';\r\nimport {\r\n calculateFileHash,\r\n getCommitMetadata,\r\n getVersionHistory,\r\n commitFile,\r\n hasUncommittedChanges,\r\n verifyContentIntegrity,\r\n getFileCreationDate,\r\n getFileModificationDate,\r\n GitCommitMetadata,\r\n VersionHistoryEntry\r\n} from './skill-git-integration.js';\r\n\r\n/**\r\n * Required files in skill directory\r\n */\r\nexport const REQUIRED_SKILL_FILES = [\r\n 'SKILL.md',\r\n 'execute.sh',\r\n 'test.sh',\r\n 'validate.sh',\r\n 'package.json'\r\n] as const;\r\n\r\n/**\r\n * Skill directory structure validation result\r\n */\r\nexport interface SkillStructureValidation {\r\n valid: boolean;\r\n skillName: string;\r\n skillPath: string;\r\n missingFiles: string[];\r\n invalidPermissions: string[];\r\n errors: string[];\r\n warnings: string[];\r\n}\r\n\r\n/**\r\n * Complete skill metadata including git info\r\n */\r\nexport interface SkillMetadata extends SkillFrontmatter {\r\n skillPath: string;\r\n contentHash: string;\r\n gitMetadata?: GitCommitMetadata;\r\n versionHistory?: VersionHistoryEntry[];\r\n hasUncommittedChanges?: boolean;\r\n fileCreated?: string;\r\n fileModified?: string;\r\n}\r\n\r\n/**\r\n * Skill update options\r\n */\r\nexport interface SkillUpdateOptions {\r\n autoCommit?: boolean;\r\n commitMessage?: string;\r\n updateTimestamp?: boolean;\r\n validateStructure?: boolean;\r\n}\r\n\r\n/**\r\n * Skill content manager error\r\n */\r\nexport class SkillContentError extends StandardError {\r\n constructor(message: string, public readonly context?: Record<string, unknown>) {\r\n super('SKILL_CONTENT_ERROR', message, context);\r\n this.name = 'SkillContentError';\r\n }\r\n}\r\n\r\n/**\r\n * Validate skill directory structure\r\n *\r\n * @param skillPath - Path to skill directory\r\n * @returns Validation result with details\r\n */\r\nexport async function validateSkillStructure(\r\n skillPath: string\r\n): Promise<SkillStructureValidation> {\r\n const skillName = basename(skillPath);\r\n const missingFiles: string[] = [];\r\n const invalidPermissions: string[] = [];\r\n const errors: string[] = [];\r\n const warnings: string[] = [];\r\n\r\n try {\r\n // Check if directory exists\r\n const dirStat = await stat(skillPath);\r\n if (!dirStat.isDirectory()) {\r\n errors.push(`${skillPath} is not a directory`);\r\n return {\r\n valid: false,\r\n skillName,\r\n skillPath,\r\n missingFiles,\r\n invalidPermissions,\r\n errors,\r\n warnings\r\n };\r\n }\r\n } catch (error) {\r\n errors.push(`Skill directory does not exist: ${skillPath}`);\r\n return {\r\n valid: false,\r\n skillName,\r\n skillPath,\r\n missingFiles,\r\n invalidPermissions,\r\n errors,\r\n warnings\r\n };\r\n }\r\n\r\n // Check required files\r\n for (const fileName of REQUIRED_SKILL_FILES) {\r\n const filePath = join(skillPath, fileName);\r\n\r\n try {\r\n await access(filePath, constants.F_OK);\r\n\r\n // Check execute permission for .sh files\r\n if (fileName.endsWith('.sh')) {\r\n try {\r\n await access(filePath, constants.X_OK);\r\n } catch {\r\n invalidPermissions.push(fileName);\r\n errors.push(`${fileName} is not executable`);\r\n }\r\n }\r\n } catch {\r\n missingFiles.push(fileName);\r\n errors.push(`Required file missing: ${fileName}`);\r\n }\r\n }\r\n\r\n // Validate SKILL.md frontmatter if exists\r\n const skillMdPath = join(skillPath, 'SKILL.md');\r\n try {\r\n await access(skillMdPath, constants.F_OK);\r\n const content = await readFile(skillMdPath, 'utf-8');\r\n\r\n try {\r\n const parsed = parseFrontmatter(content);\r\n const validation = validateFrontmatter(parsed.frontmatter);\r\n\r\n if (!validation.valid) {\r\n errors.push(...validation.errors);\r\n }\r\n\r\n warnings.push(...validation.warnings);\r\n } catch (error) {\r\n errors.push(`SKILL.md frontmatter error: ${error instanceof Error ? error.message : String(error)}`);\r\n }\r\n } catch {\r\n // Already reported as missing file\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n skillName,\r\n skillPath,\r\n missingFiles,\r\n invalidPermissions,\r\n errors,\r\n warnings\r\n };\r\n}\r\n\r\n/**\r\n * Fix skill file permissions\r\n *\r\n * @param skillPath - Path to skill directory\r\n * @returns Array of files that were fixed\r\n */\r\nexport async function fixSkillPermissions(skillPath: string): Promise<string[]> {\r\n const fixed: string[] = [];\r\n\r\n for (const fileName of REQUIRED_SKILL_FILES) {\r\n if (fileName.endsWith('.sh')) {\r\n const filePath = join(skillPath, fileName);\r\n\r\n try {\r\n await access(filePath, constants.F_OK);\r\n await chmod(filePath, 0o755); // rwxr-xr-x\r\n fixed.push(fileName);\r\n } catch {\r\n // File doesn't exist, skip\r\n }\r\n }\r\n }\r\n\r\n return fixed;\r\n}\r\n\r\n/**\r\n * Load skill metadata with git integration\r\n *\r\n * @param skillPath - Path to skill directory\r\n * @param includeHistory - Include version history (default: false)\r\n * @returns Complete skill metadata\r\n */\r\nexport async function loadSkillMetadata(\r\n skillPath: string,\r\n includeHistory: boolean = false\r\n): Promise<SkillMetadata> {\r\n const skillMdPath = join(skillPath, 'SKILL.md');\r\n\r\n try {\r\n // Read and parse SKILL.md\r\n const content = await readFile(skillMdPath, 'utf-8');\r\n const parsed = parseAndValidate(content);\r\n\r\n // Calculate content hash\r\n const contentHash = calculateFileHash(skillMdPath);\r\n\r\n // Get git metadata (graceful fallback if not in git repo)\r\n let gitMetadata: GitCommitMetadata | undefined;\r\n let versionHistory: VersionHistoryEntry[] | undefined;\r\n let hasChanges: boolean | undefined;\r\n let fileCreated: string | undefined;\r\n let fileModified: string | undefined;\r\n\r\n try {\r\n gitMetadata = await getCommitMetadata(skillMdPath);\r\n hasChanges = await hasUncommittedChanges(skillMdPath);\r\n fileCreated = await getFileCreationDate(skillMdPath);\r\n fileModified = await getFileModificationDate(skillMdPath);\r\n\r\n if (includeHistory) {\r\n versionHistory = await getVersionHistory(skillMdPath);\r\n }\r\n } catch {\r\n // Not in git repo or no git history - continue without git data\r\n }\r\n\r\n return {\r\n ...parsed.frontmatter,\r\n skillPath,\r\n contentHash: await contentHash,\r\n gitMetadata,\r\n versionHistory,\r\n hasUncommittedChanges: hasChanges,\r\n fileCreated,\r\n fileModified\r\n };\r\n } catch (error) {\r\n throw new SkillContentError(\r\n `Failed to load skill metadata from ${skillPath}`,\r\n { error: error instanceof Error ? error.message : String(error) }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Update skill frontmatter\r\n *\r\n * @param skillPath - Path to skill directory\r\n * @param updates - Partial frontmatter updates\r\n * @param options - Update options\r\n * @returns Updated skill metadata\r\n */\r\nexport async function updateSkillFrontmatter(\r\n skillPath: string,\r\n updates: Partial<SkillFrontmatter>,\r\n options: SkillUpdateOptions = {}\r\n): Promise<SkillMetadata> {\r\n const {\r\n autoCommit = false,\r\n commitMessage,\r\n updateTimestamp = true,\r\n validateStructure = true\r\n } = options;\r\n\r\n const skillMdPath = join(skillPath, 'SKILL.md');\r\n\r\n try {\r\n // Validate structure first if requested\r\n if (validateStructure) {\r\n const validation = await validateSkillStructure(skillPath);\r\n if (!validation.valid) {\r\n throw new SkillContentError('Skill structure validation failed', {\r\n errors: validation.errors\r\n });\r\n }\r\n }\r\n\r\n // Read current content\r\n const currentContent = await readFile(skillMdPath, 'utf-8');\r\n\r\n // Update frontmatter\r\n const updatedContent = updateFrontmatter(currentContent, updates);\r\n\r\n // Write updated content\r\n await writeFile(skillMdPath, updatedContent, 'utf-8');\r\n\r\n // Auto-commit if requested\r\n if (autoCommit) {\r\n const message = commitMessage || `Update ${basename(skillPath)} frontmatter`;\r\n await commitFile(skillMdPath, message);\r\n }\r\n\r\n // Return updated metadata\r\n return await loadSkillMetadata(skillPath);\r\n } catch (error) {\r\n throw new SkillContentError(\r\n `Failed to update skill frontmatter for ${skillPath}`,\r\n { error: error instanceof Error ? error.message : String(error) }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Create new skill directory with standard structure\r\n *\r\n * @param parentDir - Parent directory for skills\r\n * @param skillName - Name of skill to create\r\n * @param frontmatter - Initial frontmatter\r\n * @param content - Initial SKILL.md content\r\n * @returns Created skill metadata\r\n */\r\nexport async function createSkill(\r\n parentDir: string,\r\n skillName: string,\r\n frontmatter: SkillFrontmatter,\r\n content: string = ''\r\n): Promise<SkillMetadata> {\r\n const skillPath = join(parentDir, skillName);\r\n\r\n try {\r\n // Create skill directory\r\n await mkdir(skillPath, { recursive: true });\r\n\r\n // Create SKILL.md\r\n const skillMdPath = join(skillPath, 'SKILL.md');\r\n const skillDocument = createSkillDocument(frontmatter, content);\r\n await writeFile(skillMdPath, skillDocument, 'utf-8');\r\n\r\n // Create placeholder files\r\n const executeSh = `#!/bin/bash\r\n# ${frontmatter.name} - Execution Script\r\n# Version: ${frontmatter.version}\r\n\r\nset -euo pipefail\r\n\r\necho \"Executing ${frontmatter.name}...\"\r\n# Add implementation here\r\n`;\r\n\r\n const testSh = `#!/bin/bash\r\n# ${frontmatter.name} - Test Script\r\n# Version: ${frontmatter.version}\r\n\r\nset -euo pipefail\r\n\r\necho \"Testing ${frontmatter.name}...\"\r\n# Add tests here\r\n`;\r\n\r\n const validateSh = `#!/bin/bash\r\n# ${frontmatter.name} - Validation Script\r\n# Version: ${frontmatter.version}\r\n\r\nset -euo pipefail\r\n\r\necho \"Validating ${frontmatter.name}...\"\r\n# Add validation here\r\n`;\r\n\r\n const packageJson = {\r\n name: skillName,\r\n version: frontmatter.version,\r\n description: frontmatter.description,\r\n scripts: {\r\n execute: './execute.sh',\r\n test: './test.sh',\r\n validate: './validate.sh'\r\n }\r\n };\r\n\r\n await writeFile(join(skillPath, 'execute.sh'), executeSh, 'utf-8');\r\n await writeFile(join(skillPath, 'test.sh'), testSh, 'utf-8');\r\n await writeFile(join(skillPath, 'validate.sh'), validateSh, 'utf-8');\r\n await writeFile(join(skillPath, 'package.json'), JSON.stringify(packageJson, null, 2), 'utf-8');\r\n\r\n // Fix permissions\r\n await fixSkillPermissions(skillPath);\r\n\r\n // Return metadata\r\n return await loadSkillMetadata(skillPath);\r\n } catch (error) {\r\n throw new SkillContentError(\r\n `Failed to create skill ${skillName}`,\r\n { error: error instanceof Error ? error.message : String(error) }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Scan directory for all skills\r\n *\r\n * @param skillsDir - Path to skills directory\r\n * @returns Array of skill paths\r\n */\r\nexport async function scanSkills(skillsDir: string): Promise<string[]> {\r\n try {\r\n const entries = await readdir(skillsDir, { withFileTypes: true });\r\n const skillPaths: string[] = [];\r\n\r\n for (const entry of entries) {\r\n if (entry.isDirectory()) {\r\n const skillPath = join(skillsDir, entry.name);\r\n const skillMdPath = join(skillPath, 'SKILL.md');\r\n\r\n try {\r\n await access(skillMdPath, constants.F_OK);\r\n skillPaths.push(skillPath);\r\n } catch {\r\n // Not a valid skill directory, skip\r\n }\r\n }\r\n }\r\n\r\n return skillPaths.sort();\r\n } catch (error) {\r\n throw new SkillContentError(\r\n `Failed to scan skills directory ${skillsDir}`,\r\n { error: error instanceof Error ? error.message : String(error) }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Verify skill content integrity\r\n *\r\n * @param skillPath - Path to skill directory\r\n * @param expectedHash - Expected content hash\r\n * @returns True if content matches expected hash\r\n */\r\nexport async function verifySkillIntegrity(\r\n skillPath: string,\r\n expectedHash: string\r\n): Promise<boolean> {\r\n const skillMdPath = join(skillPath, 'SKILL.md');\r\n return await verifyContentIntegrity(skillMdPath, expectedHash);\r\n}\r\n"],"names":["join","basename","stat","readdir","access","chmod","readFile","writeFile","mkdir","constants","StandardError","parseFrontmatter","validateFrontmatter","parseAndValidate","updateFrontmatter","createSkillDocument","calculateFileHash","getCommitMetadata","getVersionHistory","commitFile","hasUncommittedChanges","verifyContentIntegrity","getFileCreationDate","getFileModificationDate","REQUIRED_SKILL_FILES","SkillContentError","message","context","name","validateSkillStructure","skillPath","skillName","missingFiles","invalidPermissions","errors","warnings","dirStat","isDirectory","push","valid","error","fileName","filePath","F_OK","endsWith","X_OK","skillMdPath","content","parsed","validation","frontmatter","Error","String","length","fixSkillPermissions","fixed","loadSkillMetadata","includeHistory","contentHash","gitMetadata","versionHistory","hasChanges","fileCreated","fileModified","updateSkillFrontmatter","updates","options","autoCommit","commitMessage","updateTimestamp","validateStructure","currentContent","updatedContent","createSkill","parentDir","recursive","skillDocument","executeSh","version","testSh","validateSh","packageJson","description","scripts","execute","test","validate","JSON","stringify","scanSkills","skillsDir","entries","withFileTypes","skillPaths","entry","sort","verifySkillIntegrity","expectedHash"],"mappings":"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"}
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Skill Frontmatter Parser
3
+ *
4
+ * Parses and validates YAML frontmatter in SKILL.md files
5
+ * Supports semantic versioning and comprehensive metadata tracking
6
+ *
7
+ * @module skill-frontmatter-parser
8
+ * @version 1.0.0
9
+ */ import * as yaml from 'js-yaml';
10
+ import { StandardError } from './errors.js';
11
+ /**
12
+ * Frontmatter parser error
13
+ */ export class FrontmatterParseError extends StandardError {
14
+ context;
15
+ constructor(message, context){
16
+ super('FRONTMATTER_PARSE_ERROR', message, context), this.context = context;
17
+ this.name = 'FrontmatterParseError';
18
+ }
19
+ }
20
+ /**
21
+ * Frontmatter validation error
22
+ */ export class FrontmatterValidationError extends StandardError {
23
+ errors;
24
+ constructor(message, errors){
25
+ super('FRONTMATTER_VALIDATION_ERROR', message, {
26
+ errors
27
+ }), this.errors = errors;
28
+ this.name = 'FrontmatterValidationError';
29
+ }
30
+ }
31
+ /**
32
+ * Semantic version regex pattern
33
+ */ const SEMVER_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
34
+ /**
35
+ * Valid skill status values
36
+ */ const VALID_STATUSES = [
37
+ 'draft',
38
+ 'approved',
39
+ 'staging',
40
+ 'deployed',
41
+ 'deprecated'
42
+ ];
43
+ /**
44
+ * Parse SKILL.md content and extract frontmatter
45
+ *
46
+ * @param content - Raw SKILL.md file content
47
+ * @returns Parsed document with frontmatter and content
48
+ * @throws FrontmatterParseError if parsing fails
49
+ */ export function parseFrontmatter(content) {
50
+ // Extract frontmatter block
51
+ const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
52
+ if (!frontmatterMatch) {
53
+ throw new FrontmatterParseError('No frontmatter block found. SKILL.md must start with YAML frontmatter enclosed in ---');
54
+ }
55
+ const [, frontmatterYaml, markdownContent] = frontmatterMatch;
56
+ // Parse YAML
57
+ let frontmatter;
58
+ try {
59
+ frontmatter = yaml.load(frontmatterYaml);
60
+ } catch (error) {
61
+ throw new FrontmatterParseError('Failed to parse YAML frontmatter', {
62
+ error: error instanceof Error ? error.message : String(error),
63
+ yaml: frontmatterYaml.substring(0, 200)
64
+ });
65
+ }
66
+ // Validate structure
67
+ if (!frontmatter || typeof frontmatter !== 'object') {
68
+ throw new FrontmatterParseError('Frontmatter must be a valid YAML object');
69
+ }
70
+ return {
71
+ frontmatter: frontmatter,
72
+ content: markdownContent.trim(),
73
+ raw: content
74
+ };
75
+ }
76
+ /**
77
+ * Validate frontmatter against schema
78
+ *
79
+ * @param frontmatter - Frontmatter object to validate
80
+ * @returns Validation result with errors and warnings
81
+ */ export function validateFrontmatter(frontmatter) {
82
+ const errors = [];
83
+ const warnings = [];
84
+ // Required fields
85
+ if (!frontmatter.name || typeof frontmatter.name !== 'string') {
86
+ errors.push('Field "name" is required and must be a string');
87
+ }
88
+ if (!frontmatter.version || typeof frontmatter.version !== 'string') {
89
+ errors.push('Field "version" is required and must be a string');
90
+ } else if (!SEMVER_PATTERN.test(frontmatter.version)) {
91
+ errors.push(`Field "version" must be valid semantic version (e.g., 1.0.0), got: ${frontmatter.version}`);
92
+ }
93
+ if (!Array.isArray(frontmatter.tags)) {
94
+ errors.push('Field "tags" is required and must be an array');
95
+ } else if (frontmatter.tags.length === 0) {
96
+ warnings.push('Field "tags" is empty, consider adding tags for categorization');
97
+ } else if (!frontmatter.tags.every((tag)=>typeof tag === 'string')) {
98
+ errors.push('All tags must be strings');
99
+ }
100
+ if (!frontmatter.status) {
101
+ errors.push('Field "status" is required');
102
+ } else if (!VALID_STATUSES.includes(frontmatter.status)) {
103
+ errors.push(`Field "status" must be one of: ${VALID_STATUSES.join(', ')}, got: ${frontmatter.status}`);
104
+ }
105
+ if (!frontmatter.author || typeof frontmatter.author !== 'string') {
106
+ errors.push('Field "author" is required and must be a string');
107
+ }
108
+ if (!frontmatter.description || typeof frontmatter.description !== 'string') {
109
+ errors.push('Field "description" is required and must be a string');
110
+ } else if (frontmatter.description.length < 10) {
111
+ warnings.push('Field "description" is very short, consider adding more detail');
112
+ }
113
+ // Optional fields validation
114
+ if (frontmatter.dependencies !== undefined) {
115
+ if (!Array.isArray(frontmatter.dependencies)) {
116
+ errors.push('Field "dependencies" must be an array if provided');
117
+ } else if (!frontmatter.dependencies.every((dep)=>typeof dep === 'string')) {
118
+ errors.push('All dependencies must be strings');
119
+ }
120
+ }
121
+ if (frontmatter.created !== undefined && typeof frontmatter.created !== 'string') {
122
+ errors.push('Field "created" must be a string (ISO date) if provided');
123
+ }
124
+ if (frontmatter.updated !== undefined && typeof frontmatter.updated !== 'string') {
125
+ errors.push('Field "updated" must be a string (ISO date) if provided');
126
+ }
127
+ // Date validation
128
+ if (frontmatter.created) {
129
+ const createdDate = new Date(frontmatter.created);
130
+ if (isNaN(createdDate.getTime())) {
131
+ errors.push(`Field "created" is not a valid date: ${frontmatter.created}`);
132
+ }
133
+ }
134
+ if (frontmatter.updated) {
135
+ const updatedDate = new Date(frontmatter.updated);
136
+ if (isNaN(updatedDate.getTime())) {
137
+ errors.push(`Field "updated" is not a valid date: ${frontmatter.updated}`);
138
+ }
139
+ // Check if updated is after created
140
+ if (frontmatter.created) {
141
+ const createdDate = new Date(frontmatter.created);
142
+ const updatedDate = new Date(frontmatter.updated);
143
+ if (updatedDate < createdDate) {
144
+ errors.push('Field "updated" cannot be before "created"');
145
+ }
146
+ }
147
+ }
148
+ return {
149
+ valid: errors.length === 0,
150
+ errors,
151
+ warnings
152
+ };
153
+ }
154
+ /**
155
+ * Parse and validate SKILL.md content
156
+ *
157
+ * @param content - Raw SKILL.md file content
158
+ * @returns Parsed and validated document
159
+ * @throws FrontmatterValidationError if validation fails
160
+ */ export function parseAndValidate(content) {
161
+ const parsed = parseFrontmatter(content);
162
+ const validation = validateFrontmatter(parsed.frontmatter);
163
+ if (!validation.valid) {
164
+ throw new FrontmatterValidationError('Frontmatter validation failed', validation.errors);
165
+ }
166
+ return parsed;
167
+ }
168
+ /**
169
+ * Serialize frontmatter to YAML string
170
+ *
171
+ * @param frontmatter - Frontmatter object to serialize
172
+ * @returns YAML string representation
173
+ */ export function serializeFrontmatter(frontmatter) {
174
+ return yaml.dump(frontmatter, {
175
+ indent: 2,
176
+ lineWidth: 100,
177
+ noRefs: true,
178
+ sortKeys: false
179
+ });
180
+ }
181
+ /**
182
+ * Update frontmatter in SKILL.md content
183
+ *
184
+ * @param content - Original SKILL.md content
185
+ * @param updates - Partial frontmatter updates
186
+ * @returns Updated SKILL.md content
187
+ */ export function updateFrontmatter(content, updates) {
188
+ const parsed = parseFrontmatter(content);
189
+ const updated = {
190
+ ...parsed.frontmatter,
191
+ ...updates
192
+ };
193
+ // Update timestamp
194
+ updated.updated = new Date().toISOString().split('T')[0];
195
+ const yamlString = serializeFrontmatter(updated);
196
+ return `---\n${yamlString}---\n${parsed.content}`;
197
+ }
198
+ /**
199
+ * Create new SKILL.md content with frontmatter
200
+ *
201
+ * @param frontmatter - Frontmatter object
202
+ * @param content - Markdown content
203
+ * @returns Complete SKILL.md content
204
+ */ export function createSkillDocument(frontmatter, content) {
205
+ // Validate before creating
206
+ const validation = validateFrontmatter(frontmatter);
207
+ if (!validation.valid) {
208
+ throw new FrontmatterValidationError('Cannot create skill document with invalid frontmatter', validation.errors);
209
+ }
210
+ const yamlString = serializeFrontmatter(frontmatter);
211
+ return `---\n${yamlString}---\n${content}`;
212
+ }
213
+ /**
214
+ * Extract frontmatter summary for display
215
+ *
216
+ * @param frontmatter - Frontmatter object
217
+ * @returns Human-readable summary
218
+ */ export function getFrontmatterSummary(frontmatter) {
219
+ return `${frontmatter.name} v${frontmatter.version} [${frontmatter.status}]`;
220
+ }
221
+ /**
222
+ * Compare two versions using semantic versioning
223
+ *
224
+ * @param version1 - First version string
225
+ * @param version2 - Second version string
226
+ * @returns -1 if v1 < v2, 0 if equal, 1 if v1 > v2
227
+ */ export function compareVersions(version1, version2) {
228
+ const v1Parts = version1.split('.').map(Number);
229
+ const v2Parts = version2.split('.').map(Number);
230
+ for(let i = 0; i < 3; i++){
231
+ if (v1Parts[i] > v2Parts[i]) return 1;
232
+ if (v1Parts[i] < v2Parts[i]) return -1;
233
+ }
234
+ return 0;
235
+ }
236
+
237
+ //# sourceMappingURL=skill-frontmatter-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/skill-frontmatter-parser.ts"],"sourcesContent":["/**\r\n * Skill Frontmatter Parser\r\n *\r\n * Parses and validates YAML frontmatter in SKILL.md files\r\n * Supports semantic versioning and comprehensive metadata tracking\r\n *\r\n * @module skill-frontmatter-parser\r\n * @version 1.0.0\r\n */\r\n\r\nimport * as yaml from 'js-yaml';\r\nimport { StandardError } from './errors.js';\r\n\r\n/**\r\n * Skill status lifecycle stages\r\n */\r\nexport type SkillStatus = 'draft' | 'approved' | 'staging' | 'deployed' | 'deprecated';\r\n\r\n/**\r\n * Skill frontmatter schema\r\n */\r\nexport interface SkillFrontmatter {\r\n name: string;\r\n version: string;\r\n tags: string[];\r\n status: SkillStatus;\r\n author: string;\r\n description: string;\r\n dependencies?: string[];\r\n created?: string;\r\n updated?: string;\r\n\r\n // Optional extended metadata\r\n complexity?: 'Low' | 'Medium' | 'High';\r\n keywords?: string[];\r\n triggers?: string[];\r\n performance_targets?: Record<string, number | string>;\r\n}\r\n\r\n/**\r\n * Parsed frontmatter with content\r\n */\r\nexport interface ParsedSkillDocument {\r\n frontmatter: SkillFrontmatter;\r\n content: string;\r\n raw: string;\r\n}\r\n\r\n/**\r\n * Frontmatter validation result\r\n */\r\nexport interface ValidationResult {\r\n valid: boolean;\r\n errors: string[];\r\n warnings: string[];\r\n}\r\n\r\n/**\r\n * Frontmatter parser error\r\n */\r\nexport class FrontmatterParseError extends StandardError {\r\n constructor(message: string, public readonly context?: Record<string, unknown>) {\r\n super('FRONTMATTER_PARSE_ERROR', message, context);\r\n this.name = 'FrontmatterParseError';\r\n }\r\n}\r\n\r\n/**\r\n * Frontmatter validation error\r\n */\r\nexport class FrontmatterValidationError extends StandardError {\r\n constructor(message: string, public readonly errors: string[]) {\r\n super('FRONTMATTER_VALIDATION_ERROR', message, { errors });\r\n this.name = 'FrontmatterValidationError';\r\n }\r\n}\r\n\r\n/**\r\n * Semantic version regex pattern\r\n */\r\nconst SEMVER_PATTERN = /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/;\r\n\r\n/**\r\n * Valid skill status values\r\n */\r\nconst VALID_STATUSES: SkillStatus[] = ['draft', 'approved', 'staging', 'deployed', 'deprecated'];\r\n\r\n/**\r\n * Parse SKILL.md content and extract frontmatter\r\n *\r\n * @param content - Raw SKILL.md file content\r\n * @returns Parsed document with frontmatter and content\r\n * @throws FrontmatterParseError if parsing fails\r\n */\r\nexport function parseFrontmatter(content: string): ParsedSkillDocument {\r\n // Extract frontmatter block\r\n const frontmatterMatch = content.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n([\\s\\S]*)$/);\r\n\r\n if (!frontmatterMatch) {\r\n throw new FrontmatterParseError('No frontmatter block found. SKILL.md must start with YAML frontmatter enclosed in ---');\r\n }\r\n\r\n const [, frontmatterYaml, markdownContent] = frontmatterMatch;\r\n\r\n // Parse YAML\r\n let frontmatter: unknown;\r\n try {\r\n frontmatter = yaml.load(frontmatterYaml);\r\n } catch (error) {\r\n throw new FrontmatterParseError(\r\n 'Failed to parse YAML frontmatter',\r\n {\r\n error: error instanceof Error ? error.message : String(error),\r\n yaml: frontmatterYaml.substring(0, 200)\r\n }\r\n );\r\n }\r\n\r\n // Validate structure\r\n if (!frontmatter || typeof frontmatter !== 'object') {\r\n throw new FrontmatterParseError('Frontmatter must be a valid YAML object');\r\n }\r\n\r\n return {\r\n frontmatter: frontmatter as SkillFrontmatter,\r\n content: markdownContent.trim(),\r\n raw: content\r\n };\r\n}\r\n\r\n/**\r\n * Validate frontmatter against schema\r\n *\r\n * @param frontmatter - Frontmatter object to validate\r\n * @returns Validation result with errors and warnings\r\n */\r\nexport function validateFrontmatter(frontmatter: SkillFrontmatter): ValidationResult {\r\n const errors: string[] = [];\r\n const warnings: string[] = [];\r\n\r\n // Required fields\r\n if (!frontmatter.name || typeof frontmatter.name !== 'string') {\r\n errors.push('Field \"name\" is required and must be a string');\r\n }\r\n\r\n if (!frontmatter.version || typeof frontmatter.version !== 'string') {\r\n errors.push('Field \"version\" is required and must be a string');\r\n } else if (!SEMVER_PATTERN.test(frontmatter.version)) {\r\n errors.push(`Field \"version\" must be valid semantic version (e.g., 1.0.0), got: ${frontmatter.version}`);\r\n }\r\n\r\n if (!Array.isArray(frontmatter.tags)) {\r\n errors.push('Field \"tags\" is required and must be an array');\r\n } else if (frontmatter.tags.length === 0) {\r\n warnings.push('Field \"tags\" is empty, consider adding tags for categorization');\r\n } else if (!frontmatter.tags.every(tag => typeof tag === 'string')) {\r\n errors.push('All tags must be strings');\r\n }\r\n\r\n if (!frontmatter.status) {\r\n errors.push('Field \"status\" is required');\r\n } else if (!VALID_STATUSES.includes(frontmatter.status)) {\r\n errors.push(`Field \"status\" must be one of: ${VALID_STATUSES.join(', ')}, got: ${frontmatter.status}`);\r\n }\r\n\r\n if (!frontmatter.author || typeof frontmatter.author !== 'string') {\r\n errors.push('Field \"author\" is required and must be a string');\r\n }\r\n\r\n if (!frontmatter.description || typeof frontmatter.description !== 'string') {\r\n errors.push('Field \"description\" is required and must be a string');\r\n } else if (frontmatter.description.length < 10) {\r\n warnings.push('Field \"description\" is very short, consider adding more detail');\r\n }\r\n\r\n // Optional fields validation\r\n if (frontmatter.dependencies !== undefined) {\r\n if (!Array.isArray(frontmatter.dependencies)) {\r\n errors.push('Field \"dependencies\" must be an array if provided');\r\n } else if (!frontmatter.dependencies.every(dep => typeof dep === 'string')) {\r\n errors.push('All dependencies must be strings');\r\n }\r\n }\r\n\r\n if (frontmatter.created !== undefined && typeof frontmatter.created !== 'string') {\r\n errors.push('Field \"created\" must be a string (ISO date) if provided');\r\n }\r\n\r\n if (frontmatter.updated !== undefined && typeof frontmatter.updated !== 'string') {\r\n errors.push('Field \"updated\" must be a string (ISO date) if provided');\r\n }\r\n\r\n // Date validation\r\n if (frontmatter.created) {\r\n const createdDate = new Date(frontmatter.created);\r\n if (isNaN(createdDate.getTime())) {\r\n errors.push(`Field \"created\" is not a valid date: ${frontmatter.created}`);\r\n }\r\n }\r\n\r\n if (frontmatter.updated) {\r\n const updatedDate = new Date(frontmatter.updated);\r\n if (isNaN(updatedDate.getTime())) {\r\n errors.push(`Field \"updated\" is not a valid date: ${frontmatter.updated}`);\r\n }\r\n\r\n // Check if updated is after created\r\n if (frontmatter.created) {\r\n const createdDate = new Date(frontmatter.created);\r\n const updatedDate = new Date(frontmatter.updated);\r\n if (updatedDate < createdDate) {\r\n errors.push('Field \"updated\" cannot be before \"created\"');\r\n }\r\n }\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n warnings\r\n };\r\n}\r\n\r\n/**\r\n * Parse and validate SKILL.md content\r\n *\r\n * @param content - Raw SKILL.md file content\r\n * @returns Parsed and validated document\r\n * @throws FrontmatterValidationError if validation fails\r\n */\r\nexport function parseAndValidate(content: string): ParsedSkillDocument {\r\n const parsed = parseFrontmatter(content);\r\n const validation = validateFrontmatter(parsed.frontmatter);\r\n\r\n if (!validation.valid) {\r\n throw new FrontmatterValidationError(\r\n 'Frontmatter validation failed',\r\n validation.errors\r\n );\r\n }\r\n\r\n return parsed;\r\n}\r\n\r\n/**\r\n * Serialize frontmatter to YAML string\r\n *\r\n * @param frontmatter - Frontmatter object to serialize\r\n * @returns YAML string representation\r\n */\r\nexport function serializeFrontmatter(frontmatter: SkillFrontmatter): string {\r\n return yaml.dump(frontmatter, {\r\n indent: 2,\r\n lineWidth: 100,\r\n noRefs: true,\r\n sortKeys: false\r\n });\r\n}\r\n\r\n/**\r\n * Update frontmatter in SKILL.md content\r\n *\r\n * @param content - Original SKILL.md content\r\n * @param updates - Partial frontmatter updates\r\n * @returns Updated SKILL.md content\r\n */\r\nexport function updateFrontmatter(\r\n content: string,\r\n updates: Partial<SkillFrontmatter>\r\n): string {\r\n const parsed = parseFrontmatter(content);\r\n const updated = { ...parsed.frontmatter, ...updates };\r\n\r\n // Update timestamp\r\n updated.updated = new Date().toISOString().split('T')[0];\r\n\r\n const yamlString = serializeFrontmatter(updated);\r\n return `---\\n${yamlString}---\\n${parsed.content}`;\r\n}\r\n\r\n/**\r\n * Create new SKILL.md content with frontmatter\r\n *\r\n * @param frontmatter - Frontmatter object\r\n * @param content - Markdown content\r\n * @returns Complete SKILL.md content\r\n */\r\nexport function createSkillDocument(\r\n frontmatter: SkillFrontmatter,\r\n content: string\r\n): string {\r\n // Validate before creating\r\n const validation = validateFrontmatter(frontmatter);\r\n if (!validation.valid) {\r\n throw new FrontmatterValidationError(\r\n 'Cannot create skill document with invalid frontmatter',\r\n validation.errors\r\n );\r\n }\r\n\r\n const yamlString = serializeFrontmatter(frontmatter);\r\n return `---\\n${yamlString}---\\n${content}`;\r\n}\r\n\r\n/**\r\n * Extract frontmatter summary for display\r\n *\r\n * @param frontmatter - Frontmatter object\r\n * @returns Human-readable summary\r\n */\r\nexport function getFrontmatterSummary(frontmatter: SkillFrontmatter): string {\r\n return `${frontmatter.name} v${frontmatter.version} [${frontmatter.status}]`;\r\n}\r\n\r\n/**\r\n * Compare two versions using semantic versioning\r\n *\r\n * @param version1 - First version string\r\n * @param version2 - Second version string\r\n * @returns -1 if v1 < v2, 0 if equal, 1 if v1 > v2\r\n */\r\nexport function compareVersions(version1: string, version2: string): number {\r\n const v1Parts = version1.split('.').map(Number);\r\n const v2Parts = version2.split('.').map(Number);\r\n\r\n for (let i = 0; i < 3; i++) {\r\n if (v1Parts[i] > v2Parts[i]) return 1;\r\n if (v1Parts[i] < v2Parts[i]) return -1;\r\n }\r\n\r\n return 0;\r\n}\r\n"],"names":["yaml","StandardError","FrontmatterParseError","message","context","name","FrontmatterValidationError","errors","SEMVER_PATTERN","VALID_STATUSES","parseFrontmatter","content","frontmatterMatch","match","frontmatterYaml","markdownContent","frontmatter","load","error","Error","String","substring","trim","raw","validateFrontmatter","warnings","push","version","test","Array","isArray","tags","length","every","tag","status","includes","join","author","description","dependencies","undefined","dep","created","updated","createdDate","Date","isNaN","getTime","updatedDate","valid","parseAndValidate","parsed","validation","serializeFrontmatter","dump","indent","lineWidth","noRefs","sortKeys","updateFrontmatter","updates","toISOString","split","yamlString","createSkillDocument","getFrontmatterSummary","compareVersions","version1","version2","v1Parts","map","Number","v2Parts","i"],"mappings":"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"}
@@ -0,0 +1,275 @@
1
+ /**
2
+ * Skill Git Integration
3
+ *
4
+ * Manages version tracking, content hashing, and git metadata for skills
5
+ * Provides atomic updates with rollback capabilities
6
+ *
7
+ * @module skill-git-integration
8
+ * @version 1.0.0
9
+ */ import { exec } from 'child_process';
10
+ import { promisify } from 'util';
11
+ import { createHash } from 'crypto';
12
+ import { readFile } from 'fs/promises';
13
+ import { StandardError } from './errors.js';
14
+ const execAsync = promisify(exec);
15
+ /**
16
+ * Git integration error
17
+ */ export class GitIntegrationError extends StandardError {
18
+ context;
19
+ constructor(message, context){
20
+ super('GIT_INTEGRATION_ERROR', message, context), this.context = context;
21
+ this.name = 'GitIntegrationError';
22
+ }
23
+ }
24
+ /**
25
+ * Calculate SHA256 hash of file content
26
+ *
27
+ * @param content - File content string
28
+ * @returns SHA256 hash in hexadecimal
29
+ */ export function calculateContentHash(content) {
30
+ return createHash('sha256').update(content).digest('hex');
31
+ }
32
+ /**
33
+ * Calculate SHA256 hash of file
34
+ *
35
+ * @param filePath - Path to file
36
+ * @returns SHA256 hash in hexadecimal
37
+ */ export async function calculateFileHash(filePath) {
38
+ try {
39
+ const content = await readFile(filePath, 'utf-8');
40
+ return calculateContentHash(content);
41
+ } catch (error) {
42
+ throw new GitIntegrationError(`Failed to calculate file hash for ${filePath}`, {
43
+ error: error instanceof Error ? error.message : String(error)
44
+ });
45
+ }
46
+ }
47
+ /**
48
+ * Check if a path is in a git repository
49
+ *
50
+ * @param filePath - Path to check
51
+ * @returns True if in git repository
52
+ */ export async function isGitRepository(filePath) {
53
+ try {
54
+ await execAsync('git rev-parse --is-inside-work-tree', {
55
+ cwd: filePath
56
+ });
57
+ return true;
58
+ } catch {
59
+ return false;
60
+ }
61
+ }
62
+ /**
63
+ * Get git commit metadata for a file
64
+ *
65
+ * @param filePath - Path to file
66
+ * @param commitRef - Git commit reference (default: HEAD)
67
+ * @returns Commit metadata
68
+ */ export async function getCommitMetadata(filePath, commitRef = 'HEAD') {
69
+ try {
70
+ const { stdout } = await execAsync(`git log -1 --format="%H%n%an%n%ae%n%ai%n%s" ${commitRef} -- "${filePath}"`);
71
+ const [hash, author, email, date, message] = stdout.trim().split('\n');
72
+ if (!hash) {
73
+ throw new GitIntegrationError('No git history found for file', {
74
+ filePath
75
+ });
76
+ }
77
+ return {
78
+ hash,
79
+ author,
80
+ email,
81
+ date,
82
+ message: message || 'No commit message'
83
+ };
84
+ } catch (error) {
85
+ throw new GitIntegrationError(`Failed to get git metadata for ${filePath}`, {
86
+ error: error instanceof Error ? error.message : String(error)
87
+ });
88
+ }
89
+ }
90
+ /**
91
+ * Get version history for a skill file
92
+ *
93
+ * @param filePath - Path to SKILL.md file
94
+ * @param limit - Maximum number of entries (default: 10)
95
+ * @returns Array of version history entries
96
+ */ export async function getVersionHistory(filePath, limit = 10) {
97
+ try {
98
+ // Get commit history
99
+ const { stdout } = await execAsync(`git log -${limit} --format="%H" -- "${filePath}"`);
100
+ const commits = stdout.trim().split('\n').filter(Boolean);
101
+ const history = [];
102
+ for (const commitHash of commits){
103
+ try {
104
+ // Get file content at this commit
105
+ const { stdout: content } = await execAsync(`git show ${commitHash}:"${filePath}"`);
106
+ // Get commit metadata
107
+ const metadata = await getCommitMetadata(filePath, commitHash);
108
+ // Calculate content hash
109
+ const contentHash = calculateContentHash(content);
110
+ // Extract version from content (if available in frontmatter)
111
+ const versionMatch = content.match(/version:\s*["']?([0-9.]+)["']?/);
112
+ const version = versionMatch ? versionMatch[1] : 'unknown';
113
+ history.push({
114
+ version,
115
+ commit: metadata,
116
+ contentHash,
117
+ timestamp: metadata.date,
118
+ filePath
119
+ });
120
+ } catch (error) {
121
+ continue;
122
+ }
123
+ }
124
+ return history;
125
+ } catch (error) {
126
+ throw new GitIntegrationError(`Failed to get version history for ${filePath}`, {
127
+ error: error instanceof Error ? error.message : String(error)
128
+ });
129
+ }
130
+ }
131
+ /**
132
+ * Stage and commit a file with atomic operation
133
+ *
134
+ * @param filePath - Path to file to commit
135
+ * @param message - Commit message
136
+ * @returns Git operation result
137
+ */ export async function commitFile(filePath, message) {
138
+ try {
139
+ // Stage file
140
+ await execAsync(`git add "${filePath}"`);
141
+ // Commit
142
+ const { stdout } = await execAsync(`git commit -m "${message}"`);
143
+ // Get commit hash
144
+ const { stdout: hashOutput } = await execAsync('git rev-parse HEAD');
145
+ const commitHash = hashOutput.trim();
146
+ return {
147
+ success: true,
148
+ commitHash
149
+ };
150
+ } catch (error) {
151
+ return {
152
+ success: false,
153
+ error: error instanceof Error ? error.message : String(error)
154
+ };
155
+ }
156
+ }
157
+ /**
158
+ * Rollback file to previous commit
159
+ *
160
+ * @param filePath - Path to file to rollback
161
+ * @param commitRef - Git commit reference to rollback to (default: HEAD~1)
162
+ * @returns Git operation result
163
+ */ export async function rollbackFile(filePath, commitRef = 'HEAD~1') {
164
+ try {
165
+ // Checkout file from previous commit
166
+ await execAsync(`git checkout ${commitRef} -- "${filePath}"`);
167
+ // Commit the rollback
168
+ const message = `Rollback ${filePath} to ${commitRef}`;
169
+ return await commitFile(filePath, message);
170
+ } catch (error) {
171
+ return {
172
+ success: false,
173
+ error: error instanceof Error ? error.message : String(error)
174
+ };
175
+ }
176
+ }
177
+ /**
178
+ * Check if file has uncommitted changes
179
+ *
180
+ * @param filePath - Path to file
181
+ * @returns True if file has uncommitted changes
182
+ */ export async function hasUncommittedChanges(filePath) {
183
+ try {
184
+ const { stdout } = await execAsync(`git status --porcelain "${filePath}"`);
185
+ return stdout.trim().length > 0;
186
+ } catch (error) {
187
+ throw new GitIntegrationError(`Failed to check git status for ${filePath}`, {
188
+ error: error instanceof Error ? error.message : String(error)
189
+ });
190
+ }
191
+ }
192
+ /**
193
+ * Get current git branch
194
+ *
195
+ * @returns Current branch name
196
+ */ export async function getCurrentBranch() {
197
+ try {
198
+ const { stdout } = await execAsync('git rev-parse --abbrev-ref HEAD');
199
+ return stdout.trim();
200
+ } catch (error) {
201
+ throw new GitIntegrationError('Failed to get current branch', {
202
+ error: error instanceof Error ? error.message : String(error)
203
+ });
204
+ }
205
+ }
206
+ /**
207
+ * Get file diff between two commits
208
+ *
209
+ * @param filePath - Path to file
210
+ * @param commitRef1 - First commit reference
211
+ * @param commitRef2 - Second commit reference (default: HEAD)
212
+ * @returns Diff output
213
+ */ export async function getFileDiff(filePath, commitRef1, commitRef2 = 'HEAD') {
214
+ try {
215
+ const { stdout } = await execAsync(`git diff ${commitRef1} ${commitRef2} -- "${filePath}"`);
216
+ return stdout;
217
+ } catch (error) {
218
+ throw new GitIntegrationError(`Failed to get diff for ${filePath}`, {
219
+ error: error instanceof Error ? error.message : String(error)
220
+ });
221
+ }
222
+ }
223
+ /**
224
+ * Verify content integrity using git hash
225
+ *
226
+ * @param filePath - Path to file
227
+ * @param expectedHash - Expected content hash
228
+ * @returns True if content matches expected hash
229
+ */ export async function verifyContentIntegrity(filePath, expectedHash) {
230
+ try {
231
+ const actualHash = await calculateFileHash(filePath);
232
+ return actualHash === expectedHash;
233
+ } catch (error) {
234
+ throw new GitIntegrationError(`Failed to verify content integrity for ${filePath}`, {
235
+ error: error instanceof Error ? error.message : String(error)
236
+ });
237
+ }
238
+ }
239
+ /**
240
+ * Get file creation date from git history
241
+ *
242
+ * @param filePath - Path to file
243
+ * @returns ISO date string of first commit
244
+ */ export async function getFileCreationDate(filePath) {
245
+ try {
246
+ const { stdout } = await execAsync(`git log --diff-filter=A --follow --format="%ai" -- "${filePath}" | tail -1`);
247
+ if (!stdout.trim()) {
248
+ throw new GitIntegrationError('No creation date found in git history', {
249
+ filePath
250
+ });
251
+ }
252
+ return new Date(stdout.trim()).toISOString();
253
+ } catch (error) {
254
+ throw new GitIntegrationError(`Failed to get creation date for ${filePath}`, {
255
+ error: error instanceof Error ? error.message : String(error)
256
+ });
257
+ }
258
+ }
259
+ /**
260
+ * Get file last modification date from git history
261
+ *
262
+ * @param filePath - Path to file
263
+ * @returns ISO date string of last commit
264
+ */ export async function getFileModificationDate(filePath) {
265
+ try {
266
+ const metadata = await getCommitMetadata(filePath);
267
+ return new Date(metadata.date).toISOString();
268
+ } catch (error) {
269
+ throw new GitIntegrationError(`Failed to get modification date for ${filePath}`, {
270
+ error: error instanceof Error ? error.message : String(error)
271
+ });
272
+ }
273
+ }
274
+
275
+ //# sourceMappingURL=skill-git-integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/skill-git-integration.ts"],"sourcesContent":["/**\r\n * Skill Git Integration\r\n *\r\n * Manages version tracking, content hashing, and git metadata for skills\r\n * Provides atomic updates with rollback capabilities\r\n *\r\n * @module skill-git-integration\r\n * @version 1.0.0\r\n */\r\n\r\nimport { exec } from 'child_process';\r\nimport { promisify } from 'util';\r\nimport { createHash } from 'crypto';\r\nimport { readFile } from 'fs/promises';\r\nimport { StandardError } from './errors.js';\r\n\r\nconst execAsync = promisify(exec);\r\n\r\n/**\r\n * Git commit metadata\r\n */\r\nexport interface GitCommitMetadata {\r\n hash: string;\r\n author: string;\r\n email: string;\r\n date: string;\r\n message: string;\r\n}\r\n\r\n/**\r\n * Version history entry\r\n */\r\nexport interface VersionHistoryEntry {\r\n version: string;\r\n commit: GitCommitMetadata;\r\n contentHash: string;\r\n timestamp: string;\r\n filePath: string;\r\n}\r\n\r\n/**\r\n * Git operation result\r\n */\r\nexport interface GitOperationResult {\r\n success: boolean;\r\n commitHash?: string;\r\n error?: string;\r\n}\r\n\r\n/**\r\n * Git integration error\r\n */\r\nexport class GitIntegrationError extends StandardError {\r\n constructor(message: string, public readonly context?: Record<string, unknown>) {\r\n super('GIT_INTEGRATION_ERROR', message, context);\r\n this.name = 'GitIntegrationError';\r\n }\r\n}\r\n\r\n/**\r\n * Calculate SHA256 hash of file content\r\n *\r\n * @param content - File content string\r\n * @returns SHA256 hash in hexadecimal\r\n */\r\nexport function calculateContentHash(content: string): string {\r\n return createHash('sha256').update(content).digest('hex');\r\n}\r\n\r\n/**\r\n * Calculate SHA256 hash of file\r\n *\r\n * @param filePath - Path to file\r\n * @returns SHA256 hash in hexadecimal\r\n */\r\nexport async function calculateFileHash(filePath: string): Promise<string> {\r\n try {\r\n const content = await readFile(filePath, 'utf-8');\r\n return calculateContentHash(content);\r\n } catch (error) {\r\n throw new GitIntegrationError(\r\n `Failed to calculate file hash for ${filePath}`,\r\n { error: error instanceof Error ? error.message : String(error) }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Check if a path is in a git repository\r\n *\r\n * @param filePath - Path to check\r\n * @returns True if in git repository\r\n */\r\nexport async function isGitRepository(filePath: string): Promise<boolean> {\r\n try {\r\n await execAsync('git rev-parse --is-inside-work-tree', {\r\n cwd: filePath\r\n });\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Get git commit metadata for a file\r\n *\r\n * @param filePath - Path to file\r\n * @param commitRef - Git commit reference (default: HEAD)\r\n * @returns Commit metadata\r\n */\r\nexport async function getCommitMetadata(\r\n filePath: string,\r\n commitRef: string = 'HEAD'\r\n): Promise<GitCommitMetadata> {\r\n try {\r\n const { stdout } = await execAsync(\r\n `git log -1 --format=\"%H%n%an%n%ae%n%ai%n%s\" ${commitRef} -- \"${filePath}\"`\r\n );\r\n\r\n const [hash, author, email, date, message] = stdout.trim().split('\\n');\r\n\r\n if (!hash) {\r\n throw new GitIntegrationError('No git history found for file', { filePath });\r\n }\r\n\r\n return {\r\n hash,\r\n author,\r\n email,\r\n date,\r\n message: message || 'No commit message'\r\n };\r\n } catch (error) {\r\n throw new GitIntegrationError(\r\n `Failed to get git metadata for ${filePath}`,\r\n { error: error instanceof Error ? error.message : String(error) }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Get version history for a skill file\r\n *\r\n * @param filePath - Path to SKILL.md file\r\n * @param limit - Maximum number of entries (default: 10)\r\n * @returns Array of version history entries\r\n */\r\nexport async function getVersionHistory(\r\n filePath: string,\r\n limit: number = 10\r\n): Promise<VersionHistoryEntry[]> {\r\n try {\r\n // Get commit history\r\n const { stdout } = await execAsync(\r\n `git log -${limit} --format=\"%H\" -- \"${filePath}\"`\r\n );\r\n\r\n const commits = stdout.trim().split('\\n').filter(Boolean);\r\n const history: VersionHistoryEntry[] = [];\r\n\r\n for (const commitHash of commits) {\r\n try {\r\n // Get file content at this commit\r\n const { stdout: content } = await execAsync(\r\n `git show ${commitHash}:\"${filePath}\"`\r\n );\r\n\r\n // Get commit metadata\r\n const metadata = await getCommitMetadata(filePath, commitHash);\r\n\r\n // Calculate content hash\r\n const contentHash = calculateContentHash(content);\r\n\r\n // Extract version from content (if available in frontmatter)\r\n const versionMatch = content.match(/version:\\s*[\"']?([0-9.]+)[\"']?/);\r\n const version = versionMatch ? versionMatch[1] : 'unknown';\r\n\r\n history.push({\r\n version,\r\n commit: metadata,\r\n contentHash,\r\n timestamp: metadata.date,\r\n filePath\r\n });\r\n } catch (error) {\r\n // Skip commits where file doesn't exist\r\n continue;\r\n }\r\n }\r\n\r\n return history;\r\n } catch (error) {\r\n throw new GitIntegrationError(\r\n `Failed to get version history for ${filePath}`,\r\n { error: error instanceof Error ? error.message : String(error) }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Stage and commit a file with atomic operation\r\n *\r\n * @param filePath - Path to file to commit\r\n * @param message - Commit message\r\n * @returns Git operation result\r\n */\r\nexport async function commitFile(\r\n filePath: string,\r\n message: string\r\n): Promise<GitOperationResult> {\r\n try {\r\n // Stage file\r\n await execAsync(`git add \"${filePath}\"`);\r\n\r\n // Commit\r\n const { stdout } = await execAsync(`git commit -m \"${message}\"`);\r\n\r\n // Get commit hash\r\n const { stdout: hashOutput } = await execAsync('git rev-parse HEAD');\r\n const commitHash = hashOutput.trim();\r\n\r\n return {\r\n success: true,\r\n commitHash\r\n };\r\n } catch (error) {\r\n return {\r\n success: false,\r\n error: error instanceof Error ? error.message : String(error)\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Rollback file to previous commit\r\n *\r\n * @param filePath - Path to file to rollback\r\n * @param commitRef - Git commit reference to rollback to (default: HEAD~1)\r\n * @returns Git operation result\r\n */\r\nexport async function rollbackFile(\r\n filePath: string,\r\n commitRef: string = 'HEAD~1'\r\n): Promise<GitOperationResult> {\r\n try {\r\n // Checkout file from previous commit\r\n await execAsync(`git checkout ${commitRef} -- \"${filePath}\"`);\r\n\r\n // Commit the rollback\r\n const message = `Rollback ${filePath} to ${commitRef}`;\r\n return await commitFile(filePath, message);\r\n } catch (error) {\r\n return {\r\n success: false,\r\n error: error instanceof Error ? error.message : String(error)\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Check if file has uncommitted changes\r\n *\r\n * @param filePath - Path to file\r\n * @returns True if file has uncommitted changes\r\n */\r\nexport async function hasUncommittedChanges(filePath: string): Promise<boolean> {\r\n try {\r\n const { stdout } = await execAsync(`git status --porcelain \"${filePath}\"`);\r\n return stdout.trim().length > 0;\r\n } catch (error) {\r\n throw new GitIntegrationError(\r\n `Failed to check git status for ${filePath}`,\r\n { error: error instanceof Error ? error.message : String(error) }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Get current git branch\r\n *\r\n * @returns Current branch name\r\n */\r\nexport async function getCurrentBranch(): Promise<string> {\r\n try {\r\n const { stdout } = await execAsync('git rev-parse --abbrev-ref HEAD');\r\n return stdout.trim();\r\n } catch (error) {\r\n throw new GitIntegrationError(\r\n 'Failed to get current branch',\r\n { error: error instanceof Error ? error.message : String(error) }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Get file diff between two commits\r\n *\r\n * @param filePath - Path to file\r\n * @param commitRef1 - First commit reference\r\n * @param commitRef2 - Second commit reference (default: HEAD)\r\n * @returns Diff output\r\n */\r\nexport async function getFileDiff(\r\n filePath: string,\r\n commitRef1: string,\r\n commitRef2: string = 'HEAD'\r\n): Promise<string> {\r\n try {\r\n const { stdout } = await execAsync(\r\n `git diff ${commitRef1} ${commitRef2} -- \"${filePath}\"`\r\n );\r\n return stdout;\r\n } catch (error) {\r\n throw new GitIntegrationError(\r\n `Failed to get diff for ${filePath}`,\r\n { error: error instanceof Error ? error.message : String(error) }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Verify content integrity using git hash\r\n *\r\n * @param filePath - Path to file\r\n * @param expectedHash - Expected content hash\r\n * @returns True if content matches expected hash\r\n */\r\nexport async function verifyContentIntegrity(\r\n filePath: string,\r\n expectedHash: string\r\n): Promise<boolean> {\r\n try {\r\n const actualHash = await calculateFileHash(filePath);\r\n return actualHash === expectedHash;\r\n } catch (error) {\r\n throw new GitIntegrationError(\r\n `Failed to verify content integrity for ${filePath}`,\r\n { error: error instanceof Error ? error.message : String(error) }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Get file creation date from git history\r\n *\r\n * @param filePath - Path to file\r\n * @returns ISO date string of first commit\r\n */\r\nexport async function getFileCreationDate(filePath: string): Promise<string> {\r\n try {\r\n const { stdout } = await execAsync(\r\n `git log --diff-filter=A --follow --format=\"%ai\" -- \"${filePath}\" | tail -1`\r\n );\r\n\r\n if (!stdout.trim()) {\r\n throw new GitIntegrationError('No creation date found in git history', { filePath });\r\n }\r\n\r\n return new Date(stdout.trim()).toISOString();\r\n } catch (error) {\r\n throw new GitIntegrationError(\r\n `Failed to get creation date for ${filePath}`,\r\n { error: error instanceof Error ? error.message : String(error) }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Get file last modification date from git history\r\n *\r\n * @param filePath - Path to file\r\n * @returns ISO date string of last commit\r\n */\r\nexport async function getFileModificationDate(filePath: string): Promise<string> {\r\n try {\r\n const metadata = await getCommitMetadata(filePath);\r\n return new Date(metadata.date).toISOString();\r\n } catch (error) {\r\n throw new GitIntegrationError(\r\n `Failed to get modification date for ${filePath}`,\r\n { error: error instanceof Error ? error.message : String(error) }\r\n );\r\n }\r\n}\r\n"],"names":["exec","promisify","createHash","readFile","StandardError","execAsync","GitIntegrationError","message","context","name","calculateContentHash","content","update","digest","calculateFileHash","filePath","error","Error","String","isGitRepository","cwd","getCommitMetadata","commitRef","stdout","hash","author","email","date","trim","split","getVersionHistory","limit","commits","filter","Boolean","history","commitHash","metadata","contentHash","versionMatch","match","version","push","commit","timestamp","commitFile","hashOutput","success","rollbackFile","hasUncommittedChanges","length","getCurrentBranch","getFileDiff","commitRef1","commitRef2","verifyContentIntegrity","expectedHash","actualHash","getFileCreationDate","Date","toISOString","getFileModificationDate"],"mappings":"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"}