@skillsmith/mcp-server 0.3.3 → 0.3.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 (261) hide show
  1. package/README.md +5 -3
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/src/__tests__/LocalIndexer.test.d.ts +5 -0
  4. package/dist/src/__tests__/LocalIndexer.test.d.ts.map +1 -0
  5. package/dist/src/__tests__/LocalIndexer.test.js +396 -0
  6. package/dist/src/__tests__/LocalIndexer.test.js.map +1 -0
  7. package/dist/src/__tests__/context.test.d.ts +10 -0
  8. package/dist/src/__tests__/context.test.d.ts.map +1 -0
  9. package/dist/src/__tests__/context.test.js +345 -0
  10. package/dist/src/__tests__/context.test.js.map +1 -0
  11. package/dist/src/__tests__/get-skill.test.d.ts +1 -0
  12. package/dist/src/__tests__/get-skill.test.d.ts.map +1 -1
  13. package/dist/src/__tests__/get-skill.test.js +279 -0
  14. package/dist/src/__tests__/get-skill.test.js.map +1 -1
  15. package/dist/src/__tests__/index-local.test.d.ts +5 -0
  16. package/dist/src/__tests__/index-local.test.d.ts.map +1 -0
  17. package/dist/src/__tests__/index-local.test.js +203 -0
  18. package/dist/src/__tests__/index-local.test.js.map +1 -0
  19. package/dist/src/__tests__/middleware/license.test.js +180 -78
  20. package/dist/src/__tests__/middleware/license.test.js.map +1 -1
  21. package/dist/src/__tests__/recommend.test.d.ts +7 -0
  22. package/dist/src/__tests__/recommend.test.d.ts.map +1 -0
  23. package/dist/src/__tests__/recommend.test.js +277 -0
  24. package/dist/src/__tests__/recommend.test.js.map +1 -0
  25. package/dist/src/__tests__/search.test.js +140 -1
  26. package/dist/src/__tests__/search.test.js.map +1 -1
  27. package/dist/src/__tests__/utils/validation.test.d.ts +7 -0
  28. package/dist/src/__tests__/utils/validation.test.d.ts.map +1 -0
  29. package/dist/src/__tests__/utils/validation.test.js +82 -0
  30. package/dist/src/__tests__/utils/validation.test.js.map +1 -0
  31. package/dist/src/context.d.ts +22 -0
  32. package/dist/src/context.d.ts.map +1 -1
  33. package/dist/src/context.js +63 -9
  34. package/dist/src/context.js.map +1 -1
  35. package/dist/src/index.js +15 -1
  36. package/dist/src/index.js.map +1 -1
  37. package/dist/src/indexer/FrontmatterParser.d.ts +30 -0
  38. package/dist/src/indexer/FrontmatterParser.d.ts.map +1 -0
  39. package/dist/src/indexer/FrontmatterParser.js +109 -0
  40. package/dist/src/indexer/FrontmatterParser.js.map +1 -0
  41. package/dist/src/indexer/LocalIndexer.d.ts +136 -0
  42. package/dist/src/indexer/LocalIndexer.d.ts.map +1 -0
  43. package/dist/src/indexer/LocalIndexer.js +271 -0
  44. package/dist/src/indexer/LocalIndexer.js.map +1 -0
  45. package/dist/src/indexer/index.d.ts +8 -0
  46. package/dist/src/indexer/index.d.ts.map +1 -0
  47. package/dist/src/indexer/index.js +8 -0
  48. package/dist/src/indexer/index.js.map +1 -0
  49. package/dist/src/llm/failover.d.ts +210 -0
  50. package/dist/src/llm/failover.d.ts.map +1 -0
  51. package/dist/src/llm/failover.js +329 -0
  52. package/dist/src/llm/failover.js.map +1 -0
  53. package/dist/src/middleware/errorFormatter.d.ts +27 -0
  54. package/dist/src/middleware/errorFormatter.d.ts.map +1 -1
  55. package/dist/src/middleware/errorFormatter.js +95 -0
  56. package/dist/src/middleware/errorFormatter.js.map +1 -1
  57. package/dist/src/middleware/index.d.ts +1 -1
  58. package/dist/src/middleware/index.d.ts.map +1 -1
  59. package/dist/src/middleware/index.js.map +1 -1
  60. package/dist/src/middleware/license.d.ts +5 -0
  61. package/dist/src/middleware/license.d.ts.map +1 -1
  62. package/dist/src/middleware/license.js +2 -1
  63. package/dist/src/middleware/license.js.map +1 -1
  64. package/dist/src/middleware/quota-helpers.d.ts +40 -0
  65. package/dist/src/middleware/quota-helpers.d.ts.map +1 -0
  66. package/dist/src/middleware/quota-helpers.js +90 -0
  67. package/dist/src/middleware/quota-helpers.js.map +1 -0
  68. package/dist/src/middleware/quota-types.d.ts +105 -0
  69. package/dist/src/middleware/quota-types.d.ts.map +1 -0
  70. package/dist/src/middleware/quota-types.js +4 -0
  71. package/dist/src/middleware/quota-types.js.map +1 -0
  72. package/dist/src/middleware/quota.d.ts +3 -97
  73. package/dist/src/middleware/quota.d.ts.map +1 -1
  74. package/dist/src/middleware/quota.js +2 -87
  75. package/dist/src/middleware/quota.js.map +1 -1
  76. package/dist/src/tools/LocalSkillSearch.d.ts +32 -0
  77. package/dist/src/tools/LocalSkillSearch.d.ts.map +1 -0
  78. package/dist/src/tools/LocalSkillSearch.js +74 -0
  79. package/dist/src/tools/LocalSkillSearch.js.map +1 -0
  80. package/dist/src/tools/compare.d.ts +3 -102
  81. package/dist/src/tools/compare.d.ts.map +1 -1
  82. package/dist/src/tools/compare.helpers.d.ts +36 -0
  83. package/dist/src/tools/compare.helpers.d.ts.map +1 -0
  84. package/dist/src/tools/compare.helpers.js +252 -0
  85. package/dist/src/tools/compare.helpers.js.map +1 -0
  86. package/dist/src/tools/compare.js +6 -288
  87. package/dist/src/tools/compare.js.map +1 -1
  88. package/dist/src/tools/compare.types.d.ts +134 -0
  89. package/dist/src/tools/compare.types.d.ts.map +1 -0
  90. package/dist/src/tools/compare.types.js +47 -0
  91. package/dist/src/tools/compare.types.js.map +1 -0
  92. package/dist/src/tools/get-skill.d.ts.map +1 -1
  93. package/dist/src/tools/get-skill.js +38 -2
  94. package/dist/src/tools/get-skill.js.map +1 -1
  95. package/dist/src/tools/index-local.d.ts +117 -0
  96. package/dist/src/tools/index-local.d.ts.map +1 -0
  97. package/dist/src/tools/index-local.js +126 -0
  98. package/dist/src/tools/index-local.js.map +1 -0
  99. package/dist/src/tools/index.d.ts +2 -0
  100. package/dist/src/tools/index.d.ts.map +1 -1
  101. package/dist/src/tools/index.js +2 -0
  102. package/dist/src/tools/index.js.map +1 -1
  103. package/dist/src/tools/install.conflict-helpers.d.ts +64 -0
  104. package/dist/src/tools/install.conflict-helpers.d.ts.map +1 -0
  105. package/dist/src/tools/install.conflict-helpers.js +165 -0
  106. package/dist/src/tools/install.conflict-helpers.js.map +1 -0
  107. package/dist/src/tools/install.conflict-helpers.test.d.ts +15 -0
  108. package/dist/src/tools/install.conflict-helpers.test.d.ts.map +1 -0
  109. package/dist/src/tools/install.conflict-helpers.test.js +243 -0
  110. package/dist/src/tools/install.conflict-helpers.test.js.map +1 -0
  111. package/dist/src/tools/install.conflict.d.ts +58 -0
  112. package/dist/src/tools/install.conflict.d.ts.map +1 -0
  113. package/dist/src/tools/install.conflict.js +160 -0
  114. package/dist/src/tools/install.conflict.js.map +1 -0
  115. package/dist/src/tools/install.conflict.test.d.ts +15 -0
  116. package/dist/src/tools/install.conflict.test.d.ts.map +1 -0
  117. package/dist/src/tools/install.conflict.test.js +354 -0
  118. package/dist/src/tools/install.conflict.test.js.map +1 -0
  119. package/dist/src/tools/install.d.ts +11 -60
  120. package/dist/src/tools/install.d.ts.map +1 -1
  121. package/dist/src/tools/install.helpers.d.ts +83 -0
  122. package/dist/src/tools/install.helpers.d.ts.map +1 -0
  123. package/dist/src/tools/install.helpers.js +333 -0
  124. package/dist/src/tools/install.helpers.js.map +1 -0
  125. package/dist/src/tools/install.js +199 -255
  126. package/dist/src/tools/install.js.map +1 -1
  127. package/dist/src/tools/install.types.d.ts +178 -0
  128. package/dist/src/tools/install.types.d.ts.map +1 -0
  129. package/dist/src/tools/install.types.js +105 -0
  130. package/dist/src/tools/install.types.js.map +1 -0
  131. package/dist/src/tools/merge.d.ts +53 -0
  132. package/dist/src/tools/merge.d.ts.map +1 -0
  133. package/dist/src/tools/merge.js +276 -0
  134. package/dist/src/tools/merge.js.map +1 -0
  135. package/dist/src/tools/merge.test.d.ts +11 -0
  136. package/dist/src/tools/merge.test.d.ts.map +1 -0
  137. package/dist/src/tools/merge.test.js +224 -0
  138. package/dist/src/tools/merge.test.js.map +1 -0
  139. package/dist/src/tools/recommend.d.ts +3 -148
  140. package/dist/src/tools/recommend.d.ts.map +1 -1
  141. package/dist/src/tools/recommend.helpers.d.ts +42 -0
  142. package/dist/src/tools/recommend.helpers.d.ts.map +1 -0
  143. package/dist/src/tools/recommend.helpers.js +155 -0
  144. package/dist/src/tools/recommend.helpers.js.map +1 -0
  145. package/dist/src/tools/recommend.js +216 -154
  146. package/dist/src/tools/recommend.js.map +1 -1
  147. package/dist/src/tools/recommend.types.d.ts +164 -0
  148. package/dist/src/tools/recommend.types.d.ts.map +1 -0
  149. package/dist/src/tools/recommend.types.js +87 -0
  150. package/dist/src/tools/recommend.types.js.map +1 -0
  151. package/dist/src/tools/search.d.ts +18 -4
  152. package/dist/src/tools/search.d.ts.map +1 -1
  153. package/dist/src/tools/search.js +91 -16
  154. package/dist/src/tools/search.js.map +1 -1
  155. package/dist/src/tools/validate.d.ts +3 -70
  156. package/dist/src/tools/validate.d.ts.map +1 -1
  157. package/dist/src/tools/validate.helpers.d.ts +22 -0
  158. package/dist/src/tools/validate.helpers.d.ts.map +1 -0
  159. package/dist/src/tools/validate.helpers.js +276 -0
  160. package/dist/src/tools/validate.helpers.js.map +1 -0
  161. package/dist/src/tools/validate.js +4 -337
  162. package/dist/src/tools/validate.js.map +1 -1
  163. package/dist/src/tools/validate.types.d.ts +96 -0
  164. package/dist/src/tools/validate.types.d.ts.map +1 -0
  165. package/dist/src/tools/validate.types.js +71 -0
  166. package/dist/src/tools/validate.types.js.map +1 -0
  167. package/dist/src/utils/validation.d.ts +6 -2
  168. package/dist/src/utils/validation.d.ts.map +1 -1
  169. package/dist/src/utils/validation.js +11 -2
  170. package/dist/src/utils/validation.js.map +1 -1
  171. package/dist/src/webhooks/index.d.ts +1 -0
  172. package/dist/src/webhooks/index.d.ts.map +1 -1
  173. package/dist/src/webhooks/index.js +2 -0
  174. package/dist/src/webhooks/index.js.map +1 -1
  175. package/dist/src/webhooks/stripe-webhook-endpoint.d.ts +68 -0
  176. package/dist/src/webhooks/stripe-webhook-endpoint.d.ts.map +1 -0
  177. package/dist/src/webhooks/stripe-webhook-endpoint.js +213 -0
  178. package/dist/src/webhooks/stripe-webhook-endpoint.js.map +1 -0
  179. package/dist/src/webhooks/webhook-endpoint.d.ts +4 -49
  180. package/dist/src/webhooks/webhook-endpoint.d.ts.map +1 -1
  181. package/dist/src/webhooks/webhook-endpoint.js +3 -125
  182. package/dist/src/webhooks/webhook-endpoint.js.map +1 -1
  183. package/dist/src/webhooks/webhook-helpers.d.ts +69 -0
  184. package/dist/src/webhooks/webhook-helpers.d.ts.map +1 -0
  185. package/dist/src/webhooks/webhook-helpers.js +146 -0
  186. package/dist/src/webhooks/webhook-helpers.js.map +1 -0
  187. package/dist/tests/e2e/conflict-resolution.e2e.test.d.ts +12 -0
  188. package/dist/tests/e2e/conflict-resolution.e2e.test.d.ts.map +1 -0
  189. package/dist/tests/e2e/conflict-resolution.e2e.test.js +343 -0
  190. package/dist/tests/e2e/conflict-resolution.e2e.test.js.map +1 -0
  191. package/dist/tests/integration/fixtures/development-skills.d.ts +22 -0
  192. package/dist/tests/integration/fixtures/development-skills.d.ts.map +1 -0
  193. package/dist/tests/integration/fixtures/development-skills.js +165 -0
  194. package/dist/tests/integration/fixtures/development-skills.js.map +1 -0
  195. package/dist/tests/integration/fixtures/devops-skills.d.ts +10 -0
  196. package/dist/tests/integration/fixtures/devops-skills.d.ts.map +1 -0
  197. package/dist/tests/integration/fixtures/devops-skills.js +70 -0
  198. package/dist/tests/integration/fixtures/devops-skills.js.map +1 -0
  199. package/dist/tests/integration/fixtures/experimental-skills.d.ts +14 -0
  200. package/dist/tests/integration/fixtures/experimental-skills.d.ts.map +1 -0
  201. package/dist/tests/integration/fixtures/experimental-skills.js +255 -0
  202. package/dist/tests/integration/fixtures/experimental-skills.js.map +1 -0
  203. package/dist/tests/integration/fixtures/skill-types.d.ts +18 -0
  204. package/dist/tests/integration/fixtures/skill-types.d.ts.map +1 -0
  205. package/dist/tests/integration/fixtures/skill-types.js +6 -0
  206. package/dist/tests/integration/fixtures/skill-types.js.map +1 -0
  207. package/dist/tests/integration/fixtures/test-skills.d.ts +10 -14
  208. package/dist/tests/integration/fixtures/test-skills.d.ts.map +1 -1
  209. package/dist/tests/integration/fixtures/test-skills.js +23 -590
  210. package/dist/tests/integration/fixtures/test-skills.js.map +1 -1
  211. package/dist/tests/integration/fixtures/testing-skills.d.ts +10 -0
  212. package/dist/tests/integration/fixtures/testing-skills.d.ts.map +1 -0
  213. package/dist/tests/integration/fixtures/testing-skills.js +70 -0
  214. package/dist/tests/integration/fixtures/testing-skills.js.map +1 -0
  215. package/dist/tests/integration/fixtures/verified-skills.d.ts +11 -0
  216. package/dist/tests/integration/fixtures/verified-skills.d.ts.map +1 -0
  217. package/dist/tests/integration/fixtures/verified-skills.js +91 -0
  218. package/dist/tests/integration/fixtures/verified-skills.js.map +1 -0
  219. package/dist/tests/integration/install-conflict.integration.test.d.ts +8 -0
  220. package/dist/tests/integration/install-conflict.integration.test.d.ts.map +1 -0
  221. package/dist/tests/integration/install-conflict.integration.test.js +384 -0
  222. package/dist/tests/integration/install-conflict.integration.test.js.map +1 -0
  223. package/dist/tests/integration/install-trust-parsing.integration.test.d.ts +13 -0
  224. package/dist/tests/integration/install-trust-parsing.integration.test.d.ts.map +1 -0
  225. package/dist/tests/integration/install-trust-parsing.integration.test.js +290 -0
  226. package/dist/tests/integration/install-trust-parsing.integration.test.js.map +1 -0
  227. package/dist/tests/integration/install.integration.test.js +151 -1
  228. package/dist/tests/integration/install.integration.test.js.map +1 -1
  229. package/dist/tests/integration/recommend.integration.test.js +2 -1
  230. package/dist/tests/integration/recommend.integration.test.js.map +1 -1
  231. package/dist/tests/llm/failover.test.d.ts +13 -0
  232. package/dist/tests/llm/failover.test.d.ts.map +1 -0
  233. package/dist/tests/llm/failover.test.js +250 -0
  234. package/dist/tests/llm/failover.test.js.map +1 -0
  235. package/dist/tests/recommend.test.js +133 -1
  236. package/dist/tests/recommend.test.js.map +1 -1
  237. package/dist/tests/tools.test.d.ts +1 -0
  238. package/dist/tests/tools.test.d.ts.map +1 -1
  239. package/dist/tests/tools.test.js +59 -1
  240. package/dist/tests/tools.test.js.map +1 -1
  241. package/dist/tests/unit/compare-helpers.test.d.ts +8 -0
  242. package/dist/tests/unit/compare-helpers.test.d.ts.map +1 -0
  243. package/dist/tests/unit/compare-helpers.test.js +224 -0
  244. package/dist/tests/unit/compare-helpers.test.js.map +1 -0
  245. package/dist/tests/unit/install-helpers.test.d.ts +8 -0
  246. package/dist/tests/unit/install-helpers.test.d.ts.map +1 -0
  247. package/dist/tests/unit/install-helpers.test.js +460 -0
  248. package/dist/tests/unit/install-helpers.test.js.map +1 -0
  249. package/dist/tests/unit/recommend-helpers.test.d.ts +8 -0
  250. package/dist/tests/unit/recommend-helpers.test.d.ts.map +1 -0
  251. package/dist/tests/unit/recommend-helpers.test.js +117 -0
  252. package/dist/tests/unit/recommend-helpers.test.js.map +1 -0
  253. package/dist/tests/unit/validate-helpers.test.d.ts +8 -0
  254. package/dist/tests/unit/validate-helpers.test.d.ts.map +1 -0
  255. package/dist/tests/unit/validate-helpers.test.js +243 -0
  256. package/dist/tests/unit/validate-helpers.test.js.map +1 -0
  257. package/package.json +7 -6
  258. package/src/assets/docs/USER_GUIDE.md +0 -220
  259. package/src/assets/skills/skillsmith/docs/QUOTAS.md +0 -182
  260. package/src/assets/skills/skillsmith/docs/SECURITY.md +0 -174
  261. package/src/assets/skills/skillsmith/docs/TRUST_TIERS.md +0 -142
