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,427 @@
1
+ /**
2
+ * Skill Loader with Memory Budget
3
+ *
4
+ * High-performance skill loading system with:
5
+ * - Lazy loading (metadata at startup, content on-demand)
6
+ * - Memory budget enforcement (100MB default)
7
+ * - LRU cache with eviction
8
+ * - SHA-256 hash validation
9
+ * - <2s startup for 500 skills
10
+ * - <100ms cache hit, <500ms cache miss
11
+ *
12
+ * @module skill-loader
13
+ */ import * as fs from 'fs/promises';
14
+ import * as path from 'path';
15
+ import * as crypto from 'crypto';
16
+ import { LRUSkillCache } from '../lib/skill-cache.js';
17
+ import { createLogger } from '../lib/logging.js';
18
+ import { StandardError } from '../lib/errors.js';
19
+ /**
20
+ * Skill Loader with memory budget and lazy loading
21
+ */ export class SkillLoader {
22
+ cache;
23
+ metadata;
24
+ dbService;
25
+ skillsBasePath;
26
+ logger;
27
+ debug;
28
+ maxMemoryBytes;
29
+ initialized = false;
30
+ // Loading locks (prevent duplicate loads)
31
+ loadingLocks = new Map();
32
+ // Metrics
33
+ metrics = {
34
+ hashMismatches: 0,
35
+ cacheInvalidations: 0
36
+ };
37
+ constructor(config){
38
+ this.dbService = config.dbService;
39
+ this.maxMemoryBytes = config.maxMemoryBytes ?? 100 * 1024 * 1024; // 100MB default
40
+ this.skillsBasePath = config.skillsBasePath ?? path.join(process.cwd(), '.claude/skills');
41
+ this.logger = config.logger ?? createLogger('skill-loader');
42
+ this.debug = config.debug ?? false;
43
+ // Initialize metadata map
44
+ this.metadata = new Map();
45
+ // Initialize LRU cache
46
+ this.cache = new LRUSkillCache({
47
+ maxMemoryBytes: this.maxMemoryBytes,
48
+ logger: this.logger,
49
+ debug: this.debug
50
+ });
51
+ if (this.debug) {
52
+ this.logger.info('SkillLoader initialized', {
53
+ maxMemoryBytes: this.maxMemoryBytes,
54
+ maxMemoryMB: (this.maxMemoryBytes / 1024 / 1024).toFixed(2),
55
+ skillsBasePath: this.skillsBasePath
56
+ });
57
+ }
58
+ }
59
+ /**
60
+ * Initialize loader
61
+ *
62
+ * Scans skills directory and loads metadata (NOT content).
63
+ * Fast: <2s for 500 skills.
64
+ */ async initialize() {
65
+ const startTime = Date.now();
66
+ if (this.initialized) {
67
+ this.logger.warn('SkillLoader already initialized');
68
+ return;
69
+ }
70
+ this.logger.info('Initializing SkillLoader', {
71
+ skillsBasePath: this.skillsBasePath
72
+ });
73
+ // Scan skills directory
74
+ await this.scanSkillsDirectory();
75
+ // Load metadata from database (if available)
76
+ if (this.dbService) {
77
+ await this.loadMetadataFromDatabase();
78
+ }
79
+ this.initialized = true;
80
+ const initTime = Date.now() - startTime;
81
+ this.logger.info('SkillLoader initialized', {
82
+ skillsLoaded: this.metadata.size,
83
+ initTimeMs: initTime
84
+ });
85
+ if (initTime >= 2000) {
86
+ this.logger.warn('Initialization time exceeded target', {
87
+ initTimeMs: initTime,
88
+ target: 2000
89
+ });
90
+ }
91
+ }
92
+ /**
93
+ * Load skill content
94
+ *
95
+ * Lazy loading: content loaded on-demand.
96
+ * - Cache hit: <100ms
97
+ * - Cache miss: <500ms (disk I/O + hash validation)
98
+ *
99
+ * @param skillId - Skill ID to load
100
+ * @returns Loaded skill with content
101
+ */ async loadSkill(skillId) {
102
+ const startTime = Date.now();
103
+ if (!this.initialized) {
104
+ throw new StandardError('LOADER_NOT_INITIALIZED', 'SkillLoader not initialized. Call initialize() first.');
105
+ }
106
+ // Check if already loading (prevent duplicate loads)
107
+ const existingLoad = this.loadingLocks.get(skillId);
108
+ if (existingLoad) {
109
+ if (this.debug) {
110
+ this.logger.debug('Waiting for existing load', {
111
+ skillId
112
+ });
113
+ }
114
+ return existingLoad;
115
+ }
116
+ // Create loading promise
117
+ const loadPromise = this.doLoadSkill(skillId, startTime);
118
+ this.loadingLocks.set(skillId, loadPromise);
119
+ try {
120
+ const skill = await loadPromise;
121
+ return skill;
122
+ } finally{
123
+ this.loadingLocks.delete(skillId);
124
+ }
125
+ }
126
+ /**
127
+ * Internal skill loading implementation
128
+ */ async doLoadSkill(skillId, startTime) {
129
+ // Get metadata
130
+ const meta = this.metadata.get(skillId);
131
+ if (!meta) {
132
+ throw new StandardError('SKILL_NOT_FOUND', `Skill not found: ${skillId}`, {
133
+ skillId
134
+ });
135
+ }
136
+ // Check cache first
137
+ const cached = this.cache.get(skillId);
138
+ if (cached) {
139
+ const loadTime = Date.now() - startTime;
140
+ if (this.debug) {
141
+ this.logger.debug('Cache hit', {
142
+ skillId,
143
+ loadTimeMs: loadTime
144
+ });
145
+ }
146
+ // Verify hash (detect file changes)
147
+ const currentHash = await this.computeFileHash(meta.path);
148
+ if (currentHash !== meta.hash) {
149
+ // Hash mismatch - invalidate cache and reload
150
+ this.metrics.hashMismatches++;
151
+ this.metrics.cacheInvalidations++;
152
+ this.cache.delete(skillId);
153
+ if (this.debug) {
154
+ this.logger.debug('Hash mismatch detected, reloading', {
155
+ skillId,
156
+ oldHash: meta.hash,
157
+ newHash: currentHash
158
+ });
159
+ }
160
+ // Fall through to load from disk
161
+ } else {
162
+ // Cache hit with valid hash
163
+ return {
164
+ ...meta,
165
+ content: cached
166
+ };
167
+ }
168
+ }
169
+ // Cache miss - load from disk
170
+ const content = await this.loadSkillFromDisk(meta);
171
+ const loadTime = Date.now() - startTime;
172
+ if (this.debug) {
173
+ this.logger.debug('Cache miss, loaded from disk', {
174
+ skillId,
175
+ loadTimeMs: loadTime
176
+ });
177
+ }
178
+ if (loadTime >= 500) {
179
+ this.logger.warn('Load time exceeded target', {
180
+ skillId,
181
+ loadTimeMs: loadTime,
182
+ target: 500
183
+ });
184
+ }
185
+ // Update metadata with new hash (if changed)
186
+ const currentHash = await this.computeFileHash(meta.path);
187
+ if (currentHash !== meta.hash) {
188
+ meta.hash = currentHash;
189
+ this.metrics.hashMismatches++;
190
+ // Update database
191
+ if (this.dbService) {
192
+ await this.updateMetadataInDatabase(meta);
193
+ }
194
+ }
195
+ // Cache the content
196
+ const contentSize = this.estimateContentSize(content);
197
+ this.cache.set(skillId, content, contentSize);
198
+ return {
199
+ ...meta,
200
+ content
201
+ };
202
+ }
203
+ /**
204
+ * Load skill content from disk
205
+ */ async loadSkillFromDisk(meta) {
206
+ const skillPath = path.join(this.skillsBasePath, meta.path);
207
+ try {
208
+ const markdown = await fs.readFile(skillPath, 'utf-8');
209
+ // Validate content
210
+ if (!markdown || markdown.trim().length === 0) {
211
+ throw new StandardError('EMPTY_SKILL_FILE', `Empty skill file: ${meta.id}`, {
212
+ skillId: meta.id,
213
+ path: skillPath
214
+ });
215
+ }
216
+ // Check for corrupted content (null bytes, invalid characters)
217
+ if (markdown.includes('\0') || /[\x00-\x08\x0B-\x0C\x0E-\x1F]/.test(markdown)) {
218
+ throw new StandardError('CORRUPTED_SKILL_FILE', `Corrupted skill file (invalid characters): ${meta.id}`, {
219
+ skillId: meta.id,
220
+ path: skillPath
221
+ });
222
+ }
223
+ // Validate minimum content length (reasonable skill should be >50 chars)
224
+ if (markdown.trim().length < 50) {
225
+ throw new StandardError('INVALID_SKILL_FILE', `Invalid skill file (too short): ${meta.id}`, {
226
+ skillId: meta.id,
227
+ path: skillPath,
228
+ length: markdown.trim().length
229
+ });
230
+ }
231
+ // Parse frontmatter (simple implementation)
232
+ const { frontmatter, content } = this.parseFrontmatter(markdown);
233
+ return {
234
+ markdown,
235
+ frontmatter,
236
+ title: frontmatter?.title ?? meta.id,
237
+ description: frontmatter?.description
238
+ };
239
+ } catch (error) {
240
+ throw new StandardError('SKILL_LOAD_ERROR', `Failed to load skill from disk: ${meta.id}`, {
241
+ skillId: meta.id,
242
+ path: skillPath,
243
+ error: String(error)
244
+ });
245
+ }
246
+ }
247
+ /**
248
+ * Scan skills directory and load metadata
249
+ */ async scanSkillsDirectory() {
250
+ try {
251
+ const entries = await fs.readdir(this.skillsBasePath, {
252
+ withFileTypes: true
253
+ });
254
+ for (const entry of entries){
255
+ if (entry.isDirectory()) {
256
+ const skillId = entry.name;
257
+ const skillFile = path.join(this.skillsBasePath, skillId, 'SKILL.md');
258
+ try {
259
+ const stat = await fs.stat(skillFile);
260
+ const hash = await this.computeFileHash(path.join(skillId, 'SKILL.md'));
261
+ const metadata = {
262
+ id: skillId,
263
+ path: path.join(skillId, 'SKILL.md'),
264
+ hash,
265
+ size: stat.size
266
+ };
267
+ this.metadata.set(skillId, metadata);
268
+ } catch (error) {
269
+ // Skip invalid skills
270
+ if (this.debug) {
271
+ this.logger.debug('Skipping invalid skill', {
272
+ skillId,
273
+ error: String(error)
274
+ });
275
+ }
276
+ }
277
+ }
278
+ }
279
+ } catch (error) {
280
+ throw new StandardError('SCAN_ERROR', 'Failed to scan skills directory', {
281
+ skillsBasePath: this.skillsBasePath,
282
+ error: String(error)
283
+ });
284
+ }
285
+ }
286
+ /**
287
+ * Compute SHA-256 hash of file
288
+ */ async computeFileHash(relativePath) {
289
+ const fullPath = path.join(this.skillsBasePath, relativePath);
290
+ const content = await fs.readFile(fullPath, 'utf-8');
291
+ return crypto.createHash('sha256').update(content, 'utf-8').digest('hex');
292
+ }
293
+ /**
294
+ * Load metadata from database
295
+ */ async loadMetadataFromDatabase() {
296
+ if (!this.dbService) {
297
+ return;
298
+ }
299
+ try {
300
+ const sqliteAdapter = this.dbService.getAdapter('sqlite');
301
+ const rows = await sqliteAdapter.raw('SELECT id, path, hash, size, last_loaded FROM skill_metadata');
302
+ for (const row of rows){
303
+ const existing = this.metadata.get(row.id);
304
+ if (existing) {
305
+ // Update with database values
306
+ existing.lastLoaded = row.last_loaded ? new Date(row.last_loaded) : undefined;
307
+ }
308
+ }
309
+ } catch (error) {
310
+ // Table might not exist yet
311
+ if (this.debug) {
312
+ this.logger.debug('Failed to load metadata from database', {
313
+ error: String(error)
314
+ });
315
+ }
316
+ }
317
+ }
318
+ /**
319
+ * Update metadata in database
320
+ */ async updateMetadataInDatabase(meta) {
321
+ if (!this.dbService) {
322
+ return;
323
+ }
324
+ try {
325
+ const sqliteAdapter = this.dbService.getAdapter('sqlite');
326
+ await sqliteAdapter.raw(`INSERT OR REPLACE INTO skill_metadata (id, path, hash, size, last_loaded)
327
+ VALUES (?, ?, ?, ?, ?)`, [
328
+ meta.id,
329
+ meta.path,
330
+ meta.hash,
331
+ meta.size,
332
+ new Date().toISOString()
333
+ ]);
334
+ } catch (error) {
335
+ if (this.debug) {
336
+ this.logger.debug('Failed to update metadata in database', {
337
+ skillId: meta.id,
338
+ error: String(error)
339
+ });
340
+ }
341
+ }
342
+ }
343
+ /**
344
+ * Parse frontmatter from markdown
345
+ */ parseFrontmatter(markdown) {
346
+ const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/;
347
+ const match = markdown.match(frontmatterRegex);
348
+ if (!match) {
349
+ return {
350
+ content: markdown
351
+ };
352
+ }
353
+ const [, frontmatterText, content] = match;
354
+ const frontmatter = {};
355
+ // Simple YAML parser (key: value)
356
+ const lines = frontmatterText.split('\n');
357
+ for (const line of lines){
358
+ const colonIndex = line.indexOf(':');
359
+ if (colonIndex > 0) {
360
+ const key = line.substring(0, colonIndex).trim();
361
+ const value = line.substring(colonIndex + 1).trim();
362
+ frontmatter[key] = value;
363
+ }
364
+ }
365
+ return {
366
+ frontmatter,
367
+ content
368
+ };
369
+ }
370
+ /**
371
+ * Estimate content size in bytes
372
+ */ estimateContentSize(content) {
373
+ // Rough estimate: markdown size + frontmatter overhead
374
+ let size = Buffer.byteLength(content.markdown, 'utf-8');
375
+ if (content.frontmatter) {
376
+ size += JSON.stringify(content.frontmatter).length;
377
+ }
378
+ return size;
379
+ }
380
+ /**
381
+ * Get loader metrics
382
+ */ getMetrics() {
383
+ const cacheStats = this.cache.getStatistics();
384
+ const contentLoaded = this.cache.size;
385
+ return {
386
+ skillsLoaded: this.metadata.size,
387
+ skillContentLoaded: contentLoaded,
388
+ memoryUsageBytes: cacheStats.memoryUsageBytes,
389
+ cacheHits: cacheStats.hits,
390
+ cacheMisses: cacheStats.misses,
391
+ evictions: cacheStats.evictions,
392
+ hashMismatches: this.metrics.hashMismatches,
393
+ cacheInvalidations: this.metrics.cacheInvalidations,
394
+ cacheHitRate: cacheStats.hitRate
395
+ };
396
+ }
397
+ /**
398
+ * Reset metrics
399
+ */ resetMetrics() {
400
+ this.cache.resetStatistics();
401
+ this.metrics = {
402
+ hashMismatches: 0,
403
+ cacheInvalidations: 0
404
+ };
405
+ }
406
+ /**
407
+ * Get cache statistics
408
+ */ getCacheStatistics() {
409
+ return this.cache.getStatistics();
410
+ }
411
+ /**
412
+ * Get loader configuration
413
+ */ getConfig() {
414
+ return {
415
+ maxMemoryBytes: this.maxMemoryBytes,
416
+ skillsBasePath: this.skillsBasePath
417
+ };
418
+ }
419
+ /**
420
+ * Clear cache
421
+ */ clearCache() {
422
+ this.cache.clear();
423
+ this.logger.info('Cache cleared');
424
+ }
425
+ }
426
+
427
+ //# sourceMappingURL=skill-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/services/skill-loader.ts"],"sourcesContent":["/**\r\n * Skill Loader with Memory Budget\r\n *\r\n * High-performance skill loading system with:\r\n * - Lazy loading (metadata at startup, content on-demand)\r\n * - Memory budget enforcement (100MB default)\r\n * - LRU cache with eviction\r\n * - SHA-256 hash validation\r\n * - <2s startup for 500 skills\r\n * - <100ms cache hit, <500ms cache miss\r\n *\r\n * @module skill-loader\r\n */\r\n\r\nimport * as fs from 'fs/promises';\r\nimport * as path from 'path';\r\nimport * as crypto from 'crypto';\r\nimport { LRUSkillCache, CacheStatistics } from '../lib/skill-cache.js';\r\nimport { DatabaseService } from '../lib/database-service.js';\r\nimport { createLogger, Logger } from '../lib/logging.js';\r\nimport { StandardError } from '../lib/errors.js';\r\n\r\n/**\r\n * Skill metadata (loaded at startup)\r\n */\r\nexport interface SkillMetadata {\r\n /** Skill ID */\r\n id: string;\r\n\r\n /** Skill file path (relative to skills base) */\r\n path: string;\r\n\r\n /** SHA-256 content hash */\r\n hash: string;\r\n\r\n /** File size in bytes */\r\n size: number;\r\n\r\n /** Last loaded timestamp */\r\n lastLoaded?: Date;\r\n\r\n /** Skill content (lazy loaded) */\r\n content?: SkillContent;\r\n}\r\n\r\n/**\r\n * Skill content (lazy loaded)\r\n */\r\nexport interface SkillContent {\r\n /** Full markdown content */\r\n markdown: string;\r\n\r\n /** Parsed frontmatter (optional) */\r\n frontmatter?: Record<string, any>;\r\n\r\n /** Skill title */\r\n title?: string;\r\n\r\n /** Skill description */\r\n description?: string;\r\n}\r\n\r\n/**\r\n * Skill with content loaded\r\n */\r\nexport interface LoadedSkill extends SkillMetadata {\r\n /** Skill content (always defined for loaded skill) */\r\n content: SkillContent;\r\n}\r\n\r\n/**\r\n * Loader metrics\r\n */\r\nexport interface LoaderMetrics {\r\n /** Total skills discovered (metadata loaded) */\r\n skillsLoaded: number;\r\n\r\n /** Skills with content loaded */\r\n skillContentLoaded: number;\r\n\r\n /** Current memory usage (bytes) */\r\n memoryUsageBytes: number;\r\n\r\n /** Cache hits */\r\n cacheHits: number;\r\n\r\n /** Cache misses */\r\n cacheMisses: number;\r\n\r\n /** Cache evictions */\r\n evictions: number;\r\n\r\n /** Hash mismatches detected */\r\n hashMismatches: number;\r\n\r\n /** Cache invalidations */\r\n cacheInvalidations: number;\r\n\r\n /** Cache hit rate (0-1) */\r\n cacheHitRate: number;\r\n}\r\n\r\n/**\r\n * Loader configuration\r\n */\r\nexport interface SkillLoaderConfig {\r\n /** Database service */\r\n dbService?: DatabaseService;\r\n\r\n /** Maximum memory budget (bytes) */\r\n maxMemoryBytes?: number;\r\n\r\n /** Skills base path */\r\n skillsBasePath?: string;\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 * Skill Loader with memory budget and lazy loading\r\n */\r\nexport class SkillLoader {\r\n private cache: LRUSkillCache<SkillContent>;\r\n private metadata: Map<string, SkillMetadata>;\r\n private dbService?: DatabaseService;\r\n private skillsBasePath: string;\r\n private logger: Logger;\r\n private debug: boolean;\r\n private maxMemoryBytes: number;\r\n private initialized: boolean = false;\r\n\r\n // Loading locks (prevent duplicate loads)\r\n private loadingLocks: Map<string, Promise<LoadedSkill>> = new Map();\r\n\r\n // Metrics\r\n private metrics = {\r\n hashMismatches: 0,\r\n cacheInvalidations: 0,\r\n };\r\n\r\n constructor(config: SkillLoaderConfig) {\r\n this.dbService = config.dbService;\r\n this.maxMemoryBytes = config.maxMemoryBytes ?? 100 * 1024 * 1024; // 100MB default\r\n this.skillsBasePath = config.skillsBasePath ?? path.join(process.cwd(), '.claude/skills');\r\n this.logger = config.logger ?? createLogger('skill-loader');\r\n this.debug = config.debug ?? false;\r\n\r\n // Initialize metadata map\r\n this.metadata = new Map();\r\n\r\n // Initialize LRU cache\r\n this.cache = new LRUSkillCache<SkillContent>({\r\n maxMemoryBytes: this.maxMemoryBytes,\r\n logger: this.logger,\r\n debug: this.debug,\r\n });\r\n\r\n if (this.debug) {\r\n this.logger.info('SkillLoader initialized', {\r\n maxMemoryBytes: this.maxMemoryBytes,\r\n maxMemoryMB: (this.maxMemoryBytes / 1024 / 1024).toFixed(2),\r\n skillsBasePath: this.skillsBasePath,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Initialize loader\r\n *\r\n * Scans skills directory and loads metadata (NOT content).\r\n * Fast: <2s for 500 skills.\r\n */\r\n async initialize(): Promise<void> {\r\n const startTime = Date.now();\r\n\r\n if (this.initialized) {\r\n this.logger.warn('SkillLoader already initialized');\r\n return;\r\n }\r\n\r\n this.logger.info('Initializing SkillLoader', { skillsBasePath: this.skillsBasePath });\r\n\r\n // Scan skills directory\r\n await this.scanSkillsDirectory();\r\n\r\n // Load metadata from database (if available)\r\n if (this.dbService) {\r\n await this.loadMetadataFromDatabase();\r\n }\r\n\r\n this.initialized = true;\r\n\r\n const initTime = Date.now() - startTime;\r\n this.logger.info('SkillLoader initialized', {\r\n skillsLoaded: this.metadata.size,\r\n initTimeMs: initTime,\r\n });\r\n\r\n if (initTime >= 2000) {\r\n this.logger.warn('Initialization time exceeded target', {\r\n initTimeMs: initTime,\r\n target: 2000,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Load skill content\r\n *\r\n * Lazy loading: content loaded on-demand.\r\n * - Cache hit: <100ms\r\n * - Cache miss: <500ms (disk I/O + hash validation)\r\n *\r\n * @param skillId - Skill ID to load\r\n * @returns Loaded skill with content\r\n */\r\n async loadSkill(skillId: string): Promise<LoadedSkill> {\r\n const startTime = Date.now();\r\n\r\n if (!this.initialized) {\r\n throw new StandardError(\r\n 'LOADER_NOT_INITIALIZED',\r\n 'SkillLoader not initialized. Call initialize() first.'\r\n );\r\n }\r\n\r\n // Check if already loading (prevent duplicate loads)\r\n const existingLoad = this.loadingLocks.get(skillId);\r\n if (existingLoad) {\r\n if (this.debug) {\r\n this.logger.debug('Waiting for existing load', { skillId });\r\n }\r\n return existingLoad;\r\n }\r\n\r\n // Create loading promise\r\n const loadPromise = this.doLoadSkill(skillId, startTime);\r\n this.loadingLocks.set(skillId, loadPromise);\r\n\r\n try {\r\n const skill = await loadPromise;\r\n return skill;\r\n } finally {\r\n this.loadingLocks.delete(skillId);\r\n }\r\n }\r\n\r\n /**\r\n * Internal skill loading implementation\r\n */\r\n private async doLoadSkill(skillId: string, startTime: number): Promise<LoadedSkill> {\r\n // Get metadata\r\n const meta = this.metadata.get(skillId);\r\n if (!meta) {\r\n throw new StandardError(\r\n 'SKILL_NOT_FOUND',\r\n `Skill not found: ${skillId}`,\r\n { skillId }\r\n );\r\n }\r\n\r\n // Check cache first\r\n const cached = this.cache.get(skillId);\r\n if (cached) {\r\n const loadTime = Date.now() - startTime;\r\n\r\n if (this.debug) {\r\n this.logger.debug('Cache hit', {\r\n skillId,\r\n loadTimeMs: loadTime,\r\n });\r\n }\r\n\r\n // Verify hash (detect file changes)\r\n const currentHash = await this.computeFileHash(meta.path);\r\n if (currentHash !== meta.hash) {\r\n // Hash mismatch - invalidate cache and reload\r\n this.metrics.hashMismatches++;\r\n this.metrics.cacheInvalidations++;\r\n this.cache.delete(skillId);\r\n\r\n if (this.debug) {\r\n this.logger.debug('Hash mismatch detected, reloading', {\r\n skillId,\r\n oldHash: meta.hash,\r\n newHash: currentHash,\r\n });\r\n }\r\n\r\n // Fall through to load from disk\r\n } else {\r\n // Cache hit with valid hash\r\n return {\r\n ...meta,\r\n content: cached,\r\n };\r\n }\r\n }\r\n\r\n // Cache miss - load from disk\r\n const content = await this.loadSkillFromDisk(meta);\r\n const loadTime = Date.now() - startTime;\r\n\r\n if (this.debug) {\r\n this.logger.debug('Cache miss, loaded from disk', {\r\n skillId,\r\n loadTimeMs: loadTime,\r\n });\r\n }\r\n\r\n if (loadTime >= 500) {\r\n this.logger.warn('Load time exceeded target', {\r\n skillId,\r\n loadTimeMs: loadTime,\r\n target: 500,\r\n });\r\n }\r\n\r\n // Update metadata with new hash (if changed)\r\n const currentHash = await this.computeFileHash(meta.path);\r\n if (currentHash !== meta.hash) {\r\n meta.hash = currentHash;\r\n this.metrics.hashMismatches++;\r\n\r\n // Update database\r\n if (this.dbService) {\r\n await this.updateMetadataInDatabase(meta);\r\n }\r\n }\r\n\r\n // Cache the content\r\n const contentSize = this.estimateContentSize(content);\r\n this.cache.set(skillId, content, contentSize);\r\n\r\n return {\r\n ...meta,\r\n content,\r\n };\r\n }\r\n\r\n /**\r\n * Load skill content from disk\r\n */\r\n private async loadSkillFromDisk(meta: SkillMetadata): Promise<SkillContent> {\r\n const skillPath = path.join(this.skillsBasePath, meta.path);\r\n\r\n try {\r\n const markdown = await fs.readFile(skillPath, 'utf-8');\r\n\r\n // Validate content\r\n if (!markdown || markdown.trim().length === 0) {\r\n throw new StandardError(\r\n 'EMPTY_SKILL_FILE',\r\n `Empty skill file: ${meta.id}`,\r\n { skillId: meta.id, path: skillPath }\r\n );\r\n }\r\n\r\n // Check for corrupted content (null bytes, invalid characters)\r\n if (markdown.includes('\\0') || /[\\x00-\\x08\\x0B-\\x0C\\x0E-\\x1F]/.test(markdown)) {\r\n throw new StandardError(\r\n 'CORRUPTED_SKILL_FILE',\r\n `Corrupted skill file (invalid characters): ${meta.id}`,\r\n { skillId: meta.id, path: skillPath }\r\n );\r\n }\r\n\r\n // Validate minimum content length (reasonable skill should be >50 chars)\r\n if (markdown.trim().length < 50) {\r\n throw new StandardError(\r\n 'INVALID_SKILL_FILE',\r\n `Invalid skill file (too short): ${meta.id}`,\r\n { skillId: meta.id, path: skillPath, length: markdown.trim().length }\r\n );\r\n }\r\n\r\n // Parse frontmatter (simple implementation)\r\n const { frontmatter, content } = this.parseFrontmatter(markdown);\r\n\r\n return {\r\n markdown,\r\n frontmatter,\r\n title: frontmatter?.title ?? meta.id,\r\n description: frontmatter?.description,\r\n };\r\n } catch (error) {\r\n throw new StandardError(\r\n 'SKILL_LOAD_ERROR',\r\n `Failed to load skill from disk: ${meta.id}`,\r\n { skillId: meta.id, path: skillPath, error: String(error) }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Scan skills directory and load metadata\r\n */\r\n private async scanSkillsDirectory(): Promise<void> {\r\n try {\r\n const entries = await fs.readdir(this.skillsBasePath, { withFileTypes: true });\r\n\r\n for (const entry of entries) {\r\n if (entry.isDirectory()) {\r\n const skillId = entry.name;\r\n const skillFile = path.join(this.skillsBasePath, skillId, 'SKILL.md');\r\n\r\n try {\r\n const stat = await fs.stat(skillFile);\r\n const hash = await this.computeFileHash(path.join(skillId, 'SKILL.md'));\r\n\r\n const metadata: SkillMetadata = {\r\n id: skillId,\r\n path: path.join(skillId, 'SKILL.md'),\r\n hash,\r\n size: stat.size,\r\n };\r\n\r\n this.metadata.set(skillId, metadata);\r\n } catch (error) {\r\n // Skip invalid skills\r\n if (this.debug) {\r\n this.logger.debug('Skipping invalid skill', {\r\n skillId,\r\n error: String(error),\r\n });\r\n }\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n throw new StandardError(\r\n 'SCAN_ERROR',\r\n 'Failed to scan skills directory',\r\n { skillsBasePath: this.skillsBasePath, error: String(error) }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Compute SHA-256 hash of file\r\n */\r\n private async computeFileHash(relativePath: string): Promise<string> {\r\n const fullPath = path.join(this.skillsBasePath, relativePath);\r\n const content = await fs.readFile(fullPath, 'utf-8');\r\n return crypto.createHash('sha256').update(content, 'utf-8').digest('hex');\r\n }\r\n\r\n /**\r\n * Load metadata from database\r\n */\r\n private async loadMetadataFromDatabase(): Promise<void> {\r\n if (!this.dbService) {\r\n return;\r\n }\r\n\r\n try {\r\n const sqliteAdapter = this.dbService.getAdapter('sqlite');\r\n const rows = await sqliteAdapter.raw<any[]>(\r\n 'SELECT id, path, hash, size, last_loaded FROM skill_metadata'\r\n );\r\n\r\n for (const row of rows) {\r\n const existing = this.metadata.get(row.id);\r\n if (existing) {\r\n // Update with database values\r\n existing.lastLoaded = row.last_loaded ? new Date(row.last_loaded) : undefined;\r\n }\r\n }\r\n } catch (error) {\r\n // Table might not exist yet\r\n if (this.debug) {\r\n this.logger.debug('Failed to load metadata from database', {\r\n error: String(error),\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Update metadata in database\r\n */\r\n private async updateMetadataInDatabase(meta: SkillMetadata): Promise<void> {\r\n if (!this.dbService) {\r\n return;\r\n }\r\n\r\n try {\r\n const sqliteAdapter = this.dbService.getAdapter('sqlite');\r\n await sqliteAdapter.raw(\r\n `INSERT OR REPLACE INTO skill_metadata (id, path, hash, size, last_loaded)\r\n VALUES (?, ?, ?, ?, ?)`,\r\n [meta.id, meta.path, meta.hash, meta.size, new Date().toISOString()]\r\n );\r\n } catch (error) {\r\n if (this.debug) {\r\n this.logger.debug('Failed to update metadata in database', {\r\n skillId: meta.id,\r\n error: String(error),\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Parse frontmatter from markdown\r\n */\r\n private parseFrontmatter(markdown: string): {\r\n frontmatter?: Record<string, any>;\r\n content: string;\r\n } {\r\n const frontmatterRegex = /^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n([\\s\\S]*)$/;\r\n const match = markdown.match(frontmatterRegex);\r\n\r\n if (!match) {\r\n return { content: markdown };\r\n }\r\n\r\n const [, frontmatterText, content] = match;\r\n const frontmatter: Record<string, any> = {};\r\n\r\n // Simple YAML parser (key: value)\r\n const lines = frontmatterText.split('\\n');\r\n for (const line of lines) {\r\n const colonIndex = line.indexOf(':');\r\n if (colonIndex > 0) {\r\n const key = line.substring(0, colonIndex).trim();\r\n const value = line.substring(colonIndex + 1).trim();\r\n frontmatter[key] = value;\r\n }\r\n }\r\n\r\n return { frontmatter, content };\r\n }\r\n\r\n /**\r\n * Estimate content size in bytes\r\n */\r\n private estimateContentSize(content: SkillContent): number {\r\n // Rough estimate: markdown size + frontmatter overhead\r\n let size = Buffer.byteLength(content.markdown, 'utf-8');\r\n\r\n if (content.frontmatter) {\r\n size += JSON.stringify(content.frontmatter).length;\r\n }\r\n\r\n return size;\r\n }\r\n\r\n /**\r\n * Get loader metrics\r\n */\r\n getMetrics(): LoaderMetrics {\r\n const cacheStats = this.cache.getStatistics();\r\n const contentLoaded = this.cache.size;\r\n\r\n return {\r\n skillsLoaded: this.metadata.size,\r\n skillContentLoaded: contentLoaded,\r\n memoryUsageBytes: cacheStats.memoryUsageBytes,\r\n cacheHits: cacheStats.hits,\r\n cacheMisses: cacheStats.misses,\r\n evictions: cacheStats.evictions,\r\n hashMismatches: this.metrics.hashMismatches,\r\n cacheInvalidations: this.metrics.cacheInvalidations,\r\n cacheHitRate: cacheStats.hitRate,\r\n };\r\n }\r\n\r\n /**\r\n * Reset metrics\r\n */\r\n resetMetrics(): void {\r\n this.cache.resetStatistics();\r\n this.metrics = {\r\n hashMismatches: 0,\r\n cacheInvalidations: 0,\r\n };\r\n }\r\n\r\n /**\r\n * Get cache statistics\r\n */\r\n getCacheStatistics(): CacheStatistics {\r\n return this.cache.getStatistics();\r\n }\r\n\r\n /**\r\n * Get loader configuration\r\n */\r\n getConfig(): { maxMemoryBytes: number; skillsBasePath: string } {\r\n return {\r\n maxMemoryBytes: this.maxMemoryBytes,\r\n skillsBasePath: this.skillsBasePath,\r\n };\r\n }\r\n\r\n /**\r\n * Clear cache\r\n */\r\n clearCache(): void {\r\n this.cache.clear();\r\n this.logger.info('Cache cleared');\r\n }\r\n}\r\n"],"names":["fs","path","crypto","LRUSkillCache","createLogger","StandardError","SkillLoader","cache","metadata","dbService","skillsBasePath","logger","debug","maxMemoryBytes","initialized","loadingLocks","Map","metrics","hashMismatches","cacheInvalidations","config","join","process","cwd","info","maxMemoryMB","toFixed","initialize","startTime","Date","now","warn","scanSkillsDirectory","loadMetadataFromDatabase","initTime","skillsLoaded","size","initTimeMs","target","loadSkill","skillId","existingLoad","get","loadPromise","doLoadSkill","set","skill","delete","meta","cached","loadTime","loadTimeMs","currentHash","computeFileHash","hash","oldHash","newHash","content","loadSkillFromDisk","updateMetadataInDatabase","contentSize","estimateContentSize","skillPath","markdown","readFile","trim","length","id","includes","test","frontmatter","parseFrontmatter","title","description","error","String","entries","readdir","withFileTypes","entry","isDirectory","name","skillFile","stat","relativePath","fullPath","createHash","update","digest","sqliteAdapter","getAdapter","rows","raw","row","existing","lastLoaded","last_loaded","undefined","toISOString","frontmatterRegex","match","frontmatterText","lines","split","line","colonIndex","indexOf","key","substring","value","Buffer","byteLength","JSON","stringify","getMetrics","cacheStats","getStatistics","contentLoaded","skillContentLoaded","memoryUsageBytes","cacheHits","hits","cacheMisses","misses","evictions","cacheHitRate","hitRate","resetMetrics","resetStatistics","getCacheStatistics","getConfig","clearCache","clear"],"mappings":"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"}