@skillsmith/mcp-server 0.1.0

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 (306) hide show
  1. package/dist/.tsbuildinfo +1 -0
  2. package/dist/src/__tests__/get-skill.test.d.ts +6 -0
  3. package/dist/src/__tests__/get-skill.test.d.ts.map +1 -0
  4. package/dist/src/__tests__/get-skill.test.js +88 -0
  5. package/dist/src/__tests__/get-skill.test.js.map +1 -0
  6. package/dist/src/__tests__/middleware/errorFormatter.test.d.ts +7 -0
  7. package/dist/src/__tests__/middleware/errorFormatter.test.d.ts.map +1 -0
  8. package/dist/src/__tests__/middleware/errorFormatter.test.js +304 -0
  9. package/dist/src/__tests__/middleware/errorFormatter.test.js.map +1 -0
  10. package/dist/src/__tests__/middleware/license.test.d.ts +7 -0
  11. package/dist/src/__tests__/middleware/license.test.d.ts.map +1 -0
  12. package/dist/src/__tests__/middleware/license.test.js +500 -0
  13. package/dist/src/__tests__/middleware/license.test.js.map +1 -0
  14. package/dist/src/__tests__/search.test.d.ts +6 -0
  15. package/dist/src/__tests__/search.test.d.ts.map +1 -0
  16. package/dist/src/__tests__/search.test.js +86 -0
  17. package/dist/src/__tests__/search.test.js.map +1 -0
  18. package/dist/src/__tests__/test-utils.d.ts +19 -0
  19. package/dist/src/__tests__/test-utils.d.ts.map +1 -0
  20. package/dist/src/__tests__/test-utils.js +87 -0
  21. package/dist/src/__tests__/test-utils.js.map +1 -0
  22. package/dist/src/context/index.d.ts +19 -0
  23. package/dist/src/context/index.d.ts.map +1 -0
  24. package/dist/src/context/index.js +25 -0
  25. package/dist/src/context/index.js.map +1 -0
  26. package/dist/src/context/project-detector.d.ts +145 -0
  27. package/dist/src/context/project-detector.d.ts.map +1 -0
  28. package/dist/src/context/project-detector.js +321 -0
  29. package/dist/src/context/project-detector.js.map +1 -0
  30. package/dist/src/context.d.ts +100 -0
  31. package/dist/src/context.d.ts.map +1 -0
  32. package/dist/src/context.js +157 -0
  33. package/dist/src/context.js.map +1 -0
  34. package/dist/src/core-shim.d.ts +7 -0
  35. package/dist/src/core-shim.d.ts.map +1 -0
  36. package/dist/src/core-shim.js +9 -0
  37. package/dist/src/core-shim.js.map +1 -0
  38. package/dist/src/health/healthCheck.d.ts +88 -0
  39. package/dist/src/health/healthCheck.d.ts.map +1 -0
  40. package/dist/src/health/healthCheck.js +117 -0
  41. package/dist/src/health/healthCheck.js.map +1 -0
  42. package/dist/src/health/index.d.ts +21 -0
  43. package/dist/src/health/index.d.ts.map +1 -0
  44. package/dist/src/health/index.js +21 -0
  45. package/dist/src/health/index.js.map +1 -0
  46. package/dist/src/health/readinessCheck.d.ts +139 -0
  47. package/dist/src/health/readinessCheck.d.ts.map +1 -0
  48. package/dist/src/health/readinessCheck.js +266 -0
  49. package/dist/src/health/readinessCheck.js.map +1 -0
  50. package/dist/src/index.d.ts +8 -0
  51. package/dist/src/index.d.ts.map +1 -0
  52. package/dist/src/index.js +178 -0
  53. package/dist/src/index.js.map +1 -0
  54. package/dist/src/index.test.d.ts +2 -0
  55. package/dist/src/index.test.d.ts.map +1 -0
  56. package/dist/src/index.test.js +43 -0
  57. package/dist/src/index.test.js.map +1 -0
  58. package/dist/src/logger.d.ts +26 -0
  59. package/dist/src/logger.d.ts.map +1 -0
  60. package/dist/src/logger.js +179 -0
  61. package/dist/src/logger.js.map +1 -0
  62. package/dist/src/middleware/__tests__/csp.test.d.ts +2 -0
  63. package/dist/src/middleware/__tests__/csp.test.d.ts.map +1 -0
  64. package/dist/src/middleware/__tests__/csp.test.js +389 -0
  65. package/dist/src/middleware/__tests__/csp.test.js.map +1 -0
  66. package/dist/src/middleware/csp.d.ts +87 -0
  67. package/dist/src/middleware/csp.d.ts.map +1 -0
  68. package/dist/src/middleware/csp.js +273 -0
  69. package/dist/src/middleware/csp.js.map +1 -0
  70. package/dist/src/middleware/degradation.d.ts +99 -0
  71. package/dist/src/middleware/degradation.d.ts.map +1 -0
  72. package/dist/src/middleware/degradation.js +315 -0
  73. package/dist/src/middleware/degradation.js.map +1 -0
  74. package/dist/src/middleware/errorFormatter.d.ts +119 -0
  75. package/dist/src/middleware/errorFormatter.d.ts.map +1 -0
  76. package/dist/src/middleware/errorFormatter.js +294 -0
  77. package/dist/src/middleware/errorFormatter.js.map +1 -0
  78. package/dist/src/middleware/index.d.ts +10 -0
  79. package/dist/src/middleware/index.d.ts.map +1 -0
  80. package/dist/src/middleware/index.js +14 -0
  81. package/dist/src/middleware/index.js.map +1 -0
  82. package/dist/src/middleware/license.d.ts +161 -0
  83. package/dist/src/middleware/license.d.ts.map +1 -0
  84. package/dist/src/middleware/license.js +281 -0
  85. package/dist/src/middleware/license.js.map +1 -0
  86. package/dist/src/middleware/toolFeatureMapping.d.ts +36 -0
  87. package/dist/src/middleware/toolFeatureMapping.d.ts.map +1 -0
  88. package/dist/src/middleware/toolFeatureMapping.js +90 -0
  89. package/dist/src/middleware/toolFeatureMapping.js.map +1 -0
  90. package/dist/src/onboarding/first-run.d.ts +64 -0
  91. package/dist/src/onboarding/first-run.d.ts.map +1 -0
  92. package/dist/src/onboarding/first-run.js +77 -0
  93. package/dist/src/onboarding/first-run.js.map +1 -0
  94. package/dist/src/onboarding/index.d.ts +7 -0
  95. package/dist/src/onboarding/index.d.ts.map +1 -0
  96. package/dist/src/onboarding/index.js +7 -0
  97. package/dist/src/onboarding/index.js.map +1 -0
  98. package/dist/src/suggestions/index.d.ts +21 -0
  99. package/dist/src/suggestions/index.d.ts.map +1 -0
  100. package/dist/src/suggestions/index.js +20 -0
  101. package/dist/src/suggestions/index.js.map +1 -0
  102. package/dist/src/suggestions/suggestion-engine.d.ts +185 -0
  103. package/dist/src/suggestions/suggestion-engine.d.ts.map +1 -0
  104. package/dist/src/suggestions/suggestion-engine.js +352 -0
  105. package/dist/src/suggestions/suggestion-engine.js.map +1 -0
  106. package/dist/src/suggestions/types.d.ts +88 -0
  107. package/dist/src/suggestions/types.d.ts.map +1 -0
  108. package/dist/src/suggestions/types.js +21 -0
  109. package/dist/src/suggestions/types.js.map +1 -0
  110. package/dist/src/tools/analyze.d.ts +151 -0
  111. package/dist/src/tools/analyze.d.ts.map +1 -0
  112. package/dist/src/tools/analyze.js +205 -0
  113. package/dist/src/tools/analyze.js.map +1 -0
  114. package/dist/src/tools/compare.d.ts +149 -0
  115. package/dist/src/tools/compare.d.ts.map +1 -0
  116. package/dist/src/tools/compare.js +464 -0
  117. package/dist/src/tools/compare.js.map +1 -0
  118. package/dist/src/tools/get-skill.d.ts +116 -0
  119. package/dist/src/tools/get-skill.d.ts.map +1 -0
  120. package/dist/src/tools/get-skill.js +224 -0
  121. package/dist/src/tools/get-skill.js.map +1 -0
  122. package/dist/src/tools/index.d.ts +20 -0
  123. package/dist/src/tools/index.d.ts.map +1 -0
  124. package/dist/src/tools/index.js +20 -0
  125. package/dist/src/tools/index.js.map +1 -0
  126. package/dist/src/tools/install.d.ts +122 -0
  127. package/dist/src/tools/install.d.ts.map +1 -0
  128. package/dist/src/tools/install.js +314 -0
  129. package/dist/src/tools/install.js.map +1 -0
  130. package/dist/src/tools/recommend.d.ts +171 -0
  131. package/dist/src/tools/recommend.d.ts.map +1 -0
  132. package/dist/src/tools/recommend.js +325 -0
  133. package/dist/src/tools/recommend.js.map +1 -0
  134. package/dist/src/tools/search.d.ts +121 -0
  135. package/dist/src/tools/search.d.ts.map +1 -0
  136. package/dist/src/tools/search.js +249 -0
  137. package/dist/src/tools/search.js.map +1 -0
  138. package/dist/src/tools/suggest.d.ts +181 -0
  139. package/dist/src/tools/suggest.d.ts.map +1 -0
  140. package/dist/src/tools/suggest.js +342 -0
  141. package/dist/src/tools/suggest.js.map +1 -0
  142. package/dist/src/tools/uninstall.d.ts +123 -0
  143. package/dist/src/tools/uninstall.d.ts.map +1 -0
  144. package/dist/src/tools/uninstall.js +250 -0
  145. package/dist/src/tools/uninstall.js.map +1 -0
  146. package/dist/src/tools/validate.d.ts +122 -0
  147. package/dist/src/tools/validate.d.ts.map +1 -0
  148. package/dist/src/tools/validate.js +497 -0
  149. package/dist/src/tools/validate.js.map +1 -0
  150. package/dist/src/utils/installed-skills.d.ts +101 -0
  151. package/dist/src/utils/installed-skills.d.ts.map +1 -0
  152. package/dist/src/utils/installed-skills.js +220 -0
  153. package/dist/src/utils/installed-skills.js.map +1 -0
  154. package/dist/src/utils/validation.d.ts +76 -0
  155. package/dist/src/utils/validation.d.ts.map +1 -0
  156. package/dist/src/utils/validation.js +153 -0
  157. package/dist/src/utils/validation.js.map +1 -0
  158. package/dist/src/webhooks/index.d.ts +8 -0
  159. package/dist/src/webhooks/index.d.ts.map +1 -0
  160. package/dist/src/webhooks/index.js +9 -0
  161. package/dist/src/webhooks/index.js.map +1 -0
  162. package/dist/src/webhooks/webhook-endpoint.d.ts +149 -0
  163. package/dist/src/webhooks/webhook-endpoint.d.ts.map +1 -0
  164. package/dist/src/webhooks/webhook-endpoint.js +339 -0
  165. package/dist/src/webhooks/webhook-endpoint.js.map +1 -0
  166. package/dist/tests/compare.test.d.ts +6 -0
  167. package/dist/tests/compare.test.d.ts.map +1 -0
  168. package/dist/tests/compare.test.js +225 -0
  169. package/dist/tests/compare.test.js.map +1 -0
  170. package/dist/tests/context/project-detector.test.d.ts +6 -0
  171. package/dist/tests/context/project-detector.test.d.ts.map +1 -0
  172. package/dist/tests/context/project-detector.test.js +719 -0
  173. package/dist/tests/context/project-detector.test.js.map +1 -0
  174. package/dist/tests/e2e/compare.e2e.test.d.ts +10 -0
  175. package/dist/tests/e2e/compare.e2e.test.d.ts.map +1 -0
  176. package/dist/tests/e2e/compare.e2e.test.js +286 -0
  177. package/dist/tests/e2e/compare.e2e.test.js.map +1 -0
  178. package/dist/tests/e2e/install-flow.e2e.test.d.ts +10 -0
  179. package/dist/tests/e2e/install-flow.e2e.test.d.ts.map +1 -0
  180. package/dist/tests/e2e/install-flow.e2e.test.js +209 -0
  181. package/dist/tests/e2e/install-flow.e2e.test.js.map +1 -0
  182. package/dist/tests/e2e/recommend.e2e.test.d.ts +12 -0
  183. package/dist/tests/e2e/recommend.e2e.test.d.ts.map +1 -0
  184. package/dist/tests/e2e/recommend.e2e.test.js +347 -0
  185. package/dist/tests/e2e/recommend.e2e.test.js.map +1 -0
  186. package/dist/tests/e2e/skill-flow.e2e.test.d.ts +10 -0
  187. package/dist/tests/e2e/skill-flow.e2e.test.d.ts.map +1 -0
  188. package/dist/tests/e2e/skill-flow.e2e.test.js +280 -0
  189. package/dist/tests/e2e/skill-flow.e2e.test.js.map +1 -0
  190. package/dist/tests/e2e/suggest.e2e.test.d.ts +13 -0
  191. package/dist/tests/e2e/suggest.e2e.test.d.ts.map +1 -0
  192. package/dist/tests/e2e/suggest.e2e.test.js +347 -0
  193. package/dist/tests/e2e/suggest.e2e.test.js.map +1 -0
  194. package/dist/tests/e2e/utils/baseline-collector.d.ts +107 -0
  195. package/dist/tests/e2e/utils/baseline-collector.d.ts.map +1 -0
  196. package/dist/tests/e2e/utils/baseline-collector.js +211 -0
  197. package/dist/tests/e2e/utils/baseline-collector.js.map +1 -0
  198. package/dist/tests/e2e/utils/hardcoded-detector.d.ts +46 -0
  199. package/dist/tests/e2e/utils/hardcoded-detector.d.ts.map +1 -0
  200. package/dist/tests/e2e/utils/hardcoded-detector.js +255 -0
  201. package/dist/tests/e2e/utils/hardcoded-detector.js.map +1 -0
  202. package/dist/tests/e2e/utils/index.d.ts +7 -0
  203. package/dist/tests/e2e/utils/index.d.ts.map +1 -0
  204. package/dist/tests/e2e/utils/index.js +7 -0
  205. package/dist/tests/e2e/utils/index.js.map +1 -0
  206. package/dist/tests/e2e/utils/linear-reporter.d.ts +60 -0
  207. package/dist/tests/e2e/utils/linear-reporter.d.ts.map +1 -0
  208. package/dist/tests/e2e/utils/linear-reporter.js +232 -0
  209. package/dist/tests/e2e/utils/linear-reporter.js.map +1 -0
  210. package/dist/tests/health.test.d.ts +9 -0
  211. package/dist/tests/health.test.d.ts.map +1 -0
  212. package/dist/tests/health.test.js +308 -0
  213. package/dist/tests/health.test.js.map +1 -0
  214. package/dist/tests/integration/analyze.integration.test.d.ts +2 -0
  215. package/dist/tests/integration/analyze.integration.test.d.ts.map +1 -0
  216. package/dist/tests/integration/analyze.integration.test.js +244 -0
  217. package/dist/tests/integration/analyze.integration.test.js.map +1 -0
  218. package/dist/tests/integration/compare.integration.test.d.ts +2 -0
  219. package/dist/tests/integration/compare.integration.test.d.ts.map +1 -0
  220. package/dist/tests/integration/compare.integration.test.js +120 -0
  221. package/dist/tests/integration/compare.integration.test.js.map +1 -0
  222. package/dist/tests/integration/fixtures/test-skills.d.ts +62 -0
  223. package/dist/tests/integration/fixtures/test-skills.d.ts.map +1 -0
  224. package/dist/tests/integration/fixtures/test-skills.js +644 -0
  225. package/dist/tests/integration/fixtures/test-skills.js.map +1 -0
  226. package/dist/tests/integration/get-skill.integration.test.d.ts +6 -0
  227. package/dist/tests/integration/get-skill.integration.test.d.ts.map +1 -0
  228. package/dist/tests/integration/get-skill.integration.test.js +203 -0
  229. package/dist/tests/integration/get-skill.integration.test.js.map +1 -0
  230. package/dist/tests/integration/github-api.integration.test.d.ts +14 -0
  231. package/dist/tests/integration/github-api.integration.test.d.ts.map +1 -0
  232. package/dist/tests/integration/github-api.integration.test.js +190 -0
  233. package/dist/tests/integration/github-api.integration.test.js.map +1 -0
  234. package/dist/tests/integration/install.integration.test.d.ts +6 -0
  235. package/dist/tests/integration/install.integration.test.d.ts.map +1 -0
  236. package/dist/tests/integration/install.integration.test.js +282 -0
  237. package/dist/tests/integration/install.integration.test.js.map +1 -0
  238. package/dist/tests/integration/recommend.integration.test.d.ts +2 -0
  239. package/dist/tests/integration/recommend.integration.test.d.ts.map +1 -0
  240. package/dist/tests/integration/recommend.integration.test.js +215 -0
  241. package/dist/tests/integration/recommend.integration.test.js.map +1 -0
  242. package/dist/tests/integration/search.integration.test.d.ts +6 -0
  243. package/dist/tests/integration/search.integration.test.d.ts.map +1 -0
  244. package/dist/tests/integration/search.integration.test.js +229 -0
  245. package/dist/tests/integration/search.integration.test.js.map +1 -0
  246. package/dist/tests/integration/setup.d.ts +71 -0
  247. package/dist/tests/integration/setup.d.ts.map +1 -0
  248. package/dist/tests/integration/setup.js +124 -0
  249. package/dist/tests/integration/setup.js.map +1 -0
  250. package/dist/tests/integration/uninstall.integration.test.d.ts +6 -0
  251. package/dist/tests/integration/uninstall.integration.test.d.ts.map +1 -0
  252. package/dist/tests/integration/uninstall.integration.test.js +296 -0
  253. package/dist/tests/integration/uninstall.integration.test.js.map +1 -0
  254. package/dist/tests/integration/validate.integration.test.d.ts +2 -0
  255. package/dist/tests/integration/validate.integration.test.d.ts.map +1 -0
  256. package/dist/tests/integration/validate.integration.test.js +181 -0
  257. package/dist/tests/integration/validate.integration.test.js.map +1 -0
  258. package/dist/tests/onboarding/first-run.test.d.ts +7 -0
  259. package/dist/tests/onboarding/first-run.test.d.ts.map +1 -0
  260. package/dist/tests/onboarding/first-run.test.js +258 -0
  261. package/dist/tests/onboarding/first-run.test.js.map +1 -0
  262. package/dist/tests/performance/search-performance.test.d.ts +10 -0
  263. package/dist/tests/performance/search-performance.test.d.ts.map +1 -0
  264. package/dist/tests/performance/search-performance.test.js +218 -0
  265. package/dist/tests/performance/search-performance.test.js.map +1 -0
  266. package/dist/tests/recommend.test.d.ts +6 -0
  267. package/dist/tests/recommend.test.d.ts.map +1 -0
  268. package/dist/tests/recommend.test.js +208 -0
  269. package/dist/tests/recommend.test.js.map +1 -0
  270. package/dist/tests/suggestions/suggestion-engine.test.d.ts +6 -0
  271. package/dist/tests/suggestions/suggestion-engine.test.d.ts.map +1 -0
  272. package/dist/tests/suggestions/suggestion-engine.test.js +448 -0
  273. package/dist/tests/suggestions/suggestion-engine.test.js.map +1 -0
  274. package/dist/tests/test-utils.d.ts +74 -0
  275. package/dist/tests/test-utils.d.ts.map +1 -0
  276. package/dist/tests/test-utils.js +98 -0
  277. package/dist/tests/test-utils.js.map +1 -0
  278. package/dist/tests/tools.test.d.ts +5 -0
  279. package/dist/tests/tools.test.d.ts.map +1 -0
  280. package/dist/tests/tools.test.js +138 -0
  281. package/dist/tests/tools.test.js.map +1 -0
  282. package/dist/tests/unit/installed-skills.test.d.ts +6 -0
  283. package/dist/tests/unit/installed-skills.test.d.ts.map +1 -0
  284. package/dist/tests/unit/installed-skills.test.js +285 -0
  285. package/dist/tests/unit/installed-skills.test.js.map +1 -0
  286. package/dist/tests/unit/logger.test.d.ts +6 -0
  287. package/dist/tests/unit/logger.test.d.ts.map +1 -0
  288. package/dist/tests/unit/logger.test.js +281 -0
  289. package/dist/tests/unit/logger.test.js.map +1 -0
  290. package/dist/tests/validate.test.d.ts +5 -0
  291. package/dist/tests/validate.test.d.ts.map +1 -0
  292. package/dist/tests/validate.test.js +303 -0
  293. package/dist/tests/validate.test.js.map +1 -0
  294. package/dist/tests/webhooks/proxy-trust.security.test.d.ts +8 -0
  295. package/dist/tests/webhooks/proxy-trust.security.test.d.ts.map +1 -0
  296. package/dist/tests/webhooks/proxy-trust.security.test.js +145 -0
  297. package/dist/tests/webhooks/proxy-trust.security.test.js.map +1 -0
  298. package/dist/tests/webhooks/rate-limiter.security.test.d.ts +8 -0
  299. package/dist/tests/webhooks/rate-limiter.security.test.d.ts.map +1 -0
  300. package/dist/tests/webhooks/rate-limiter.security.test.js +122 -0
  301. package/dist/tests/webhooks/rate-limiter.security.test.js.map +1 -0
  302. package/dist/vitest.config.d.ts +6 -0
  303. package/dist/vitest.config.d.ts.map +1 -0
  304. package/dist/vitest.config.js +13 -0
  305. package/dist/vitest.config.js.map +1 -0
  306. package/package.json +63 -0