@@ -0,0 +1,243 @@
1
+ /**
2
+ * @fileoverview Tests for validate.helpers.ts
3
+ * @module @skillsmith/mcp-server/tests/unit/validate-helpers
4
+ *
5
+ * SMI-1719: Unit tests for extracted helper functions from Wave 3 refactor
6
+ */
7
+ import { describe, it, expect } from 'vitest';
8
+ import { parseYamlFrontmatter, hasSsrfPattern, hasPathTraversal, validateMetadata, } from '../../src/tools/validate.helpers.js';
9
+ describe('validate.helpers', () => {
10
+ describe('parseYamlFrontmatter', () => {
11
+ it('parses simple key-value pairs', () => {
12
+ const content = `---
13
+ name: my-skill
14
+ description: A test skill
15
+ version: 1.0.0
16
+ ---
17
+ # Content`;
18
+ const result = parseYamlFrontmatter(content);
19
+ expect(result).toEqual({
20
+ name: 'my-skill',
21
+ description: 'A test skill',
22
+ version: '1.0.0',
23
+ });
24
+ });
25
+ it('parses quoted strings', () => {
26
+ const content = `---
27
+ name: "my-skill"
28
+ description: 'A test skill'
29
+ ---`;
30
+ const result = parseYamlFrontmatter(content);
31
+ expect(result?.name).toBe('my-skill');
32
+ expect(result?.description).toBe('A test skill');
33
+ });
34
+ it('parses boolean values', () => {
35
+ const content = `---
36
+ enabled: true
37
+ disabled: false
38
+ ---`;
39
+ const result = parseYamlFrontmatter(content);
40
+ expect(result?.enabled).toBe(true);
41
+ expect(result?.disabled).toBe(false);
42
+ });
43
+ it('parses numeric values', () => {
44
+ const content = `---
45
+ count: 42
46
+ score: 3.14
47
+ negative: -10
48
+ ---`;
49
+ const result = parseYamlFrontmatter(content);
50
+ expect(result?.count).toBe(42);
51
+ expect(result?.score).toBe(3.14);
52
+ expect(result?.negative).toBe(-10);
53
+ });
54
+ it('parses inline arrays', () => {
55
+ const content = `---
56
+ tags: [typescript, testing, cli]
57
+ ---`;
58
+ const result = parseYamlFrontmatter(content);
59
+ expect(result?.tags).toEqual(['typescript', 'testing', 'cli']);
60
+ });
61
+ it('parses multiline arrays', () => {
62
+ const content = `---
63
+ tags:
64
+ - typescript
65
+ - testing
66
+ - cli
67
+ ---`;
68
+ const result = parseYamlFrontmatter(content);
69
+ expect(result?.tags).toEqual(['typescript', 'testing', 'cli']);
70
+ });
71
+ it('ignores comments', () => {
72
+ const content = `---
73
+ # This is a comment
74
+ name: my-skill
75
+ # Another comment
76
+ description: Test
77
+ ---`;
78
+ const result = parseYamlFrontmatter(content);
79
+ expect(result).toEqual({
80
+ name: 'my-skill',
81
+ description: 'Test',
82
+ });
83
+ });
84
+ it('returns null for content without frontmatter', () => {
85
+ const content = '# Just markdown\n\nNo frontmatter here';
86
+ expect(parseYamlFrontmatter(content)).toBeNull();
87
+ });
88
+ it('returns null for truly unclosed frontmatter', () => {
89
+ // Note: The parser uses indexOf('---', 3) so any occurrence of --- will close it
90
+ // This test verifies truly unclosed frontmatter (no --- anywhere after the opening)
91
+ const content = `---
92
+ name: my-skill
93
+ description: Test
94
+ author: someone`;
95
+ expect(parseYamlFrontmatter(content)).toBeNull();
96
+ });
97
+ it('handles empty values', () => {
98
+ const content = `---
99
+ name: my-skill
100
+ tags:
101
+ ---`;
102
+ const result = parseYamlFrontmatter(content);
103
+ expect(result?.name).toBe('my-skill');
104
+ });
105
+ });
106
+ describe('hasSsrfPattern', () => {
107
+ it('detects file:// protocol', () => {
108
+ expect(hasSsrfPattern('file:///etc/passwd')).toBe(true);
109
+ });
110
+ it('detects gopher:// protocol', () => {
111
+ expect(hasSsrfPattern('gopher://localhost')).toBe(true);
112
+ });
113
+ it('detects localhost', () => {
114
+ expect(hasSsrfPattern('http://localhost/admin')).toBe(true);
115
+ });
116
+ it('detects 127.0.0.x', () => {
117
+ expect(hasSsrfPattern('http://127.0.0.1/admin')).toBe(true);
118
+ });
119
+ it('detects private IP 10.x.x.x', () => {
120
+ expect(hasSsrfPattern('http://10.0.0.1/internal')).toBe(true);
121
+ });
122
+ // SMI-1723: Additional private IP ranges
123
+ it('detects private IP 192.168.x.x', () => {
124
+ expect(hasSsrfPattern('http://192.168.1.1/admin')).toBe(true);
125
+ expect(hasSsrfPattern('http://192.168.0.100/config')).toBe(true);
126
+ });
127
+ it('detects cloud metadata service 169.254.x.x', () => {
128
+ // AWS/Azure/GCP metadata endpoints
129
+ expect(hasSsrfPattern('http://169.254.169.254/latest/meta-data/')).toBe(true);
130
+ expect(hasSsrfPattern('http://169.254.170.2/v2/credentials')).toBe(true);
131
+ });
132
+ it('allows safe URLs', () => {
133
+ expect(hasSsrfPattern('https://github.com/user/repo')).toBe(false);
134
+ expect(hasSsrfPattern('https://example.com')).toBe(false);
135
+ });
136
+ });
137
+ describe('hasPathTraversal', () => {
138
+ it('detects ../', () => {
139
+ expect(hasPathTraversal('../etc/passwd')).toBe(true);
140
+ });
141
+ it('detects encoded path traversal', () => {
142
+ expect(hasPathTraversal('%2e%2e/etc/passwd')).toBe(true);
143
+ });
144
+ it('detects windows-style traversal', () => {
145
+ expect(hasPathTraversal('..\\windows\\system32')).toBe(true);
146
+ });
147
+ it('allows safe paths', () => {
148
+ expect(hasPathTraversal('/home/user/file.txt')).toBe(false);
149
+ expect(hasPathTraversal('src/index.ts')).toBe(false);
150
+ });
151
+ });
152
+ describe('validateMetadata', () => {
153
+ it('validates valid metadata', () => {
154
+ const metadata = {
155
+ name: 'my-skill',
156
+ description: 'A test skill',
157
+ author: 'test-author',
158
+ version: '1.0.0',
159
+ tags: ['testing'],
160
+ };
161
+ const errors = validateMetadata(metadata, false);
162
+ expect(errors).toEqual([]);
163
+ });
164
+ it('requires name field', () => {
165
+ const metadata = { description: 'Test' };
166
+ const errors = validateMetadata(metadata, false);
167
+ expect(errors.some((e) => e.field === 'name' && e.severity === 'error')).toBe(true);
168
+ });
169
+ it('requires description in strict mode', () => {
170
+ const metadata = { name: 'my-skill' };
171
+ const strictErrors = validateMetadata(metadata, true);
172
+ const normalErrors = validateMetadata(metadata, false);
173
+ expect(strictErrors.some((e) => e.field === 'description' && e.severity === 'error')).toBe(true);
174
+ expect(normalErrors.some((e) => e.field === 'description' && e.severity === 'warning')).toBe(true);
175
+ });
176
+ it('validates name type', () => {
177
+ const metadata = { name: 123, description: 'Test' };
178
+ const errors = validateMetadata(metadata, false);
179
+ expect(errors.some((e) => e.field === 'name' && e.message.includes('must be a string'))).toBe(true);
180
+ });
181
+ it('validates name length', () => {
182
+ const metadata = { name: 'a'.repeat(100), description: 'Test' };
183
+ const errors = validateMetadata(metadata, false);
184
+ expect(errors.some((e) => e.field === 'name' && e.message.includes('exceeds maximum'))).toBe(true);
185
+ });
186
+ it('validates tags array', () => {
187
+ const metadata = { name: 'test', description: 'Test', tags: 'not-an-array' };
188
+ const errors = validateMetadata(metadata, false);
189
+ expect(errors.some((e) => e.field === 'tags' && e.message.includes('must be an array'))).toBe(true);
190
+ });
191
+ it('validates tag count', () => {
192
+ const metadata = {
193
+ name: 'test',
194
+ description: 'Test',
195
+ tags: Array(25).fill('tag'),
196
+ };
197
+ const errors = validateMetadata(metadata, false);
198
+ expect(errors.some((e) => e.field === 'tags' && e.message.includes('exceeds maximum count'))).toBe(true);
199
+ });
200
+ it('validates individual tag type', () => {
201
+ const metadata = { name: 'test', description: 'Test', tags: [123, 'valid'] };
202
+ const errors = validateMetadata(metadata, false);
203
+ expect(errors.some((e) => e.field === 'tags[0]' && e.message.includes('must be a string'))).toBe(true);
204
+ });
205
+ it('detects SSRF in repository URL', () => {
206
+ const metadata = {
207
+ name: 'test',
208
+ description: 'Test',
209
+ repository: 'http://localhost/admin',
210
+ };
211
+ const errors = validateMetadata(metadata, false);
212
+ expect(errors.some((e) => e.field === 'repository' && e.message.includes('dangerous URL'))).toBe(true);
213
+ });
214
+ it('detects SSRF in homepage URL', () => {
215
+ const metadata = {
216
+ name: 'test',
217
+ description: 'Test',
218
+ homepage: 'file:///etc/passwd',
219
+ };
220
+ const errors = validateMetadata(metadata, false);
221
+ expect(errors.some((e) => e.field === 'homepage' && e.message.includes('dangerous URL'))).toBe(true);
222
+ });
223
+ it('detects path traversal in any field', () => {
224
+ const metadata = {
225
+ name: 'test',
226
+ description: '../../../etc/passwd',
227
+ };
228
+ const errors = validateMetadata(metadata, false);
229
+ expect(errors.some((e) => e.field === 'description' && e.message.includes('path traversal'))).toBe(true);
230
+ });
231
+ it('recommends version in strict mode', () => {
232
+ const metadata = { name: 'test', description: 'Test' };
233
+ const errors = validateMetadata(metadata, true);
234
+ expect(errors.some((e) => e.field === 'version' && e.severity === 'warning')).toBe(true);
235
+ });
236
+ it('recommends tags in strict mode', () => {
237
+ const metadata = { name: 'test', description: 'Test' };
238
+ const errors = validateMetadata(metadata, true);
239
+ expect(errors.some((e) => e.field === 'tags' && e.message.includes('recommended'))).toBe(true);
240
+ });
241
+ });
242
+ });
243
+ //# sourceMappingURL=validate-helpers.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-helpers.test.js","sourceRoot":"","sources":["../../../tests/unit/validate-helpers.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skillsmith/mcp-server",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "description": "MCP server for Skillsmith skill discovery",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -9,21 +9,22 @@
9
9
  "skillsmith-mcp": "./dist/src/index.js"
