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,297 @@
1
+ /**
2
+ * LRU Skill Cache
3
+ *
4
+ * Memory-aware LRU (Least Recently Used) cache for skill content.
5
+ * Tracks memory usage per skill and evicts LRU entries when budget exceeded.
6
+ *
7
+ * Features:
8
+ * - Memory budget enforcement (bytes, not just entry count)
9
+ * - LRU eviction policy
10
+ * - Cache statistics (hits, misses, evictions)
11
+ * - Thread-safe operations
12
+ * - TTL support (optional)
13
+ *
14
+ * @module skill-cache
15
+ */ import { createLogger } from './logging.js';
16
+ import { StandardError } from './errors.js';
17
+ /**
18
+ * LRU Skill Cache with memory budget enforcement
19
+ */ export class LRUSkillCache {
20
+ cache;
21
+ maxMemoryBytes;
22
+ maxEntries;
23
+ defaultTTLMs;
24
+ currentMemoryBytes = 0;
25
+ logger;
26
+ debug;
27
+ // Statistics
28
+ stats = {
29
+ hits: 0,
30
+ misses: 0,
31
+ evictions: 0
32
+ };
33
+ constructor(config){
34
+ this.cache = new Map();
35
+ this.maxMemoryBytes = config.maxMemoryBytes;
36
+ this.maxEntries = config.maxEntries ?? Number.MAX_SAFE_INTEGER;
37
+ this.defaultTTLMs = config.defaultTTLMs;
38
+ this.logger = config.logger ?? createLogger('lru-skill-cache');
39
+ this.debug = config.debug ?? false;
40
+ if (this.debug) {
41
+ this.logger.info('LRU cache initialized', {
42
+ maxMemoryBytes: this.maxMemoryBytes,
43
+ maxMemoryMB: (this.maxMemoryBytes / 1024 / 1024).toFixed(2),
44
+ maxEntries: this.maxEntries,
45
+ defaultTTLMs: this.defaultTTLMs
46
+ });
47
+ }
48
+ }
49
+ /**
50
+ * Get value from cache
51
+ *
52
+ * Updates last access time (LRU tracking).
53
+ * Returns undefined if not found or expired.
54
+ */ get(key) {
55
+ const entry = this.cache.get(key);
56
+ if (!entry) {
57
+ this.stats.misses++;
58
+ return undefined;
59
+ }
60
+ // Check expiry
61
+ if (entry.expiresAt && entry.expiresAt < new Date()) {
62
+ if (this.debug) {
63
+ this.logger.debug('Cache entry expired', {
64
+ key
65
+ });
66
+ }
67
+ this.delete(key);
68
+ this.stats.misses++;
69
+ return undefined;
70
+ }
71
+ // Update last accessed (LRU tracking)
72
+ entry.lastAccessed = new Date();
73
+ this.stats.hits++;
74
+ if (this.debug) {
75
+ this.logger.debug('Cache hit', {
76
+ key,
77
+ sizeBytes: entry.sizeBytes,
78
+ age: Date.now() - entry.createdAt.getTime()
79
+ });
80
+ }
81
+ return entry.value;
82
+ }
83
+ /**
84
+ * Set value in cache
85
+ *
86
+ * Evicts LRU entries if memory budget would be exceeded.
87
+ *
88
+ * @param key - Cache key
89
+ * @param value - Value to cache
90
+ * @param sizeBytes - Size of value in bytes
91
+ * @param ttlMs - TTL in milliseconds (optional, overrides default)
92
+ */ set(key, value, sizeBytes, ttlMs) {
93
+ // Check if entry already exists
94
+ const existing = this.cache.get(key);
95
+ if (existing) {
96
+ // Update existing entry
97
+ this.currentMemoryBytes -= existing.sizeBytes;
98
+ this.currentMemoryBytes += sizeBytes;
99
+ existing.value = value;
100
+ existing.sizeBytes = sizeBytes;
101
+ existing.lastAccessed = new Date();
102
+ existing.createdAt = new Date();
103
+ if (ttlMs !== undefined || this.defaultTTLMs !== undefined) {
104
+ const ttl = ttlMs ?? this.defaultTTLMs;
105
+ existing.expiresAt = new Date(Date.now() + ttl);
106
+ }
107
+ if (this.debug) {
108
+ this.logger.debug('Cache entry updated', {
109
+ key,
110
+ sizeBytes,
111
+ memoryUsageBytes: this.currentMemoryBytes
112
+ });
113
+ }
114
+ return;
115
+ }
116
+ // Evict entries if needed
117
+ this.evictIfNeeded(sizeBytes);
118
+ // Create new entry
119
+ const entry = {
120
+ key,
121
+ value,
122
+ sizeBytes,
123
+ lastAccessed: new Date(),
124
+ createdAt: new Date()
125
+ };
126
+ if (ttlMs !== undefined || this.defaultTTLMs !== undefined) {
127
+ const ttl = ttlMs ?? this.defaultTTLMs;
128
+ entry.expiresAt = new Date(Date.now() + ttl);
129
+ }
130
+ this.cache.set(key, entry);
131
+ this.currentMemoryBytes += sizeBytes;
132
+ if (this.debug) {
133
+ this.logger.debug('Cache entry added', {
134
+ key,
135
+ sizeBytes,
136
+ memoryUsageBytes: this.currentMemoryBytes,
137
+ memoryUtilization: (this.currentMemoryBytes / this.maxMemoryBytes).toFixed(2)
138
+ });
139
+ }
140
+ }
141
+ /**
142
+ * Delete entry from cache
143
+ */ delete(key) {
144
+ const entry = this.cache.get(key);
145
+ if (!entry) {
146
+ return false;
147
+ }
148
+ this.cache.delete(key);
149
+ this.currentMemoryBytes -= entry.sizeBytes;
150
+ if (this.debug) {
151
+ this.logger.debug('Cache entry deleted', {
152
+ key,
153
+ sizeBytes: entry.sizeBytes,
154
+ memoryUsageBytes: this.currentMemoryBytes
155
+ });
156
+ }
157
+ return true;
158
+ }
159
+ /**
160
+ * Check if key exists in cache
161
+ */ has(key) {
162
+ const entry = this.cache.get(key);
163
+ if (!entry) {
164
+ return false;
165
+ }
166
+ // Check expiry
167
+ if (entry.expiresAt && entry.expiresAt < new Date()) {
168
+ this.delete(key);
169
+ return false;
170
+ }
171
+ return true;
172
+ }
173
+ /**
174
+ * Clear all entries
175
+ */ clear() {
176
+ this.cache.clear();
177
+ this.currentMemoryBytes = 0;
178
+ if (this.debug) {
179
+ this.logger.debug('Cache cleared');
180
+ }
181
+ }
182
+ /**
183
+ * Get cache size (number of entries)
184
+ */ get size() {
185
+ return this.cache.size;
186
+ }
187
+ /**
188
+ * Get current memory usage (bytes)
189
+ */ get memoryUsageBytes() {
190
+ return this.currentMemoryBytes;
191
+ }
192
+ /**
193
+ * Get cache statistics
194
+ */ getStatistics() {
195
+ const totalOps = this.stats.hits + this.stats.misses;
196
+ const hitRate = totalOps > 0 ? this.stats.hits / totalOps : 0;
197
+ const evictionRate = totalOps > 0 ? this.stats.evictions / totalOps : 0;
198
+ const memoryUtilization = this.currentMemoryBytes / this.maxMemoryBytes;
199
+ return {
200
+ size: this.cache.size,
201
+ maxSize: this.maxEntries,
202
+ memoryUsageBytes: this.currentMemoryBytes,
203
+ maxMemoryBytes: this.maxMemoryBytes,
204
+ hits: this.stats.hits,
205
+ misses: this.stats.misses,
206
+ evictions: this.stats.evictions,
207
+ hitRate,
208
+ evictionRate,
209
+ memoryUtilization
210
+ };
211
+ }
212
+ /**
213
+ * Reset statistics
214
+ */ resetStatistics() {
215
+ this.stats = {
216
+ hits: 0,
217
+ misses: 0,
218
+ evictions: 0
219
+ };
220
+ }
221
+ /**
222
+ * Get all cache keys
223
+ */ keys() {
224
+ return Array.from(this.cache.keys());
225
+ }
226
+ /**
227
+ * Evict entries if needed to fit new entry
228
+ *
229
+ * Uses LRU (Least Recently Used) eviction policy.
230
+ *
231
+ * @param newEntrySizeBytes - Size of new entry to add
232
+ */ evictIfNeeded(newEntrySizeBytes) {
233
+ // Check entry count limit
234
+ while(this.cache.size >= this.maxEntries){
235
+ this.evictLRU();
236
+ }
237
+ // Check memory budget
238
+ while(this.currentMemoryBytes + newEntrySizeBytes > this.maxMemoryBytes && this.cache.size > 0){
239
+ this.evictLRU();
240
+ }
241
+ // Final check: if single entry exceeds budget, throw error
242
+ if (newEntrySizeBytes > this.maxMemoryBytes) {
243
+ throw new StandardError('CACHE_ENTRY_TOO_LARGE', `Entry size (${newEntrySizeBytes} bytes) exceeds maximum memory budget (${this.maxMemoryBytes} bytes)`, {
244
+ newEntrySizeBytes,
245
+ maxMemoryBytes: this.maxMemoryBytes
246
+ });
247
+ }
248
+ }
249
+ /**
250
+ * Evict least recently used entry
251
+ */ evictLRU() {
252
+ let oldestKey;
253
+ let oldestTime;
254
+ // Find LRU entry
255
+ for (const [key, entry] of this.cache.entries()){
256
+ if (!oldestTime || entry.lastAccessed < oldestTime) {
257
+ oldestKey = key;
258
+ oldestTime = entry.lastAccessed;
259
+ }
260
+ }
261
+ if (oldestKey) {
262
+ const entry = this.cache.get(oldestKey);
263
+ this.delete(oldestKey);
264
+ this.stats.evictions++;
265
+ if (this.debug) {
266
+ this.logger.debug('Evicted LRU entry', {
267
+ key: oldestKey,
268
+ sizeBytes: entry.sizeBytes,
269
+ age: Date.now() - entry.createdAt.getTime(),
270
+ lastAccessed: entry.lastAccessed.toISOString()
271
+ });
272
+ }
273
+ }
274
+ }
275
+ /**
276
+ * Remove expired entries
277
+ *
278
+ * @returns Number of expired entries removed
279
+ */ cleanupExpired() {
280
+ const now = new Date();
281
+ let removed = 0;
282
+ for (const [key, entry] of this.cache.entries()){
283
+ if (entry.expiresAt && entry.expiresAt < now) {
284
+ this.delete(key);
285
+ removed++;
286
+ }
287
+ }
288
+ if (removed > 0 && this.debug) {
289
+ this.logger.debug('Cleaned up expired entries', {
290
+ count: removed
291
+ });
292
+ }
293
+ return removed;
294
+ }
295
+ }
296
+
297
+ //# sourceMappingURL=skill-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/skill-cache.ts"],"sourcesContent":["/**\r\n * LRU Skill Cache\r\n *\r\n * Memory-aware LRU (Least Recently Used) cache for skill content.\r\n * Tracks memory usage per skill and evicts LRU entries when budget exceeded.\r\n *\r\n * Features:\r\n * - Memory budget enforcement (bytes, not just entry count)\r\n * - LRU eviction policy\r\n * - Cache statistics (hits, misses, evictions)\r\n * - Thread-safe operations\r\n * - TTL support (optional)\r\n *\r\n * @module skill-cache\r\n */\r\n\r\nimport { createLogger, Logger } from './logging.js';\r\nimport { StandardError } from './errors.js';\r\n\r\n/**\r\n * Cache entry with LRU metadata\r\n */\r\nexport interface CacheEntry<T> {\r\n /** Cache key (skill ID) */\r\n key: string;\r\n\r\n /** Cached value (skill content) */\r\n value: T;\r\n\r\n /** Entry size in bytes */\r\n sizeBytes: number;\r\n\r\n /** Last access timestamp */\r\n lastAccessed: Date;\r\n\r\n /** Creation timestamp */\r\n createdAt: Date;\r\n\r\n /** Expiry timestamp (optional) */\r\n expiresAt?: Date;\r\n}\r\n\r\n/**\r\n * Cache statistics\r\n */\r\nexport interface CacheStatistics {\r\n /** Current number of entries */\r\n size: number;\r\n\r\n /** Maximum number of entries */\r\n maxSize: number;\r\n\r\n /** Current memory usage (bytes) */\r\n memoryUsageBytes: number;\r\n\r\n /** Maximum memory budget (bytes) */\r\n maxMemoryBytes: number;\r\n\r\n /** Total cache hits */\r\n hits: number;\r\n\r\n /** Total cache misses */\r\n misses: number;\r\n\r\n /** Total evictions */\r\n evictions: number;\r\n\r\n /** Cache hit rate (0-1) */\r\n hitRate: number;\r\n\r\n /** Eviction rate (evictions / total operations) */\r\n evictionRate: number;\r\n\r\n /** Memory utilization (0-1) */\r\n memoryUtilization: number;\r\n}\r\n\r\n/**\r\n * LRU Cache configuration\r\n */\r\nexport interface LRUCacheConfig {\r\n /** Maximum memory budget in bytes */\r\n maxMemoryBytes: number;\r\n\r\n /** Maximum number of entries (optional, defaults to unlimited) */\r\n maxEntries?: number;\r\n\r\n /** Default TTL in milliseconds (optional, defaults to no expiry) */\r\n defaultTTLMs?: number;\r\n\r\n /** Logger instance */\r\n logger?: Logger;\r\n\r\n /** Enable debug logging */\r\n debug?: boolean;\r\n}\r\n\r\n/**\r\n * LRU Skill Cache with memory budget enforcement\r\n */\r\nexport class LRUSkillCache<T> {\r\n private cache: Map<string, CacheEntry<T>>;\r\n private maxMemoryBytes: number;\r\n private maxEntries: number;\r\n private defaultTTLMs?: number;\r\n private currentMemoryBytes: number = 0;\r\n private logger: Logger;\r\n private debug: boolean;\r\n\r\n // Statistics\r\n private stats = {\r\n hits: 0,\r\n misses: 0,\r\n evictions: 0,\r\n };\r\n\r\n constructor(config: LRUCacheConfig) {\r\n this.cache = new Map();\r\n this.maxMemoryBytes = config.maxMemoryBytes;\r\n this.maxEntries = config.maxEntries ?? Number.MAX_SAFE_INTEGER;\r\n this.defaultTTLMs = config.defaultTTLMs;\r\n this.logger = config.logger ?? createLogger('lru-skill-cache');\r\n this.debug = config.debug ?? false;\r\n\r\n if (this.debug) {\r\n this.logger.info('LRU cache initialized', {\r\n maxMemoryBytes: this.maxMemoryBytes,\r\n maxMemoryMB: (this.maxMemoryBytes / 1024 / 1024).toFixed(2),\r\n maxEntries: this.maxEntries,\r\n defaultTTLMs: this.defaultTTLMs,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Get value from cache\r\n *\r\n * Updates last access time (LRU tracking).\r\n * Returns undefined if not found or expired.\r\n */\r\n get(key: string): T | undefined {\r\n const entry = this.cache.get(key);\r\n\r\n if (!entry) {\r\n this.stats.misses++;\r\n return undefined;\r\n }\r\n\r\n // Check expiry\r\n if (entry.expiresAt && entry.expiresAt < new Date()) {\r\n if (this.debug) {\r\n this.logger.debug('Cache entry expired', { key });\r\n }\r\n this.delete(key);\r\n this.stats.misses++;\r\n return undefined;\r\n }\r\n\r\n // Update last accessed (LRU tracking)\r\n entry.lastAccessed = new Date();\r\n this.stats.hits++;\r\n\r\n if (this.debug) {\r\n this.logger.debug('Cache hit', {\r\n key,\r\n sizeBytes: entry.sizeBytes,\r\n age: Date.now() - entry.createdAt.getTime(),\r\n });\r\n }\r\n\r\n return entry.value;\r\n }\r\n\r\n /**\r\n * Set value in cache\r\n *\r\n * Evicts LRU entries if memory budget would be exceeded.\r\n *\r\n * @param key - Cache key\r\n * @param value - Value to cache\r\n * @param sizeBytes - Size of value in bytes\r\n * @param ttlMs - TTL in milliseconds (optional, overrides default)\r\n */\r\n set(key: string, value: T, sizeBytes: number, ttlMs?: number): void {\r\n // Check if entry already exists\r\n const existing = this.cache.get(key);\r\n if (existing) {\r\n // Update existing entry\r\n this.currentMemoryBytes -= existing.sizeBytes;\r\n this.currentMemoryBytes += sizeBytes;\r\n\r\n existing.value = value;\r\n existing.sizeBytes = sizeBytes;\r\n existing.lastAccessed = new Date();\r\n existing.createdAt = new Date();\r\n\r\n if (ttlMs !== undefined || this.defaultTTLMs !== undefined) {\r\n const ttl = ttlMs ?? this.defaultTTLMs!;\r\n existing.expiresAt = new Date(Date.now() + ttl);\r\n }\r\n\r\n if (this.debug) {\r\n this.logger.debug('Cache entry updated', {\r\n key,\r\n sizeBytes,\r\n memoryUsageBytes: this.currentMemoryBytes,\r\n });\r\n }\r\n\r\n return;\r\n }\r\n\r\n // Evict entries if needed\r\n this.evictIfNeeded(sizeBytes);\r\n\r\n // Create new entry\r\n const entry: CacheEntry<T> = {\r\n key,\r\n value,\r\n sizeBytes,\r\n lastAccessed: new Date(),\r\n createdAt: new Date(),\r\n };\r\n\r\n if (ttlMs !== undefined || this.defaultTTLMs !== undefined) {\r\n const ttl = ttlMs ?? this.defaultTTLMs!;\r\n entry.expiresAt = new Date(Date.now() + ttl);\r\n }\r\n\r\n this.cache.set(key, entry);\r\n this.currentMemoryBytes += sizeBytes;\r\n\r\n if (this.debug) {\r\n this.logger.debug('Cache entry added', {\r\n key,\r\n sizeBytes,\r\n memoryUsageBytes: this.currentMemoryBytes,\r\n memoryUtilization: (this.currentMemoryBytes / this.maxMemoryBytes).toFixed(2),\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Delete entry from cache\r\n */\r\n delete(key: string): boolean {\r\n const entry = this.cache.get(key);\r\n if (!entry) {\r\n return false;\r\n }\r\n\r\n this.cache.delete(key);\r\n this.currentMemoryBytes -= entry.sizeBytes;\r\n\r\n if (this.debug) {\r\n this.logger.debug('Cache entry deleted', {\r\n key,\r\n sizeBytes: entry.sizeBytes,\r\n memoryUsageBytes: this.currentMemoryBytes,\r\n });\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Check if key exists in cache\r\n */\r\n has(key: string): boolean {\r\n const entry = this.cache.get(key);\r\n if (!entry) {\r\n return false;\r\n }\r\n\r\n // Check expiry\r\n if (entry.expiresAt && entry.expiresAt < new Date()) {\r\n this.delete(key);\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Clear all entries\r\n */\r\n clear(): void {\r\n this.cache.clear();\r\n this.currentMemoryBytes = 0;\r\n\r\n if (this.debug) {\r\n this.logger.debug('Cache cleared');\r\n }\r\n }\r\n\r\n /**\r\n * Get cache size (number of entries)\r\n */\r\n get size(): number {\r\n return this.cache.size;\r\n }\r\n\r\n /**\r\n * Get current memory usage (bytes)\r\n */\r\n get memoryUsageBytes(): number {\r\n return this.currentMemoryBytes;\r\n }\r\n\r\n /**\r\n * Get cache statistics\r\n */\r\n getStatistics(): CacheStatistics {\r\n const totalOps = this.stats.hits + this.stats.misses;\r\n const hitRate = totalOps > 0 ? this.stats.hits / totalOps : 0;\r\n const evictionRate = totalOps > 0 ? this.stats.evictions / totalOps : 0;\r\n const memoryUtilization = this.currentMemoryBytes / this.maxMemoryBytes;\r\n\r\n return {\r\n size: this.cache.size,\r\n maxSize: this.maxEntries,\r\n memoryUsageBytes: this.currentMemoryBytes,\r\n maxMemoryBytes: this.maxMemoryBytes,\r\n hits: this.stats.hits,\r\n misses: this.stats.misses,\r\n evictions: this.stats.evictions,\r\n hitRate,\r\n evictionRate,\r\n memoryUtilization,\r\n };\r\n }\r\n\r\n /**\r\n * Reset statistics\r\n */\r\n resetStatistics(): void {\r\n this.stats = {\r\n hits: 0,\r\n misses: 0,\r\n evictions: 0,\r\n };\r\n }\r\n\r\n /**\r\n * Get all cache keys\r\n */\r\n keys(): string[] {\r\n return Array.from(this.cache.keys());\r\n }\r\n\r\n /**\r\n * Evict entries if needed to fit new entry\r\n *\r\n * Uses LRU (Least Recently Used) eviction policy.\r\n *\r\n * @param newEntrySizeBytes - Size of new entry to add\r\n */\r\n private evictIfNeeded(newEntrySizeBytes: number): void {\r\n // Check entry count limit\r\n while (this.cache.size >= this.maxEntries) {\r\n this.evictLRU();\r\n }\r\n\r\n // Check memory budget\r\n while (\r\n this.currentMemoryBytes + newEntrySizeBytes > this.maxMemoryBytes &&\r\n this.cache.size > 0\r\n ) {\r\n this.evictLRU();\r\n }\r\n\r\n // Final check: if single entry exceeds budget, throw error\r\n if (newEntrySizeBytes > this.maxMemoryBytes) {\r\n throw new StandardError(\r\n 'CACHE_ENTRY_TOO_LARGE',\r\n `Entry size (${newEntrySizeBytes} bytes) exceeds maximum memory budget (${this.maxMemoryBytes} bytes)`,\r\n { newEntrySizeBytes, maxMemoryBytes: this.maxMemoryBytes }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Evict least recently used entry\r\n */\r\n private evictLRU(): void {\r\n let oldestKey: string | undefined;\r\n let oldestTime: Date | undefined;\r\n\r\n // Find LRU entry\r\n for (const [key, entry] of this.cache.entries()) {\r\n if (!oldestTime || entry.lastAccessed < oldestTime) {\r\n oldestKey = key;\r\n oldestTime = entry.lastAccessed;\r\n }\r\n }\r\n\r\n if (oldestKey) {\r\n const entry = this.cache.get(oldestKey)!;\r\n this.delete(oldestKey);\r\n this.stats.evictions++;\r\n\r\n if (this.debug) {\r\n this.logger.debug('Evicted LRU entry', {\r\n key: oldestKey,\r\n sizeBytes: entry.sizeBytes,\r\n age: Date.now() - entry.createdAt.getTime(),\r\n lastAccessed: entry.lastAccessed.toISOString(),\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Remove expired entries\r\n *\r\n * @returns Number of expired entries removed\r\n */\r\n cleanupExpired(): number {\r\n const now = new Date();\r\n let removed = 0;\r\n\r\n for (const [key, entry] of this.cache.entries()) {\r\n if (entry.expiresAt && entry.expiresAt < now) {\r\n this.delete(key);\r\n removed++;\r\n }\r\n }\r\n\r\n if (removed > 0 && this.debug) {\r\n this.logger.debug('Cleaned up expired entries', { count: removed });\r\n }\r\n\r\n return removed;\r\n }\r\n}\r\n"],"names":["createLogger","StandardError","LRUSkillCache","cache","maxMemoryBytes","maxEntries","defaultTTLMs","currentMemoryBytes","logger","debug","stats","hits","misses","evictions","config","Map","Number","MAX_SAFE_INTEGER","info","maxMemoryMB","toFixed","get","key","entry","undefined","expiresAt","Date","delete","lastAccessed","sizeBytes","age","now","createdAt","getTime","value","set","ttlMs","existing","ttl","memoryUsageBytes","evictIfNeeded","memoryUtilization","has","clear","size","getStatistics","totalOps","hitRate","evictionRate","maxSize","resetStatistics","keys","Array","from","newEntrySizeBytes","evictLRU","oldestKey","oldestTime","entries","toISOString","cleanupExpired","removed","count"],"mappings":"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"}
@@ -0,0 +1,337 @@
1
+ /**
2
+ * Skill Content Manager
3
+ *
4
+ * Manages standardized skill content storage, organization, and versioning
5
+ * Enforces directory structure, validates required files, tracks versions
6
+ *
7
+ * @module skill-content-manager
8
+ * @version 1.0.0
9
+ */ import { join, basename } from 'path';
10
+ import { stat, readdir, access, chmod, readFile, writeFile, mkdir } from 'fs/promises';
11
+ import { constants } from 'fs';
12
+ import { StandardError } from './errors.js';
13
+ import { parseFrontmatter, validateFrontmatter, parseAndValidate, updateFrontmatter, createSkillDocument } from './skill-frontmatter-parser.js';
14
+ import { calculateFileHash, getCommitMetadata, getVersionHistory, commitFile, hasUncommittedChanges, verifyContentIntegrity, getFileCreationDate, getFileModificationDate } from './skill-git-integration.js';
15
+ /**
16
+ * Required files in skill directory
17
+ */ export const REQUIRED_SKILL_FILES = [
18
+ 'SKILL.md',
19
+ 'execute.sh',
20
+ 'test.sh',
21
+ 'validate.sh',
22
+ 'package.json'
23
+ ];
24
+ /**
25
+ * Skill content manager error
26
+ */ export class SkillContentError extends StandardError {
27
+ context;
28
+ constructor(message, context){
29
+ super('SKILL_CONTENT_ERROR', message, context), this.context = context;
30
+ this.name = 'SkillContentError';
31
+ }
32
+ }
33
+ /**
34
+ * Validate skill directory structure
35
+ *
36
+ * @param skillPath - Path to skill directory
37
+ * @returns Validation result with details
38
+ */ export async function validateSkillStructure(skillPath) {
39
+ const skillName = basename(skillPath);
40
+ const missingFiles = [];
41
+ const invalidPermissions = [];
42
+ const errors = [];
43
+ const warnings = [];
44
+ try {
45
+ // Check if directory exists
46
+ const dirStat = await stat(skillPath);
47
+ if (!dirStat.isDirectory()) {
48
+ errors.push(`${skillPath} is not a directory`);
49
+ return {
50
+ valid: false,
51
+ skillName,
52
+ skillPath,
53
+ missingFiles,
54
+ invalidPermissions,
55
+ errors,
56
+ warnings
57
+ };
58
+ }
59
+ } catch (error) {
60
+ errors.push(`Skill directory does not exist: ${skillPath}`);
61
+ return {
62
+ valid: false,
63
+ skillName,
64
+ skillPath,
65
+ missingFiles,
66
+ invalidPermissions,
67
+ errors,
68
+ warnings
69
+ };
70
+ }
71
+ // Check required files
72
+ for (const fileName of REQUIRED_SKILL_FILES){
73
+ const filePath = join(skillPath, fileName);
74
+ try {
75
+ await access(filePath, constants.F_OK);
76
+ // Check execute permission for .sh files
77
+ if (fileName.endsWith('.sh')) {
78
+ try {
79
+ await access(filePath, constants.X_OK);
80
+ } catch {
81
+ invalidPermissions.push(fileName);
82
+ errors.push(`${fileName} is not executable`);
83
+ }
84
+ }
85
+ } catch {
86
+ missingFiles.push(fileName);
87
+ errors.push(`Required file missing: ${fileName}`);
88
+ }
89
+ }
90
+ // Validate SKILL.md frontmatter if exists
91
+ const skillMdPath = join(skillPath, 'SKILL.md');
92
+ try {
93
+ await access(skillMdPath, constants.F_OK);
94
+ const content = await readFile(skillMdPath, 'utf-8');
95
+ try {
96
+ const parsed = parseFrontmatter(content);
97
+ const validation = validateFrontmatter(parsed.frontmatter);
98
+ if (!validation.valid) {
99
+ errors.push(...validation.errors);
100
+ }
101
+ warnings.push(...validation.warnings);
102
+ } catch (error) {
103
+ errors.push(`SKILL.md frontmatter error: ${error instanceof Error ? error.message : String(error)}`);
104
+ }
105
+ } catch {
106
+ // Already reported as missing file
107
+ }
108
+ return {
109
+ valid: errors.length === 0,
110
+ skillName,
111
+ skillPath,
112
+ missingFiles,
113
+ invalidPermissions,
114
+ errors,
115
+ warnings
116
+ };
117
+ }
118
+ /**
119
+ * Fix skill file permissions
120
+ *
121
+ * @param skillPath - Path to skill directory
122
+ * @returns Array of files that were fixed
123
+ */ export async function fixSkillPermissions(skillPath) {
124
+ const fixed = [];
125
+ for (const fileName of REQUIRED_SKILL_FILES){
126
+ if (fileName.endsWith('.sh')) {
127
+ const filePath = join(skillPath, fileName);
128
+ try {
129
+ await access(filePath, constants.F_OK);
130
+ await chmod(filePath, 0o755); // rwxr-xr-x
131
+ fixed.push(fileName);
132
+ } catch {
133
+ // File doesn't exist, skip
134
+ }
135
+ }
136
+ }
137
+ return fixed;
138
+ }
139
+ /**
140
+ * Load skill metadata with git integration
141
+ *
142
+ * @param skillPath - Path to skill directory
143
+ * @param includeHistory - Include version history (default: false)
144
+ * @returns Complete skill metadata
145
+ */ export async function loadSkillMetadata(skillPath, includeHistory = false) {
146
+ const skillMdPath = join(skillPath, 'SKILL.md');
147
+ try {
148
+ // Read and parse SKILL.md
149
+ const content = await readFile(skillMdPath, 'utf-8');
150
+ const parsed = parseAndValidate(content);
151
+ // Calculate content hash
152
+ const contentHash = calculateFileHash(skillMdPath);
153
+ // Get git metadata (graceful fallback if not in git repo)
154
+ let gitMetadata;
155
+ let versionHistory;
156
+ let hasChanges;
157
+ let fileCreated;
158
+ let fileModified;
159
+ try {
160
+ gitMetadata = await getCommitMetadata(skillMdPath);
161
+ hasChanges = await hasUncommittedChanges(skillMdPath);
162
+ fileCreated = await getFileCreationDate(skillMdPath);
163
+ fileModified = await getFileModificationDate(skillMdPath);
164
+ if (includeHistory) {
165
+ versionHistory = await getVersionHistory(skillMdPath);
166
+ }
167
+ } catch {
168
+ // Not in git repo or no git history - continue without git data
169
+ }
170
+ return {
171
+ ...parsed.frontmatter,
172
+ skillPath,
173
+ contentHash: await contentHash,
174
+ gitMetadata,
175
+ versionHistory,
176
+ hasUncommittedChanges: hasChanges,
177
+ fileCreated,
178
+ fileModified
179
+ };
180
+ } catch (error) {
181
+ throw new SkillContentError(`Failed to load skill metadata from ${skillPath}`, {
182
+ error: error instanceof Error ? error.message : String(error)
183
+ });
184
+ }
185
+ }
186
+ /**
187
+ * Update skill frontmatter
188
+ *
189
+ * @param skillPath - Path to skill directory
190
+ * @param updates - Partial frontmatter updates
191
+ * @param options - Update options
192
+ * @returns Updated skill metadata
193
+ */ export async function updateSkillFrontmatter(skillPath, updates, options = {}) {
194
+ const { autoCommit = false, commitMessage, updateTimestamp = true, validateStructure = true } = options;
195
+ const skillMdPath = join(skillPath, 'SKILL.md');
196
+ try {
197
+ // Validate structure first if requested
198
+ if (validateStructure) {
199
+ const validation = await validateSkillStructure(skillPath);
200
+ if (!validation.valid) {
201
+ throw new SkillContentError('Skill structure validation failed', {
202
+ errors: validation.errors
203
+ });
204
+ }
205
+ }
206
+ // Read current content
207
+ const currentContent = await readFile(skillMdPath, 'utf-8');
208
+ // Update frontmatter
209
+ const updatedContent = updateFrontmatter(currentContent, updates);
210
+ // Write updated content
211
+ await writeFile(skillMdPath, updatedContent, 'utf-8');
212
+ // Auto-commit if requested
213
+ if (autoCommit) {
214
+ const message = commitMessage || `Update ${basename(skillPath)} frontmatter`;
215
+ await commitFile(skillMdPath, message);
216
+ }
217
+ // Return updated metadata
218
+ return await loadSkillMetadata(skillPath);
219
+ } catch (error) {
220
+ throw new SkillContentError(`Failed to update skill frontmatter for ${skillPath}`, {
221
+ error: error instanceof Error ? error.message : String(error)
222
+ });
223
+ }
224
+ }
225
+ /**
226
+ * Create new skill directory with standard structure
227
+ *
228
+ * @param parentDir - Parent directory for skills
229
+ * @param skillName - Name of skill to create
230
+ * @param frontmatter - Initial frontmatter
231
+ * @param content - Initial SKILL.md content
232
+ * @returns Created skill metadata
233
+ */ export async function createSkill(parentDir, skillName, frontmatter, content = '') {
234
+ const skillPath = join(parentDir, skillName);
235
+ try {
236
+ // Create skill directory
237
+ await mkdir(skillPath, {
238
+ recursive: true
239
+ });
240
+ // Create SKILL.md
241
+ const skillMdPath = join(skillPath, 'SKILL.md');
242
+ const skillDocument = createSkillDocument(frontmatter, content);
243
+ await writeFile(skillMdPath, skillDocument, 'utf-8');
244
+ // Create placeholder files
245
+ const executeSh = `#!/bin/bash
246
+ # ${frontmatter.name} - Execution Script
247
+ # Version: ${frontmatter.version}
248
+
249
+ set -euo pipefail
250
+
251
+ echo "Executing ${frontmatter.name}..."
252
+ # Add implementation here
253
+ `;
254
+ const testSh = `#!/bin/bash
255
+ # ${frontmatter.name} - Test Script
256
+ # Version: ${frontmatter.version}
257
+
258
+ set -euo pipefail
259
+
260
+ echo "Testing ${frontmatter.name}..."
261
+ # Add tests here
262
+ `;
263
+ const validateSh = `#!/bin/bash
264
+ # ${frontmatter.name} - Validation Script
265
+ # Version: ${frontmatter.version}
266
+
267
+ set -euo pipefail
268
+
269
+ echo "Validating ${frontmatter.name}..."
270
+ # Add validation here
271
+ `;
272
+ const packageJson = {
273
+ name: skillName,
274
+ version: frontmatter.version,
275
+ description: frontmatter.description,
276
+ scripts: {
277
+ execute: './execute.sh',
278
+ test: './test.sh',
279
+ validate: './validate.sh'
280
+ }
281
+ };
282
+ await writeFile(join(skillPath, 'execute.sh'), executeSh, 'utf-8');
283
+ await writeFile(join(skillPath, 'test.sh'), testSh, 'utf-8');
284
+ await writeFile(join(skillPath, 'validate.sh'), validateSh, 'utf-8');
285
+ await writeFile(join(skillPath, 'package.json'), JSON.stringify(packageJson, null, 2), 'utf-8');
286
+ // Fix permissions
287
+ await fixSkillPermissions(skillPath);
288
+ // Return metadata
289
+ return await loadSkillMetadata(skillPath);
290
+ } catch (error) {
291
+ throw new SkillContentError(`Failed to create skill ${skillName}`, {
292
+ error: error instanceof Error ? error.message : String(error)
293
+ });
294
+ }
295
+ }
296
+ /**
297
+ * Scan directory for all skills
298
+ *
299
+ * @param skillsDir - Path to skills directory
300
+ * @returns Array of skill paths
301
+ */ export async function scanSkills(skillsDir) {
302
+ try {
303
+ const entries = await readdir(skillsDir, {
304
+ withFileTypes: true
305
+ });
306
+ const skillPaths = [];
307
+ for (const entry of entries){
308
+ if (entry.isDirectory()) {
309
+ const skillPath = join(skillsDir, entry.name);
310
+ const skillMdPath = join(skillPath, 'SKILL.md');
311
+ try {
312
+ await access(skillMdPath, constants.F_OK);
313
+ skillPaths.push(skillPath);
314
+ } catch {
315
+ // Not a valid skill directory, skip
316
+ }
317
+ }
318
+ }
319
+ return skillPaths.sort();
320
+ } catch (error) {
321
+ throw new SkillContentError(`Failed to scan skills directory ${skillsDir}`, {
322
+ error: error instanceof Error ? error.message : String(error)
323
+ });
324
+ }
325
+ }
326
+ /**
327
+ * Verify skill content integrity
328
+ *
329
+ * @param skillPath - Path to skill directory
330
+ * @param expectedHash - Expected content hash
331
+ * @returns True if content matches expected hash
332
+ */ export async function verifySkillIntegrity(skillPath, expectedHash) {
333
+ const skillMdPath = join(skillPath, 'SKILL.md');
334
+ return await verifyContentIntegrity(skillMdPath, expectedHash);
335
+ }
336
+
337
+ //# sourceMappingURL=skill-content-manager.js.map