@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,281 @@
1
+ /**
2
+ * SMI-883: Tests for logger sensitive data redaction
3
+ * Ensures API keys, tokens, passwords, and secrets are never written to disk
4
+ */
5
+ import { describe, it, expect } from 'vitest';
6
+ import { redactSensitiveData, redactSensitiveObject } from '../../src/logger.js';
7
+ describe('SMI-883: Logger Sensitive Data Redaction', () => {
8
+ describe('redactSensitiveData', () => {
9
+ describe('GitHub tokens', () => {
10
+ it('should redact classic personal access tokens (ghp_)', () => {
11
+ const input = 'Token: ghp_1234567890abcdefghijklmnopqrstuvwxyz';
12
+ const result = redactSensitiveData(input);
13
+ expect(result).toBe('Token: ghp_[REDACTED]');
14
+ expect(result).not.toContain('1234567890');
15
+ });
16
+ it('should redact fine-grained personal access tokens (github_pat_)', () => {
17
+ const input = 'Using github_pat_abcdefghijklmnopqrstuvwx12345';
18
+ const result = redactSensitiveData(input);
19
+ expect(result).toBe('Using github_pat_[REDACTED]');
20
+ });
21
+ it('should redact OAuth tokens (gho_)', () => {
22
+ const input = 'OAuth: gho_1234567890abcdefghijklmnopqrstuvwxyz';
23
+ const result = redactSensitiveData(input);
24
+ expect(result).toBe('OAuth: gho_[REDACTED]');
25
+ });
26
+ it('should redact server-to-server tokens (ghs_)', () => {
27
+ const input = 'Server: ghs_1234567890abcdefghijklmnopqrstuvwxyz';
28
+ const result = redactSensitiveData(input);
29
+ expect(result).toBe('Server: ghs_[REDACTED]');
30
+ });
31
+ it('should redact user-to-server tokens (ghu_)', () => {
32
+ const input = 'User: ghu_1234567890abcdefghijklmnopqrstuvwxyz';
33
+ const result = redactSensitiveData(input);
34
+ expect(result).toBe('User: ghu_[REDACTED]');
35
+ });
36
+ it('should redact refresh tokens (ghr_)', () => {
37
+ const input = 'Refresh: ghr_1234567890abcdefghijklmnopqrstuvwxyz';
38
+ const result = redactSensitiveData(input);
39
+ expect(result).toBe('Refresh: ghr_[REDACTED]');
40
+ });
41
+ });
42
+ describe('Linear API keys', () => {
43
+ it('should redact Linear API keys (lin_api_)', () => {
44
+ const input = 'LINEAR_API_KEY=lin_api_abcdefghijklmnopqrstuvwxyz123456';
45
+ const result = redactSensitiveData(input);
46
+ expect(result).toContain('lin_api_[REDACTED]');
47
+ expect(result).not.toContain('abcdefghij');
48
+ });
49
+ });
50
+ describe('Stripe keys', () => {
51
+ it('should redact live secret keys (sk_live_)', () => {
52
+ const input = 'STRIPE_KEY=sk_live_abcdefghijklmnopqrstuvwx';
53
+ const result = redactSensitiveData(input);
54
+ expect(result).toContain('sk_live_[REDACTED]');
55
+ });
56
+ it('should redact test secret keys (sk_test_)', () => {
57
+ const input = 'STRIPE_KEY=sk_test_abcdefghijklmnopqrstuvwx';
58
+ const result = redactSensitiveData(input);
59
+ expect(result).toContain('sk_test_[REDACTED]');
60
+ });
61
+ it('should redact live publishable keys (pk_live_)', () => {
62
+ const input = 'STRIPE_PK=pk_live_abcdefghijklmnopqrstuvwx';
63
+ const result = redactSensitiveData(input);
64
+ expect(result).toContain('pk_live_[REDACTED]');
65
+ });
66
+ it('should redact test publishable keys (pk_test_)', () => {
67
+ const input = 'STRIPE_PK=pk_test_abcdefghijklmnopqrstuvwx';
68
+ const result = redactSensitiveData(input);
69
+ expect(result).toContain('pk_test_[REDACTED]');
70
+ });
71
+ });
72
+ describe('OpenAI API keys', () => {
73
+ it('should redact OpenAI API keys (sk-)', () => {
74
+ const input = 'OPENAI_API_KEY=sk-abcdefghijklmnopqrstuvwxyz1234567890abcdefghijkl';
75
+ const result = redactSensitiveData(input);
76
+ expect(result).toContain('sk-[REDACTED]');
77
+ expect(result).not.toContain('abcdefghij');
78
+ });
79
+ });
80
+ describe('Anthropic API keys', () => {
81
+ it('should redact Anthropic API keys (sk-ant-)', () => {
82
+ const input = 'ANTHROPIC_API_KEY=sk-ant-api03-abcdefghijklmnopqrstuvwxyz12';
83
+ const result = redactSensitiveData(input);
84
+ expect(result).toContain('sk-ant-[REDACTED]');
85
+ });
86
+ });
87
+ describe('AWS keys', () => {
88
+ it('should redact AWS access key IDs (AKIA)', () => {
89
+ const input = 'AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE';
90
+ const result = redactSensitiveData(input);
91
+ expect(result).toContain('AKIA[REDACTED]');
92
+ expect(result).not.toContain('IOSFODNN7EXAMPLE');
93
+ });
94
+ });
95
+ describe('Slack tokens', () => {
96
+ it('should redact bot tokens (xoxb-)', () => {
97
+ const input = 'SLACK_TOKEN=xoxb-123456789012-1234567890123-abcdefghijklmnop';
98
+ const result = redactSensitiveData(input);
99
+ expect(result).toContain('xox*-[REDACTED]');
100
+ });
101
+ it('should redact user tokens (xoxp-)', () => {
102
+ const input = 'SLACK_TOKEN=xoxp-123456789012-1234567890123-abcdefghijklmnop';
103
+ const result = redactSensitiveData(input);
104
+ expect(result).toContain('xox*-[REDACTED]');
105
+ });
106
+ });
107
+ describe('npm tokens', () => {
108
+ it('should redact npm tokens (npm_)', () => {
109
+ const input = 'NPM_TOKEN=npm_abcdefghijklmnopqrstuvwxyz1234567890';
110
+ const result = redactSensitiveData(input);
111
+ expect(result).toContain('npm_[REDACTED]');
112
+ });
113
+ });
114
+ describe('Bearer and Basic auth', () => {
115
+ it('should redact Bearer tokens', () => {
116
+ const input = 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9';
117
+ const result = redactSensitiveData(input);
118
+ expect(result).toContain('Bearer [REDACTED]');
119
+ });
120
+ it('should redact Basic auth credentials', () => {
121
+ const input = 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQxMjM0NTY=';
122
+ const result = redactSensitiveData(input);
123
+ expect(result).toContain('Basic [REDACTED]');
124
+ });
125
+ });
126
+ describe('JWT tokens', () => {
127
+ it('should redact JWT tokens', () => {
128
+ const input = 'Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
129
+ const result = redactSensitiveData(input);
130
+ expect(result).toContain('[JWT_REDACTED]');
131
+ expect(result).not.toContain('eyJzdWI');
132
+ });
133
+ });
134
+ describe('Generic patterns', () => {
135
+ it('should redact api_key assignments', () => {
136
+ const input = 'config.api_key = "my_secret_api_key_12345"';
137
+ const result = redactSensitiveData(input);
138
+ expect(result).toContain('api_key=[REDACTED]');
139
+ });
140
+ it('should redact password assignments', () => {
141
+ const input = 'password: "supersecret123"';
142
+ const result = redactSensitiveData(input);
143
+ expect(result).toContain('password=[REDACTED]');
144
+ });
145
+ it('should redact secret assignments', () => {
146
+ const input = 'client_secret = "abcdefghijklmnop"';
147
+ const result = redactSensitiveData(input);
148
+ expect(result).toContain('secret=[REDACTED]');
149
+ });
150
+ it('should redact token assignments', () => {
151
+ const input = 'auth_token: "my_auth_token_value"';
152
+ const result = redactSensitiveData(input);
153
+ expect(result).toContain('token=[REDACTED]');
154
+ });
155
+ });
156
+ describe('Connection strings', () => {
157
+ it('should redact passwords in connection strings', () => {
158
+ const input = 'postgresql://user:mysecretpassword@localhost:5432/db';
159
+ const result = redactSensitiveData(input);
160
+ expect(result).toBe('postgresql://user:[REDACTED]@localhost:5432/db');
161
+ expect(result).not.toContain('mysecretpassword');
162
+ });
163
+ it('should redact passwords in MongoDB connection strings', () => {
164
+ const input = 'mongodb://admin:p4ssw0rd123@cluster.mongodb.net/mydb';
165
+ const result = redactSensitiveData(input);
166
+ expect(result).toContain('[REDACTED]@cluster');
167
+ expect(result).not.toContain('p4ssw0rd123');
168
+ });
169
+ });
170
+ describe('Private keys', () => {
171
+ it('should redact RSA private keys', () => {
172
+ const input = `-----BEGIN RSA PRIVATE KEY-----
173
+ MIIEpAIBAAKCAQEA0Z3VS5JJcds3xfn/ygWyF8PbnGy
174
+ -----END RSA PRIVATE KEY-----`;
175
+ const result = redactSensitiveData(input);
176
+ expect(result).toBe('-----[PRIVATE KEY REDACTED]-----');
177
+ expect(result).not.toContain('MIIEpAIBAAKCAQEA');
178
+ });
179
+ it('should redact generic private keys', () => {
180
+ const input = `-----BEGIN PRIVATE KEY-----
181
+ MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEA
182
+ -----END PRIVATE KEY-----`;
183
+ const result = redactSensitiveData(input);
184
+ expect(result).toBe('-----[PRIVATE KEY REDACTED]-----');
185
+ });
186
+ });
187
+ describe('Edge cases', () => {
188
+ it('should handle empty strings', () => {
189
+ expect(redactSensitiveData('')).toBe('');
190
+ });
191
+ it('should handle null-ish values', () => {
192
+ expect(redactSensitiveData(null)).toBe(null);
193
+ expect(redactSensitiveData(undefined)).toBe(undefined);
194
+ });
195
+ it('should handle text with no sensitive data', () => {
196
+ const input = 'This is a normal log message with no secrets';
197
+ expect(redactSensitiveData(input)).toBe(input);
198
+ });
199
+ it('should handle multiple tokens in same string', () => {
200
+ const input = 'GitHub: ghp_1234567890abcdefghijklmnopqrstuvwxyz, Stripe: sk_live_abcdefghijklmnopqrstuvwx';
201
+ const result = redactSensitiveData(input);
202
+ expect(result).toContain('ghp_[REDACTED]');
203
+ expect(result).toContain('sk_live_[REDACTED]');
204
+ });
205
+ it('should handle repeated calls (regex lastIndex reset)', () => {
206
+ const input = 'Token: ghp_1234567890abcdefghijklmnopqrstuvwxyz';
207
+ // Call multiple times to verify lastIndex is reset
208
+ const result1 = redactSensitiveData(input);
209
+ const result2 = redactSensitiveData(input);
210
+ const result3 = redactSensitiveData(input);
211
+ expect(result1).toBe('Token: ghp_[REDACTED]');
212
+ expect(result2).toBe('Token: ghp_[REDACTED]');
213
+ expect(result3).toBe('Token: ghp_[REDACTED]');
214
+ });
215
+ });
216
+ });
217
+ describe('redactSensitiveObject', () => {
218
+ it('should redact strings in simple objects', () => {
219
+ const input = {
220
+ token: 'ghp_1234567890abcdefghijklmnopqrstuvwxyz',
221
+ name: 'test',
222
+ };
223
+ const result = redactSensitiveObject(input);
224
+ expect(result.token).toBe('ghp_[REDACTED]');
225
+ expect(result.name).toBe('test');
226
+ });
227
+ it('should redact strings in nested objects', () => {
228
+ const input = {
229
+ config: {
230
+ auth: {
231
+ apiKey: 'sk_live_abcdefghijklmnopqrstuvwx',
232
+ },
233
+ },
234
+ };
235
+ const result = redactSensitiveObject(input);
236
+ expect(result.config.auth).toEqual({
237
+ apiKey: 'sk_live_[REDACTED]',
238
+ });
239
+ });
240
+ it('should redact strings in arrays', () => {
241
+ const input = ['ghp_1234567890abcdefghijklmnopqrstuvwxyz', 'normal string'];
242
+ const result = redactSensitiveObject(input);
243
+ expect(result[0]).toBe('ghp_[REDACTED]');
244
+ expect(result[1]).toBe('normal string');
245
+ });
246
+ it('should handle mixed arrays and objects', () => {
247
+ const input = {
248
+ tokens: [
249
+ { key: 'ghp_1234567890abcdefghijklmnopqrstuvwxyz' },
250
+ { key: 'sk_live_abcdefghijklmnopqrstuvwx' },
251
+ ],
252
+ };
253
+ const result = redactSensitiveObject(input);
254
+ const tokens = result.tokens;
255
+ expect(tokens[0].key).toBe('ghp_[REDACTED]');
256
+ expect(tokens[1].key).toBe('sk_live_[REDACTED]');
257
+ });
258
+ it('should handle null and undefined', () => {
259
+ expect(redactSensitiveObject(null)).toBe(null);
260
+ expect(redactSensitiveObject(undefined)).toBe(undefined);
261
+ });
262
+ it('should preserve non-string primitives', () => {
263
+ const input = {
264
+ count: 42,
265
+ enabled: true,
266
+ ratio: 3.14,
267
+ };
268
+ const result = redactSensitiveObject(input);
269
+ expect(result).toEqual(input);
270
+ });
271
+ it('should handle Error objects by converting to plain object', () => {
272
+ const input = {
273
+ error: new Error('Failed with token ghp_1234567890abcdefghijklmnopqrstuvwxyz'),
274
+ };
275
+ const result = redactSensitiveObject(input);
276
+ // Error.message won't be in entries, but if serialized it would be redacted
277
+ expect(result.error).toBeDefined();
278
+ });
279
+ });
280
+ });
281
+ //# sourceMappingURL=logger.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.test.js","sourceRoot":"","sources":["../../../tests/unit/logger.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for SMI-742: MCP Skill Validate Tool
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=validate.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.test.d.ts","sourceRoot":"","sources":["../../tests/validate.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,303 @@
1
+ /**
2
+ * Tests for SMI-742: MCP Skill Validate Tool
3
+ */
4
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
5
+ import { promises as fs } from 'fs';
6
+ import { join } from 'path';
7
+ import { tmpdir } from 'os';
8
+ import { executeValidate, formatValidationResults, validateInputSchema, } from '../src/tools/validate.js';
9
+ import { SkillsmithError, ErrorCodes } from '@skillsmith/core';
10
+ describe('Skill Validate Tool', () => {
11
+ let testDir;
12
+ beforeEach(async () => {
13
+ // Create a temporary directory for test files
14
+ testDir = await fs.mkdtemp(join(tmpdir(), 'skillsmith-validate-test-'));
15
+ });
16
+ afterEach(async () => {
17
+ // Clean up test directory
18
+ await fs.rm(testDir, { recursive: true, force: true });
19
+ });
20
+ describe('validateInputSchema', () => {
21
+ it('should require skill_path', () => {
22
+ expect(() => validateInputSchema.parse({})).toThrow();
23
+ expect(() => validateInputSchema.parse({ skill_path: '' })).toThrow();
24
+ });
25
+ it('should accept valid skill_path', () => {
26
+ const result = validateInputSchema.parse({
27
+ skill_path: '/path/to/SKILL.md',
28
+ });
29
+ expect(result.skill_path).toBe('/path/to/SKILL.md');
30
+ expect(result.strict).toBe(false); // default
31
+ });
32
+ it('should accept strict mode', () => {
33
+ const result = validateInputSchema.parse({
34
+ skill_path: '/path/to/skill',
35
+ strict: true,
36
+ });
37
+ expect(result.strict).toBe(true);
38
+ });
39
+ it('should default strict to false', () => {
40
+ const result = validateInputSchema.parse({
41
+ skill_path: '/path/to/skill',
42
+ });
43
+ expect(result.strict).toBe(false);
44
+ });
45
+ });
46
+ describe('executeValidate', () => {
47
+ it('should validate a valid SKILL.md file', async () => {
48
+ const skillContent = `---
49
+ name: test-skill
50
+ description: A test skill for validation
51
+ author: test-author
52
+ version: 1.0.0
53
+ tags:
54
+ - testing
55
+ - validation
56
+ ---
57
+
58
+ # Test Skill
59
+
60
+ This is a test skill.
61
+ `;
62
+ const filePath = join(testDir, 'SKILL.md');
63
+ await fs.writeFile(filePath, skillContent);
64
+ const result = await executeValidate({ skill_path: filePath });
65
+ expect(result.valid).toBe(true);
66
+ expect(result.errors.filter((e) => e.severity === 'error')).toHaveLength(0);
67
+ expect(result.metadata).toBeDefined();
68
+ expect(result.metadata?.name).toBe('test-skill');
69
+ expect(result.metadata?.description).toBe('A test skill for validation');
70
+ expect(result.timing.totalMs).toBeGreaterThanOrEqual(0);
71
+ });
72
+ it('should find SKILL.md in directory', async () => {
73
+ const skillContent = `---
74
+ name: dir-skill
75
+ description: Skill in directory
76
+ ---
77
+ `;
78
+ await fs.writeFile(join(testDir, 'SKILL.md'), skillContent);
79
+ const result = await executeValidate({ skill_path: testDir });
80
+ expect(result.valid).toBe(true);
81
+ expect(result.path).toBe(join(testDir, 'SKILL.md'));
82
+ expect(result.metadata?.name).toBe('dir-skill');
83
+ });
84
+ it('should return error for missing name field', async () => {
85
+ const skillContent = `---
86
+ description: A skill without a name
87
+ ---
88
+ `;
89
+ const filePath = join(testDir, 'SKILL.md');
90
+ await fs.writeFile(filePath, skillContent);
91
+ const result = await executeValidate({ skill_path: filePath });
92
+ expect(result.valid).toBe(false);
93
+ expect(result.errors.some((e) => e.field === 'name' && e.severity === 'error')).toBe(true);
94
+ });
95
+ it('should warn for missing description in non-strict mode', async () => {
96
+ const skillContent = `---
97
+ name: no-description-skill
98
+ ---
99
+ `;
100
+ const filePath = join(testDir, 'SKILL.md');
101
+ await fs.writeFile(filePath, skillContent);
102
+ const result = await executeValidate({ skill_path: filePath, strict: false });
103
+ expect(result.valid).toBe(true); // Still valid in non-strict mode
104
+ expect(result.errors.some((e) => e.field === 'description' && e.severity === 'warning')).toBe(true);
105
+ });
106
+ it('should error for missing description in strict mode', async () => {
107
+ const skillContent = `---
108
+ name: no-description-skill
109
+ ---
110
+ `;
111
+ const filePath = join(testDir, 'SKILL.md');
112
+ await fs.writeFile(filePath, skillContent);
113
+ const result = await executeValidate({ skill_path: filePath, strict: true });
114
+ expect(result.valid).toBe(false);
115
+ expect(result.errors.some((e) => e.field === 'description' && e.severity === 'error')).toBe(true);
116
+ });
117
+ it('should error for name exceeding 64 characters', async () => {
118
+ const longName = 'a'.repeat(65);
119
+ const skillContent = `---
120
+ name: ${longName}
121
+ description: A skill with a very long name
122
+ ---
123
+ `;
124
+ const filePath = join(testDir, 'SKILL.md');
125
+ await fs.writeFile(filePath, skillContent);
126
+ const result = await executeValidate({ skill_path: filePath });
127
+ expect(result.valid).toBe(false);
128
+ expect(result.errors.some((e) => e.field === 'name' && e.message.includes('exceeds maximum length'))).toBe(true);
129
+ });
130
+ it('should error for description exceeding 1024 characters', async () => {
131
+ const longDesc = 'a'.repeat(1025);
132
+ const skillContent = `---
133
+ name: long-desc-skill
134
+ description: ${longDesc}
135
+ ---
136
+ `;
137
+ const filePath = join(testDir, 'SKILL.md');
138
+ await fs.writeFile(filePath, skillContent);
139
+ const result = await executeValidate({ skill_path: filePath });
140
+ expect(result.valid).toBe(false);
141
+ expect(result.errors.some((e) => e.field === 'description' && e.message.includes('exceeds maximum length'))).toBe(true);
142
+ });
143
+ it('should detect SSRF pattern in repository URL', async () => {
144
+ const skillContent = `---
145
+ name: ssrf-skill
146
+ description: A skill with dangerous URL
147
+ repository: file:///etc/passwd
148
+ ---
149
+ `;
150
+ const filePath = join(testDir, 'SKILL.md');
151
+ await fs.writeFile(filePath, skillContent);
152
+ const result = await executeValidate({ skill_path: filePath });
153
+ expect(result.valid).toBe(false);
154
+ expect(result.errors.some((e) => e.field === 'repository' && e.message.includes('dangerous URL pattern'))).toBe(true);
155
+ });
156
+ it('should detect localhost in repository URL', async () => {
157
+ const skillContent = `---
158
+ name: localhost-skill
159
+ description: A skill with localhost URL
160
+ repository: http://localhost:8080/repo
161
+ ---
162
+ `;
163
+ const filePath = join(testDir, 'SKILL.md');
164
+ await fs.writeFile(filePath, skillContent);
165
+ const result = await executeValidate({ skill_path: filePath });
166
+ expect(result.valid).toBe(false);
167
+ expect(result.errors.some((e) => e.field === 'repository' && e.message.includes('dangerous URL pattern'))).toBe(true);
168
+ });
169
+ it('should detect path traversal in values', async () => {
170
+ const skillContent = `---
171
+ name: traversal-skill
172
+ description: ../../../etc/passwd
173
+ ---
174
+ `;
175
+ const filePath = join(testDir, 'SKILL.md');
176
+ await fs.writeFile(filePath, skillContent);
177
+ const result = await executeValidate({ skill_path: filePath });
178
+ expect(result.valid).toBe(false);
179
+ expect(result.errors.some((e) => e.message.includes('path traversal'))).toBe(true);
180
+ });
181
+ it('should error for invalid frontmatter', async () => {
182
+ const skillContent = `# No Frontmatter Skill
183
+
184
+ This skill has no YAML frontmatter.
185
+ `;
186
+ const filePath = join(testDir, 'SKILL.md');
187
+ await fs.writeFile(filePath, skillContent);
188
+ const result = await executeValidate({ skill_path: filePath });
189
+ expect(result.valid).toBe(false);
190
+ expect(result.errors.some((e) => e.field === 'frontmatter')).toBe(true);
191
+ });
192
+ it('should throw for non-existent path', async () => {
193
+ const fakePath = join(testDir, 'nonexistent', 'SKILL.md');
194
+ try {
195
+ await executeValidate({ skill_path: fakePath });
196
+ expect.fail('Should have thrown an error');
197
+ }
198
+ catch (error) {
199
+ expect(error).toBeInstanceOf(SkillsmithError);
200
+ expect(error.code).toBe(ErrorCodes.SKILL_NOT_FOUND);
201
+ }
202
+ });
203
+ it('should throw for path traversal in input path', async () => {
204
+ try {
205
+ await executeValidate({ skill_path: '../../../etc/passwd' });
206
+ expect.fail('Should have thrown an error');
207
+ }
208
+ catch (error) {
209
+ expect(error).toBeInstanceOf(SkillsmithError);
210
+ expect(error.code).toBe(ErrorCodes.VALIDATION_INVALID_TYPE);
211
+ }
212
+ });
213
+ it('should validate tags array correctly', async () => {
214
+ const skillContent = `---
215
+ name: tags-skill
216
+ description: A skill with invalid tags
217
+ tags: not-an-array
218
+ ---
219
+ `;
220
+ const filePath = join(testDir, 'SKILL.md');
221
+ await fs.writeFile(filePath, skillContent);
222
+ const result = await executeValidate({ skill_path: filePath });
223
+ expect(result.valid).toBe(false);
224
+ expect(result.errors.some((e) => e.field === 'tags' && e.message.includes('array'))).toBe(true);
225
+ });
226
+ it('should validate tag length limits', async () => {
227
+ const longTag = 'a'.repeat(33);
228
+ const skillContent = `---
229
+ name: long-tag-skill
230
+ description: A skill with a very long tag
231
+ tags:
232
+ - ${longTag}
233
+ ---
234
+ `;
235
+ const filePath = join(testDir, 'SKILL.md');
236
+ await fs.writeFile(filePath, skillContent);
237
+ const result = await executeValidate({ skill_path: filePath });
238
+ expect(result.valid).toBe(false);
239
+ expect(result.errors.some((e) => e.field.startsWith('tags[') && e.message.includes('exceeds'))).toBe(true);
240
+ });
241
+ });
242
+ describe('formatValidationResults', () => {
243
+ it('should format valid skill results', async () => {
244
+ const skillContent = `---
245
+ name: format-test-skill
246
+ description: A skill for testing formatting
247
+ author: tester
248
+ version: 1.0.0
249
+ tags: [testing, formatting]
250
+ ---
251
+ `;
252
+ const filePath = join(testDir, 'SKILL.md');
253
+ await fs.writeFile(filePath, skillContent);
254
+ const result = await executeValidate({ skill_path: filePath });
255
+ const formatted = formatValidationResults(result);
256
+ expect(formatted).toContain('Skill Validation Results');
257
+ expect(formatted).toContain('Status: VALID');
258
+ expect(formatted).toContain('Metadata:');
259
+ expect(formatted).toContain('Name: format-test-skill');
260
+ expect(formatted).toContain('Author: tester');
261
+ expect(formatted).toContain('Version: 1.0.0');
262
+ });
263
+ it('should format invalid skill results with errors', async () => {
264
+ const skillContent = `---
265
+ description: No name field
266
+ ---
267
+ `;
268
+ const filePath = join(testDir, 'SKILL.md');
269
+ await fs.writeFile(filePath, skillContent);
270
+ const result = await executeValidate({ skill_path: filePath });
271
+ const formatted = formatValidationResults(result);
272
+ expect(formatted).toContain('Status: INVALID');
273
+ expect(formatted).toContain('[ERROR]');
274
+ expect(formatted).toContain('name');
275
+ });
276
+ it('should show warning count in formatted output', async () => {
277
+ const skillContent = `---
278
+ name: warning-skill
279
+ ---
280
+ `;
281
+ const filePath = join(testDir, 'SKILL.md');
282
+ await fs.writeFile(filePath, skillContent);
283
+ const result = await executeValidate({ skill_path: filePath });
284
+ const formatted = formatValidationResults(result);
285
+ expect(formatted).toContain('warning(s)');
286
+ expect(formatted).toContain('[WARN]');
287
+ });
288
+ it('should include timing information', async () => {
289
+ const skillContent = `---
290
+ name: timing-skill
291
+ description: Test timing
292
+ ---
293
+ `;
294
+ const filePath = join(testDir, 'SKILL.md');
295
+ await fs.writeFile(filePath, skillContent);
296
+ const result = await executeValidate({ skill_path: filePath });
297
+ const formatted = formatValidationResults(result);
298
+ expect(formatted).toContain('Completed in');
299
+ expect(formatted).toContain('ms');
300
+ });
301
+ });
302
+ });
303
+ //# sourceMappingURL=validate.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.test.js","sourceRoot":"","sources":["../../tests/validate.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * SMI-682: Security tests for X-Forwarded-For proxy trust validation
3
+ *
4
+ * These tests verify that the server only trusts X-Forwarded-For headers
5
+ * when explicitly configured and from trusted proxy sources.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=proxy-trust.security.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy-trust.security.test.d.ts","sourceRoot":"","sources":["../../../tests/webhooks/proxy-trust.security.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}