@@ -0,0 +1,497 @@
1
+ /**
2
+ * @fileoverview MCP Skill Validate Tool for validating SKILL.md files
3
+ * @module @skillsmith/mcp-server/tools/validate
4
+ * @see SMI-742: Add MCP Tool skill_validate
5
+ *
6
+ * Validates skill definition files against the Skillsmith specification:
7
+ * - YAML frontmatter structure
8
+ * - Required fields (name, description)
9
+ * - Field length limits
10
+ * - Security patterns (SSRF, path traversal)
11
+ *
12
+ * @example
13
+ * // Basic validation
14
+ * const result = await executeValidate({
15
+ * skill_path: '/path/to/SKILL.md'
16
+ * });
17
+ *
18
+ * @example
19
+ * // Strict validation
20
+ * const result = await executeValidate({
21
+ * skill_path: '/path/to/skill-directory',
22
+ * strict: true
23
+ * });
24
+ */
25
+ import { z } from 'zod';
26
+ import { promises as fs } from 'fs';
27
+ import { join } from 'path';
28
+ import { SkillsmithError, ErrorCodes } from '@skillsmith/core';
29
+ /**
30
+ * Zod schema for validate tool input
31
+ */
32
+ export const validateInputSchema = z.object({
33
+ /** Path to SKILL.md file or skill directory */
34
+ skill_path: z.string().min(1, 'skill_path is required'),
35
+ /** Enable strict validation (default false) */
36
+ strict: z.boolean().default(false),
37
+ });
38
+ /**
39
+ * MCP tool schema definition for skill_validate
40
+ */
41
+ export const validateToolSchema = {
42
+ name: 'skill_validate',
43
+ description: 'Validate a SKILL.md file or skill directory against Skillsmith specification. Checks structure, required fields, and security patterns.',
44
+ inputSchema: {
45
+ type: 'object',
46
+ properties: {
47
+ skill_path: {
48
+ type: 'string',
49
+ description: 'Path to SKILL.md file or skill directory containing SKILL.md',
50
+ },
51
+ strict: {
52
+ type: 'boolean',
53
+ description: 'Enable strict validation mode (default false). Strict mode treats warnings as errors.',
54
+ default: false,
55
+ },
56
+ },
57
+ required: ['skill_path'],
58
+ },
59
+ };
60
+ /**
61
+ * Maximum field lengths for validation
62
+ */
63
+ const FIELD_LIMITS = {
64
+ name: 64,
65
+ description: 1024,
66
+ author: 128,
67
+ version: 32,
68
+ category: 64,
69
+ license: 64,
70
+ tagLength: 32,
71
+ maxTags: 20,
72
+ };
73
+ /**
74
+ * Dangerous URL patterns for SSRF prevention
75
+ */
76
+ const SSRF_PATTERNS = [
77
+ /^file:\/\//i,
78
+ /^gopher:\/\//i,
79
+ /^dict:\/\//i,
80
+ /^ldap:\/\//i,
81
+ /localhost/i,
82
+ /127\.0\.0\.\d+/,
83
+ /0\.0\.0\.0/,
84
+ /\[::1\]/,
85
+ /10\.\d+\.\d+\.\d+/,
86
+ /172\.(1[6-9]|2\d|3[01])\.\d+\.\d+/,
87
+ /192\.168\.\d+\.\d+/,
88
+ ];
89
+ /**
90
+ * Path traversal patterns
91
+ */
92
+ const PATH_TRAVERSAL_PATTERNS = [/\.\./, /\.\.%2[fF]/, /%2[eE]%2[eE]/, /\\\.\\./];
93
+ /**
94
+ * Parse YAML frontmatter from markdown content
95
+ */
96
+ function parseYamlFrontmatter(content) {
97
+ const trimmed = content.trim();
98
+ if (!trimmed.startsWith('---')) {
99
+ return null;
100
+ }
101
+ const endIndex = trimmed.indexOf('---', 3);
102
+ if (endIndex === -1) {
103
+ return null;
104
+ }
105
+ const yamlContent = trimmed.slice(3, endIndex).trim();
106
+ const result = {};
107
+ const lines = yamlContent.split('\n');
108
+ let currentKey = null;
109
+ let arrayBuffer = [];
110
+ let inArray = false;
111
+ for (const line of lines) {
112
+ const trimmedLine = line.trim();
113
+ if (!trimmedLine || trimmedLine.startsWith('#')) {
114
+ continue;
115
+ }
116
+ if (trimmedLine.startsWith('- ')) {
117
+ if (currentKey && inArray) {
118
+ const value = trimmedLine
119
+ .slice(2)
120
+ .trim()
121
+ .replace(/^["']|["']$/g, '');
122
+ arrayBuffer.push(value);
123
+ }
124
+ continue;
125
+ }
126
+ const colonIndex = trimmedLine.indexOf(':');
127
+ if (colonIndex > 0) {
128
+ if (currentKey && inArray && arrayBuffer.length > 0) {
129
+ result[currentKey] = arrayBuffer;
130
+ arrayBuffer = [];
131
+ }
132
+ const key = trimmedLine.slice(0, colonIndex).trim();
133
+ const value = trimmedLine.slice(colonIndex + 1).trim();
134
+ if (value === '' || value === '|' || value === '>') {
135
+ currentKey = key;
136
+ inArray = true;
137
+ arrayBuffer = [];
138
+ }
139
+ else {
140
+ currentKey = null;
141
+ inArray = false;
142
+ let parsedValue = value;
143
+ if ((value.startsWith('"') && value.endsWith('"')) ||
144
+ (value.startsWith("'") && value.endsWith("'"))) {
145
+ parsedValue = value.slice(1, -1);
146
+ }
147
+ else if (value === 'true') {
148
+ parsedValue = true;
149
+ }
150
+ else if (value === 'false') {
151
+ parsedValue = false;
152
+ }
153
+ else if (/^-?\d+(\.\d+)?$/.test(value)) {
154
+ parsedValue = parseFloat(value);
155
+ }
156
+ else if (value.startsWith('[') && value.endsWith(']')) {
157
+ parsedValue = value
158
+ .slice(1, -1)
159
+ .split(',')
160
+ .map((item) => item.trim().replace(/^["']|["']$/g, ''))
161
+ .filter((item) => item.length > 0);
162
+ }
163
+ result[key] = parsedValue;
164
+ }
165
+ }
166
+ }
167
+ if (currentKey && inArray && arrayBuffer.length > 0) {
168
+ result[currentKey] = arrayBuffer;
169
+ }
170
+ return result;
171
+ }
172
+ /**
173
+ * Check for SSRF patterns in a URL
174
+ */
175
+ function hasSsrfPattern(url) {
176
+ return SSRF_PATTERNS.some((pattern) => pattern.test(url));
177
+ }
178
+ /**
179
+ * Check for path traversal patterns
180
+ */
181
+ function hasPathTraversal(path) {
182
+ return PATH_TRAVERSAL_PATTERNS.some((pattern) => pattern.test(path));
183
+ }
184
+ /**
185
+ * Validate skill metadata
186
+ */
187
+ function validateMetadata(metadata, strict) {
188
+ const errors = [];
189
+ // Required fields
190
+ if (!metadata.name) {
191
+ errors.push({
192
+ field: 'name',
193
+ message: 'Required field "name" is missing',
194
+ severity: 'error',
195
+ });
196
+ }
197
+ else if (typeof metadata.name !== 'string') {
198
+ errors.push({
199
+ field: 'name',
200
+ message: 'Field "name" must be a string',
201
+ severity: 'error',
202
+ });
203
+ }
204
+ else if (metadata.name.length > FIELD_LIMITS.name) {
205
+ errors.push({
206
+ field: 'name',
207
+ message: `Field "name" exceeds maximum length of ${FIELD_LIMITS.name} characters`,
208
+ severity: 'error',
209
+ });
210
+ }
211
+ // Description validation
212
+ if (!metadata.description) {
213
+ errors.push({
214
+ field: 'description',
215
+ message: 'Required field "description" is missing',
216
+ severity: strict ? 'error' : 'warning',
217
+ });
218
+ }
219
+ else if (typeof metadata.description !== 'string') {
220
+ errors.push({
221
+ field: 'description',
222
+ message: 'Field "description" must be a string',
223
+ severity: 'error',
224
+ });
225
+ }
226
+ else if (metadata.description.length > FIELD_LIMITS.description) {
227
+ errors.push({
228
+ field: 'description',
229
+ message: `Field "description" exceeds maximum length of ${FIELD_LIMITS.description} characters`,
230
+ severity: 'error',
231
+ });
232
+ }
233
+ // Author validation
234
+ if (metadata.author !== undefined) {
235
+ if (typeof metadata.author !== 'string') {
236
+ errors.push({
237
+ field: 'author',
238
+ message: 'Field "author" must be a string',
239
+ severity: 'error',
240
+ });
241
+ }
242
+ else if (metadata.author.length > FIELD_LIMITS.author) {
243
+ errors.push({
244
+ field: 'author',
245
+ message: `Field "author" exceeds maximum length of ${FIELD_LIMITS.author} characters`,
246
+ severity: 'error',
247
+ });
248
+ }
249
+ }
250
+ // Version validation
251
+ if (metadata.version !== undefined) {
252
+ if (typeof metadata.version !== 'string') {
253
+ errors.push({
254
+ field: 'version',
255
+ message: 'Field "version" must be a string',
256
+ severity: 'error',
257
+ });
258
+ }
259
+ else if (metadata.version.length > FIELD_LIMITS.version) {
260
+ errors.push({
261
+ field: 'version',
262
+ message: `Field "version" exceeds maximum length of ${FIELD_LIMITS.version} characters`,
263
+ severity: 'error',
264
+ });
265
+ }
266
+ }
267
+ else if (strict) {
268
+ errors.push({
269
+ field: 'version',
270
+ message: 'Field "version" is recommended',
271
+ severity: 'warning',
272
+ });
273
+ }
274
+ // Tags validation
275
+ if (metadata.tags !== undefined) {
276
+ if (!Array.isArray(metadata.tags)) {
277
+ errors.push({
278
+ field: 'tags',
279
+ message: 'Field "tags" must be an array',
280
+ severity: 'error',
281
+ });
282
+ }
283
+ else {
284
+ if (metadata.tags.length > FIELD_LIMITS.maxTags) {
285
+ errors.push({
286
+ field: 'tags',
287
+ message: `Field "tags" exceeds maximum count of ${FIELD_LIMITS.maxTags}`,
288
+ severity: 'error',
289
+ });
290
+ }
291
+ for (let i = 0; i < metadata.tags.length; i++) {
292
+ const tag = metadata.tags[i];
293
+ if (typeof tag !== 'string') {
294
+ errors.push({
295
+ field: `tags[${i}]`,
296
+ message: 'Tag must be a string',
297
+ severity: 'error',
298
+ });
299
+ }
300
+ else if (tag.length > FIELD_LIMITS.tagLength) {
301
+ errors.push({
302
+ field: `tags[${i}]`,
303
+ message: `Tag exceeds maximum length of ${FIELD_LIMITS.tagLength} characters`,
304
+ severity: 'error',
305
+ });
306
+ }
307
+ }
308
+ }
309
+ }
310
+ else if (strict) {
311
+ errors.push({
312
+ field: 'tags',
313
+ message: 'Field "tags" is recommended for discoverability',
314
+ severity: 'warning',
315
+ });
316
+ }
317
+ // Security: Check repository URL for SSRF
318
+ if (metadata.repository !== undefined) {
319
+ if (typeof metadata.repository !== 'string') {
320
+ errors.push({
321
+ field: 'repository',
322
+ message: 'Field "repository" must be a string',
323
+ severity: 'error',
324
+ });
325
+ }
326
+ else if (hasSsrfPattern(metadata.repository)) {
327
+ errors.push({
328
+ field: 'repository',
329
+ message: 'Field "repository" contains potentially dangerous URL pattern',
330
+ severity: 'error',
331
+ });
332
+ }
333
+ }
334
+ // Security: Check homepage URL for SSRF
335
+ if (metadata.homepage !== undefined) {
336
+ if (typeof metadata.homepage !== 'string') {
337
+ errors.push({
338
+ field: 'homepage',
339
+ message: 'Field "homepage" must be a string',
340
+ severity: 'error',
341
+ });
342
+ }
343
+ else if (hasSsrfPattern(metadata.homepage)) {
344
+ errors.push({
345
+ field: 'homepage',
346
+ message: 'Field "homepage" contains potentially dangerous URL pattern',
347
+ severity: 'error',
348
+ });
349
+ }
350
+ }
351
+ // Security: Check for path traversal in any string fields
352
+ for (const [key, value] of Object.entries(metadata)) {
353
+ if (typeof value === 'string' && hasPathTraversal(value)) {
354
+ errors.push({
355
+ field: key,
356
+ message: `Field "${key}" contains path traversal pattern`,
357
+ severity: 'error',
358
+ });
359
+ }
360
+ }
361
+ return errors;
362
+ }
363
+ /**
364
+ * Execute skill validation.
365
+ *
366
+ * Validates a SKILL.md file against the Skillsmith specification.
367
+ * Checks structure, required fields, field lengths, and security patterns.
368
+ *
369
+ * @param input - Validation parameters
370
+ * @returns Promise resolving to validation response
371
+ * @throws {SkillsmithError} When path is invalid or file cannot be read
372
+ *
373
+ * @example
374
+ * const response = await executeValidate({
375
+ * skill_path: './skills/my-skill/SKILL.md',
376
+ * strict: true
377
+ * });
378
+ * if (response.valid) {
379
+ * console.log('Skill is valid:', response.metadata);
380
+ * } else {
381
+ * console.log('Errors:', response.errors);
382
+ * }
383
+ */
384
+ export async function executeValidate(input, _context) {
385
+ const startTime = performance.now();
386
+ // Validate input with Zod
387
+ const validated = validateInputSchema.parse(input);
388
+ const { skill_path, strict } = validated;
389
+ // Security: Check for path traversal in input path
390
+ if (hasPathTraversal(skill_path)) {
391
+ throw new SkillsmithError(ErrorCodes.VALIDATION_INVALID_TYPE, 'Path contains path traversal pattern', { details: { path: skill_path } });
392
+ }
393
+ // Determine actual file path
394
+ let filePath = skill_path;
395
+ let isDirectory = false;
396
+ try {
397
+ const stats = await fs.stat(skill_path);
398
+ isDirectory = stats.isDirectory();
399
+ if (isDirectory) {
400
+ filePath = join(skill_path, 'SKILL.md');
401
+ }
402
+ }
403
+ catch {
404
+ // Path doesn't exist or is inaccessible
405
+ throw new SkillsmithError(ErrorCodes.SKILL_NOT_FOUND, `Path not found: ${skill_path}`, {
406
+ details: { path: skill_path },
407
+ });
408
+ }
409
+ // Read file content
410
+ let content;
411
+ try {
412
+ content = await fs.readFile(filePath, 'utf-8');
413
+ }
414
+ catch {
415
+ throw new SkillsmithError(ErrorCodes.SKILL_NOT_FOUND, `Cannot read file: ${filePath}`, {
416
+ details: { path: filePath },
417
+ });
418
+ }
419
+ // Parse frontmatter
420
+ const metadata = parseYamlFrontmatter(content);
421
+ const errors = [];
422
+ if (!metadata) {
423
+ errors.push({
424
+ field: 'frontmatter',
425
+ message: 'Failed to parse YAML frontmatter. Ensure file starts with "---" and ends with "---"',
426
+ severity: 'error',
427
+ });
428
+ }
429
+ else {
430
+ // Validate metadata
431
+ errors.push(...validateMetadata(metadata, strict));
432
+ }
433
+ // Determine validity
434
+ const hasErrors = errors.some((e) => e.severity === 'error');
435
+ const valid = !hasErrors;
436
+ const endTime = performance.now();
437
+ return {
438
+ valid,
439
+ errors,
440
+ metadata: valid && metadata ? metadata : null,
441
+ path: filePath,
442
+ timing: {
443
+ totalMs: Math.round(endTime - startTime),
444
+ },
445
+ };
446
+ }
447
+ /**
448
+ * Format validation results for terminal display
449
+ */
450
+ export function formatValidationResults(response) {
451
+ const lines = [];
452
+ lines.push('\n=== Skill Validation Results ===\n');
453
+ lines.push(`Path: ${response.path}`);
454
+ lines.push('');
455
+ if (response.valid) {
456
+ lines.push('Status: VALID');
457
+ lines.push('');
458
+ if (response.metadata) {
459
+ lines.push('Metadata:');
460
+ if (response.metadata.name) {
461
+ lines.push(` Name: ${response.metadata.name}`);
462
+ }
463
+ if (response.metadata.description) {
464
+ const desc = String(response.metadata.description);
465
+ lines.push(` Description: ${desc.slice(0, 80)}${desc.length > 80 ? '...' : ''}`);
466
+ }
467
+ if (response.metadata.author) {
468
+ lines.push(` Author: ${response.metadata.author}`);
469
+ }
470
+ if (response.metadata.version) {
471
+ lines.push(` Version: ${response.metadata.version}`);
472
+ }
473
+ if (response.metadata.tags && Array.isArray(response.metadata.tags)) {
474
+ lines.push(` Tags: ${response.metadata.tags.join(', ')}`);
475
+ }
476
+ }
477
+ }
478
+ else {
479
+ lines.push('Status: INVALID');
480
+ lines.push('');
481
+ }
482
+ if (response.errors.length > 0) {
483
+ const errorCount = response.errors.filter((e) => e.severity === 'error').length;
484
+ const warningCount = response.errors.filter((e) => e.severity === 'warning').length;
485
+ lines.push(`Issues: ${errorCount} error(s), ${warningCount} warning(s)`);
486
+ lines.push('');
487
+ for (const error of response.errors) {
488
+ const prefix = error.severity === 'error' ? '[ERROR]' : '[WARN]';
489
+ lines.push(` ${prefix} ${error.field}: ${error.message}`);
490
+ }
491
+ }
492
+ lines.push('');
493
+ lines.push('---');
494
+ lines.push(`Completed in ${response.timing.totalMs}ms`);
495
+ return lines.join('\n');
496
+ }
497
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/tools/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * @fileoverview Utility for auto-detecting installed skills from ~/.claude/skills/
3
+ * @module @skillsmith/mcp-server/utils/installed-skills
4
+ * @see SMI-906: Auto-detect installed skills from ~/.claude/skills/
5
+ *
6
+ * Scans the user's skills directory and extracts skill IDs from SKILL.md files.
7
+ * Falls back to folder name if no SKILL.md or no ID found in frontmatter.
8
+ *
9
+ * @example
10
+ * const skills = await getInstalledSkills();
11
+ * // Returns: ["docker", "linear", "varlock"]
12
+ */
13
+ /**
14
+ * Result from parsing a SKILL.md file
15
+ */
16
+ interface SkillMdParsed {
17
+ /** Skill ID from name field */
18
+ id: string | null;
19
+ /** Skill name from name field */
20
+ name: string | null;
21
+ /** Skill description from description field */
22
+ description: string | null;
23
+ }
24
+ /**
25
+ * Parse SKILL.md frontmatter to extract skill metadata.
26
+ *
27
+ * Extracts the `name` field from YAML frontmatter in SKILL.md files.
28
+ * Frontmatter is delimited by `---` lines at the start of the file.
29
+ *
30
+ * @param content - Content of the SKILL.md file
31
+ * @returns Parsed skill metadata, or null values if parsing fails
32
+ *
33
+ * @example
34
+ * const content = `---
35
+ * name: docker
36
+ * description: Docker skill
37
+ * ---
38
+ * # Docker Skill`;
39
+ * parseSkillMd(content); // { id: "docker", name: "docker", description: "Docker skill" }
40
+ */
41
+ export declare function parseSkillMd(content: string): SkillMdParsed;
42
+ /**
43
+ * Get the skill ID from a skill directory.
44
+ *
45
+ * Looks for SKILL.md in the directory and extracts the ID from frontmatter.
46
+ * Falls back to the directory name if no SKILL.md or no ID found.
47
+ *
48
+ * @param skillDir - Path to the skill directory
49
+ * @param dirName - Name of the directory (used as fallback)
50
+ * @returns Skill ID
51
+ */
52
+ export declare function getSkillIdFromDir(skillDir: string, dirName: string): string;
53
+ /**
54
+ * Auto-detect installed skills from ~/.claude/skills/ directory.
55
+ *
56
+ * Scans the skills directory for subdirectories containing SKILL.md files.
57
+ * Extracts the skill ID from the `name` field in SKILL.md frontmatter.
58
+ * Falls back to directory name if no SKILL.md or no name field found.
59
+ *
60
+ * @param skillsDir - Optional custom skills directory path (defaults to ~/.claude/skills/)
61
+ * @returns Promise resolving to array of skill IDs
62
+ *
63
+ * @example
64
+ * const skills = await getInstalledSkills();
65
+ * // Returns: ["docker", "linear", "varlock"]
66
+ *
67
+ * @example
68
+ * // With custom directory
69
+ * const skills = await getInstalledSkills('/path/to/custom/skills');
70
+ */
71
+ export declare function getInstalledSkills(skillsDir?: string): Promise<string[]>;
72
+ /**
73
+ * Synchronous version of getInstalledSkills for use in non-async contexts.
74
+ *
75
+ * @param skillsDir - Optional custom skills directory path (defaults to ~/.claude/skills/)
76
+ * @returns Array of skill IDs
77
+ */
78
+ export declare function getInstalledSkillsSync(skillsDir?: string): string[];
79
+ /**
80
+ * Get detailed information about installed skills.
81
+ *
82
+ * Returns full parsed information from SKILL.md files, not just IDs.
83
+ *
84
+ * @param skillsDir - Optional custom skills directory path
85
+ * @returns Array of skill information objects
86
+ */
87
+ export interface InstalledSkillInfo {
88
+ /** Skill ID (from name field or directory name) */
89
+ id: string;
90
+ /** Directory name */
91
+ directory: string;
92
+ /** Full path to skill directory */
93
+ path: string;
94
+ /** Whether SKILL.md was found */
95
+ hasSkillMd: boolean;
96
+ /** Description from SKILL.md if available */
97
+ description: string | null;
98
+ }
99
+ export declare function getInstalledSkillsDetailed(skillsDir?: string): Promise<InstalledSkillInfo[]>;
100
+ export {};
101
+ //# sourceMappingURL=installed-skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installed-skills.d.ts","sourceRoot":"","sources":["../../../src/utils/installed-skills.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAWH;;GAEG;AACH,UAAU,aAAa;IACrB,+BAA+B;IAC/B,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;IACjB,iCAAiC;IACjC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,+CAA+C;IAC/C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAuC3D;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAoB3E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAgC9E;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAgCnE;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAA;IACV,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,iCAAiC;IACjC,UAAU,EAAE,OAAO,CAAA;IACnB,6CAA6C;IAC7C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B;AAED,wBAAsB,0BAA0B,CAC9C,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,kBAAkB,EAAE,CAAC,CA4D/B"}