10
10
  },
11
11
  "scripts": {
12
- "prepublishOnly": "npm run build && npm run test",
12
+ "prepublishOnly": "npm run build && npm run test && chmod +x dist/src/index.js",
13
13
  "build": "tsc",
14
+ "postbuild": "chmod +x dist/src/index.js || true",
14
15
  "dev": "tsx watch src/index.ts",
15
- "start": "node dist/index.js",
16
+ "start": "node dist/src/index.js",
16
17
  "test": "vitest run",
17
18
  "test:watch": "vitest",
18
19
  "test:integration": "vitest run --config vitest.config.integration.ts"
19
20
  },
20
21
  "dependencies": {
21
- "@modelcontextprotocol/sdk": "^1.0.4",
22
- "@skillsmith/core": "*",
22
+ "@modelcontextprotocol/sdk": "1.25.3",
23
+ "@skillsmith/core": "0.4.1",
23
24
  "esbuild": "0.27.2"
24
25
  },
25
26
  "devDependencies": {
26
- "tsx": "^4.6.0",
27
+ "tsx": "4.21.0",
27
28
  "vitest": "4.0.16",
28
29
  "zod": "^3.25.0"
29
30
  },
@@ -1,220 +0,0 @@
1
- # Skillsmith User Guide
2
-
3
- Welcome to Skillsmith, the skill discovery and management system for Claude Code.
4
-
5
- ## Quick Start
6
-
7
- ### 1. Configure MCP Server
8
-
9
- Add to `~/.claude/settings.json`:
10
-
11
- ```json
12
- {
13
- "mcpServers": {
14
- "skillsmith": {
15
- "command": "npx",
16
- "args": ["-y", "@skillsmith/mcp-server"]
17
- }
18
- }
19
- }
20
- ```
21
-
22
- ### 2. Restart Claude Code
23
-
24
- Close and reopen your Claude Code session.
25
-
26
- ### 3. Start Using
27
-
28
- Ask Claude:
29
- - "Search for testing skills"
30
- - "Install the commit skill"
31
- - "What skills do I have installed?"
32
-
33
- ## What Gets Installed
34
-
35
- On first run, Skillsmith automatically installs essential skills:
36
-
37
- | Skill | Purpose |
38
- |-------|---------|
39
- | **varlock** | Secure environment variable management |
40
- | **commit** | Git commit message generation |
41
- | **governance** | Code quality enforcement |
42
- | **skill-builder** | Create custom skills |
43
- | **skillsmith** | This documentation |
44
-
45
- ## Trust Tiers
46
-
47
- Always check the trust tier before installing skills:
48
-
49
- | Tier | Safety | Action |
50
- |------|--------|--------|
51
- | **Official** (Green) | Highest | Install freely |
52
- | **Verified** (Blue) | High | Install freely |
53
- | **Community** (Yellow) | Medium | Review first |
54
- | **Unverified** (Red) | Unknown | Careful review |
55
-
56
- ### Quick Trust Check
57
-
58
- ```
59
- "Show details for community/some-skill"
60
- ```
61
-
62
- Look for:
63
- - Trust tier badge
64
- - Quality score (aim for 70+)
65
- - Number of stars
66
- - Days since published
67
-
68
- ## Common Tasks
69
-
70
- ### Search for Skills
71
-
72
- ```
73
- "Find testing skills"
74
- "Search for devops skills with score above 80"
75
- "Find verified git workflow skills"
76
- ```
77
-
78
- ### Install a Skill
79
-
80
- ```
81
- "Install community/jest-helper"
82
- "Install the commit skill"
83
- ```
84
-
85
- ### Compare Skills
86
-
87
- ```
88
- "Compare jest-helper and vitest-helper"
89
- ```
90
-
91
- ### Get Recommendations
92
-
93
- ```
94
- "Recommend skills for my React project"
95
- "What skills would help with this codebase?"
96
- ```
97
-
98
- ### Create a Custom Skill
99
-
100
- ```
101
- "Create a skill for generating changelogs"
102
- ```
103
-
104
- ## Quota Limits
105
-
106
- | Tier | API Calls/Month | Price |
107
- |------|-----------------|-------|
108
- | Community | 1,000 | Free |
109
- | Individual | 10,000 | $9.99/mo |
110
- | Team | 100,000 | $25/user/mo |
111
- | Enterprise | Unlimited | $55/user/mo |
112
-
113
- Check your usage:
114
- ```
115
- "What's my Skillsmith quota?"
116
- ```
117
-
118
- Upgrade at: https://skillsmith.app/upgrade
119
-
120
- ## Security Best Practices
121
-
122
- 1. **Prefer Verified or Official skills** for important projects
123
- 2. **Review Community skills** before installing
124
- 3. **Never install Unverified skills** without manual review
125
- 4. **Check the quality score** - aim for 70+
126
- 5. **Report suspicious skills** to security@skillsmith.app
127
-
128
- ## Data Sources
129
-
130
- Skillsmith uses different data sources depending on context:
131
-
132
- | Context | Data Source | Description |
133
- |---------|-------------|-------------|
134
- | **Production** | Supabase Registry | Live database with indexed skills from GitHub |
135
- | **Development** | Local SQLite + Seed Data | Sample skills for testing |
136
-
137
- ### Live Registry (Production)
138
-
139
- When you install `@skillsmith/mcp-server` via npx, it connects to the **live Supabase registry**. This registry is populated by:
140
-
141
- 1. **GitHub Indexer** - Automatically discovers skills with topics like `claude-code-skill`
142
- 2. **High-Trust Authors** - Pre-indexed skills from verified publishers (Anthropic, Hugging Face, Vercel)
143
- 3. **Community Submissions** - Skills submitted via the registry API
144
-
145
- ### Seed Data (Development Only)
146
-
147
- The seed data in `packages/core/tests/fixtures/skills/seed-skills.json` is **only for local development and testing**. It is NOT the production registry.
148
-
149
- ```bash
150
- # Development only - loads sample skills to local SQLite
151
- npm run seed
152
- ```
153
-
154
- > **Note**: If you're using Skillsmith normally (via npx), you don't need seed data. The MCP server connects directly to the live registry.
155
-
156
- ## Where Skills Are Installed
157
-
158
- Skills install to: `~/.claude/skills/<skill-name>/`
159
-
160
- Each skill contains:
161
- - `SKILL.md` - Main skill file (Claude reads this)
162
- - Optional: `docs/`, `scripts/`, `templates/`
163
-
164
- ## Troubleshooting
165
-
166
- ### "Skill not found"
167
-
168
- The skill may not exist in the registry. Try:
169
- ```
170
- "Search for similar-name"
171
- ```
172
-
173
- ### "Installation failed"
174
-
175
- Check:
176
- 1. Internet connection
177
- 2. Quota remaining
178
- 3. Skill hasn't been blocklisted
179
-
180
- ### "Security scan failed"
181
-
182
- The skill was blocked for security reasons. Try a different skill or contact support if you believe this is an error.
183
-
184
- ### Quota Exceeded
185
-
186
- You've hit your monthly limit. Options:
187
- 1. Wait until quota resets (1st of month)
188
- 2. Upgrade your tier
189
-
190
- ## Offline Usage
191
-
192
- Installed skills work offline. Only these operations require internet:
193
- - Searching for new skills
194
- - Installing skills
195
- - Getting recommendations
196
-
197
- ## Updating Skillsmith
198
-
199
- ```bash
200
- npx @skillsmith/mcp-server@latest
201
- ```
202
-
203
- Or let it auto-update via npx.
204
-
205
- ## Getting Help
206
-
207
- - **Documentation**: `npx @skillsmith/mcp-server --docs`
208
- - **Issues**: https://github.com/smith-horn/skillsmith/issues
209
- - **Support**: support@skillsmith.app
210
- - **Security**: security@skillsmith.app
211
-
212
- ## License
213
-
214
- Skillsmith is licensed under **Elastic License 2.0**:
215
- - Self-hosting for internal use: Allowed
216
- - Modification for own use: Allowed
217
- - Offering as managed service: Not allowed
218
- - Circumventing license keys: Not allowed
219
-
220
- Full license: https://www.elastic.co/licensing/elastic-license