@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,500 @@
1
+ /**
2
+ * License middleware tests
3
+ *
4
+ * @see SMI-1055: Add license middleware to MCP server
5
+ */
6
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
7
+ import { createLicenseMiddleware, requireFeature, isEnterpriseFeature, requiresLicense, getRequiredFeature, createLicenseErrorResponse, TOOL_FEATURES, FEATURE_DISPLAY_NAMES, FEATURE_TIERS, } from '../../middleware/license.js';
8
+ describe('License Middleware', () => {
9
+ const originalEnv = process.env;
10
+ beforeEach(() => {
11
+ vi.resetModules();
12
+ process.env = { ...originalEnv };
13
+ delete process.env.SKILLSMITH_LICENSE_KEY;
14
+ });
15
+ afterEach(() => {
16
+ process.env = originalEnv;
17
+ vi.restoreAllMocks();
18
+ });
19
+ describe('isEnterpriseFeature', () => {
20
+ it('should return false for community tools', () => {
21
+ expect(isEnterpriseFeature('search')).toBe(false);
22
+ expect(isEnterpriseFeature('get_skill')).toBe(false);
23
+ expect(isEnterpriseFeature('install_skill')).toBe(false);
24
+ expect(isEnterpriseFeature('skill_recommend')).toBe(false);
25
+ });
26
+ it('should return false for team tools', () => {
27
+ expect(isEnterpriseFeature('publish_private')).toBe(false);
28
+ expect(isEnterpriseFeature('team_workspace')).toBe(false);
29
+ });
30
+ it('should return true for enterprise tools', () => {
31
+ expect(isEnterpriseFeature('configure_sso')).toBe(true);
32
+ expect(isEnterpriseFeature('audit_export')).toBe(true);
33
+ expect(isEnterpriseFeature('rbac_manage')).toBe(true);
34
+ });
35
+ it('should return false for unknown tools', () => {
36
+ expect(isEnterpriseFeature('unknown_tool')).toBe(false);
37
+ });
38
+ });
39
+ describe('requiresLicense', () => {
40
+ it('should return false for community tools', () => {
41
+ expect(requiresLicense('search')).toBe(false);
42
+ expect(requiresLicense('get_skill')).toBe(false);
43
+ expect(requiresLicense('install_skill')).toBe(false);
44
+ });
45
+ it('should return true for team tools', () => {
46
+ expect(requiresLicense('publish_private')).toBe(true);
47
+ expect(requiresLicense('team_workspace')).toBe(true);
48
+ });
49
+ it('should return true for enterprise tools', () => {
50
+ expect(requiresLicense('configure_sso')).toBe(true);
51
+ expect(requiresLicense('audit_export')).toBe(true);
52
+ });
53
+ it('should return false for unknown tools', () => {
54
+ expect(requiresLicense('unknown_tool')).toBe(false);
55
+ });
56
+ });
57
+ describe('getRequiredFeature', () => {
58
+ it('should return null for community tools', () => {
59
+ expect(getRequiredFeature('search')).toBeNull();
60
+ expect(getRequiredFeature('get_skill')).toBeNull();
61
+ });
62
+ it('should return correct feature for team tools', () => {
63
+ expect(getRequiredFeature('publish_private')).toBe('private_skills');
64
+ expect(getRequiredFeature('team_workspace')).toBe('team_workspaces');
65
+ });
66
+ it('should return correct feature for enterprise tools', () => {
67
+ expect(getRequiredFeature('configure_sso')).toBe('sso_saml');
68
+ expect(getRequiredFeature('audit_export')).toBe('audit_logging');
69
+ expect(getRequiredFeature('rbac_manage')).toBe('rbac');
70
+ });
71
+ it('should return null for unknown tools', () => {
72
+ expect(getRequiredFeature('unknown_tool')).toBeNull();
73
+ });
74
+ });
75
+ describe('createLicenseMiddleware', () => {
76
+ describe('without license key', () => {
77
+ it('should allow community tools', async () => {
78
+ const middleware = createLicenseMiddleware();
79
+ const result = await middleware.checkTool('search');
80
+ expect(result.valid).toBe(true);
81
+ });
82
+ it('should deny team tools', async () => {
83
+ const middleware = createLicenseMiddleware();
84
+ const result = await middleware.checkTool('publish_private');
85
+ expect(result.valid).toBe(false);
86
+ expect(result.message).toContain('team license');
87
+ expect(result.upgradeUrl).toBeDefined();
88
+ });
89
+ it('should deny enterprise tools', async () => {
90
+ const middleware = createLicenseMiddleware();
91
+ const result = await middleware.checkTool('configure_sso');
92
+ expect(result.valid).toBe(false);
93
+ expect(result.message).toContain('enterprise license');
94
+ expect(result.upgradeUrl).toBeDefined();
95
+ });
96
+ it('should return community license info', async () => {
97
+ const middleware = createLicenseMiddleware();
98
+ const license = await middleware.getLicenseInfo();
99
+ expect(license).not.toBeNull();
100
+ expect(license?.tier).toBe('community');
101
+ expect(license?.features).toEqual([]);
102
+ });
103
+ });
104
+ describe('with invalid license key', () => {
105
+ beforeEach(() => {
106
+ process.env.SKILLSMITH_LICENSE_KEY = 'invalid-key-123';
107
+ });
108
+ it('should return null when license key present but validation unavailable', async () => {
109
+ // When a license key is provided but the enterprise package is not available,
110
+ // we return null to indicate validation failure rather than silently degrading
111
+ // to community tier. This ensures paying customers get feedback.
112
+ // See SMI-1130 for rationale.
113
+ const middleware = createLicenseMiddleware();
114
+ const license = await middleware.getLicenseInfo();
115
+ // License key present + no validator = null (validation failed)
116
+ // License key present + validator available = validates (may still be null if invalid)
117
+ expect(license).toBeNull();
118
+ });
119
+ it('should still allow community tools', async () => {
120
+ const middleware = createLicenseMiddleware();
121
+ const result = await middleware.checkTool('search');
122
+ expect(result.valid).toBe(true);
123
+ });
124
+ });
125
+ describe('cache behavior', () => {
126
+ it('should cache license info', async () => {
127
+ const middleware = createLicenseMiddleware({ cacheTtlMs: 10000 });
128
+ const license1 = await middleware.getLicenseInfo();
129
+ const license2 = await middleware.getLicenseInfo();
130
+ // Both should be the same cached object
131
+ expect(license1).toEqual(license2);
132
+ });
133
+ it('should invalidate cache when requested', async () => {
134
+ const middleware = createLicenseMiddleware();
135
+ await middleware.getLicenseInfo();
136
+ middleware.invalidateCache();
137
+ // Cache should be invalidated - next call should refetch
138
+ const license = await middleware.getLicenseInfo();
139
+ expect(license).not.toBeNull();
140
+ });
141
+ });
142
+ describe('custom environment variable', () => {
143
+ it('should read from custom env var', async () => {
144
+ process.env.CUSTOM_LICENSE_KEY = 'custom-key-123';
145
+ const middleware = createLicenseMiddleware({
146
+ licenseKeyEnvVar: 'CUSTOM_LICENSE_KEY',
147
+ });
148
+ // Should attempt to validate since key is present
149
+ // License key present + no validator = null (validation failed)
150
+ // See SMI-1130 for rationale.
151
+ const license = await middleware.getLicenseInfo();
152
+ expect(license).toBeNull();
153
+ delete process.env.CUSTOM_LICENSE_KEY;
154
+ });
155
+ });
156
+ });
157
+ describe('requireFeature', () => {
158
+ it('should create a function that checks features', async () => {
159
+ const middleware = createLicenseMiddleware();
160
+ const checkAudit = requireFeature('audit_logging');
161
+ const result = await checkAudit(middleware);
162
+ expect(result.valid).toBe(false);
163
+ expect(result.feature).toBe('audit_logging');
164
+ });
165
+ it('should return valid for features in license', async () => {
166
+ // Mock a licensed middleware
167
+ const mockMiddleware = {
168
+ checkFeature: vi.fn().mockResolvedValue({ valid: true }),
169
+ checkTool: vi.fn(),
170
+ getLicenseInfo: vi.fn(),
171
+ invalidateCache: vi.fn(),
172
+ };
173
+ const checkPrivate = requireFeature('private_skills');
174
+ const result = await checkPrivate(mockMiddleware);
175
+ expect(result.valid).toBe(true);
176
+ expect(mockMiddleware.checkFeature).toHaveBeenCalledWith('private_skills');
177
+ });
178
+ });
179
+ describe('createLicenseErrorResponse', () => {
180
+ it('should create MCP-formatted error response', () => {
181
+ const validationResult = {
182
+ valid: false,
183
+ feature: 'audit_logging',
184
+ message: 'Audit logging requires enterprise license',
185
+ upgradeUrl: 'https://skillsmith.io/pricing?feature=audit_logging',
186
+ };
187
+ const response = createLicenseErrorResponse(validationResult);
188
+ expect(response.isError).toBe(true);
189
+ expect(response.content).toHaveLength(1);
190
+ expect(response.content[0].type).toBe('text');
191
+ const parsed = JSON.parse(response.content[0].text);
192
+ expect(parsed.error).toBe('license_required');
193
+ expect(parsed.feature).toBe('audit_logging');
194
+ expect(parsed.upgradeUrl).toBeDefined();
195
+ });
196
+ it('should include upgrade URL in meta', () => {
197
+ const validationResult = {
198
+ valid: false,
199
+ message: 'Feature not available',
200
+ upgradeUrl: 'https://skillsmith.io/pricing',
201
+ };
202
+ const response = createLicenseErrorResponse(validationResult);
203
+ expect(response._meta?.upgradeUrl).toBe('https://skillsmith.io/pricing');
204
+ });
205
+ });
206
+ describe('TOOL_FEATURES mapping', () => {
207
+ it('should have null for all community tools', () => {
208
+ const communityTools = ['search', 'get_skill', 'install_skill', 'uninstall_skill'];
209
+ for (const tool of communityTools) {
210
+ expect(TOOL_FEATURES[tool]).toBeNull();
211
+ }
212
+ });
213
+ it('should have valid feature flags for licensed tools', () => {
214
+ const licensedTools = Object.entries(TOOL_FEATURES).filter(([, v]) => v !== null);
215
+ expect(licensedTools.length).toBeGreaterThan(0);
216
+ for (const [tool, feature] of licensedTools) {
217
+ expect(FEATURE_DISPLAY_NAMES[feature]).toBeDefined();
218
+ expect(FEATURE_TIERS[feature]).toBeDefined();
219
+ }
220
+ });
221
+ });
222
+ describe('FEATURE_DISPLAY_NAMES', () => {
223
+ it('should have display names for all features', () => {
224
+ const features = [
225
+ 'private_skills',
226
+ 'team_workspaces',
227
+ 'sso_saml',
228
+ 'audit_logging',
229
+ 'rbac',
230
+ 'priority_support',
231
+ 'custom_integrations',
232
+ 'advanced_analytics',
233
+ ];
234
+ for (const feature of features) {
235
+ expect(FEATURE_DISPLAY_NAMES[feature]).toBeDefined();
236
+ expect(typeof FEATURE_DISPLAY_NAMES[feature]).toBe('string');
237
+ }
238
+ });
239
+ });
240
+ describe('FEATURE_TIERS', () => {
241
+ it('should categorize features into team or enterprise', () => {
242
+ const teamFeatures = ['private_skills', 'team_workspaces', 'priority_support'];
243
+ const enterpriseFeatures = [
244
+ 'sso_saml',
245
+ 'audit_logging',
246
+ 'rbac',
247
+ 'custom_integrations',
248
+ 'advanced_analytics',
249
+ ];
250
+ for (const feature of teamFeatures) {
251
+ expect(FEATURE_TIERS[feature]).toBe('team');
252
+ }
253
+ for (const feature of enterpriseFeatures) {
254
+ expect(FEATURE_TIERS[feature]).toBe('enterprise');
255
+ }
256
+ });
257
+ });
258
+ describe('checkFeature', () => {
259
+ it('should return valid=false with helpful message for community users', async () => {
260
+ const middleware = createLicenseMiddleware();
261
+ const result = await middleware.checkFeature('audit_logging');
262
+ expect(result.valid).toBe(false);
263
+ expect(result.message).toContain('Audit Logging');
264
+ expect(result.message).toContain('enterprise');
265
+ expect(result.message).toContain('community');
266
+ expect(result.upgradeUrl).toContain('skillsmith.io/pricing');
267
+ expect(result.upgradeUrl).toContain('feature=audit_logging');
268
+ });
269
+ it('should include current tier in upgrade URL', async () => {
270
+ const middleware = createLicenseMiddleware();
271
+ const result = await middleware.checkFeature('private_skills');
272
+ expect(result.upgradeUrl).toContain('current=community');
273
+ });
274
+ });
275
+ describe('error messages', () => {
276
+ it('should provide actionable error messages', async () => {
277
+ const middleware = createLicenseMiddleware();
278
+ const ssoResult = await middleware.checkFeature('sso_saml');
279
+ expect(ssoResult.message).toMatch(/SSO\/SAML Integration/);
280
+ expect(ssoResult.message).toMatch(/enterprise license/);
281
+ const privateResult = await middleware.checkFeature('private_skills');
282
+ expect(privateResult.message).toMatch(/Private Skills/);
283
+ expect(privateResult.message).toMatch(/team license/);
284
+ });
285
+ });
286
+ describe('license expiration warning', () => {
287
+ it('should return warning when license expires within 30 days', async () => {
288
+ // Mock middleware that returns a license expiring in 15 days
289
+ const expiresIn15Days = new Date(Date.now() + 15 * 24 * 60 * 60 * 1000);
290
+ const mockMiddleware = {
291
+ checkFeature: vi.fn().mockResolvedValue({
292
+ valid: true,
293
+ warning: `Your license expires in 15 days. Please renew to avoid service interruption.`,
294
+ }),
295
+ checkTool: vi.fn(),
296
+ getLicenseInfo: vi.fn().mockResolvedValue({
297
+ valid: true,
298
+ tier: 'enterprise',
299
+ features: ['audit_logging'],
300
+ expiresAt: expiresIn15Days,
301
+ }),
302
+ invalidateCache: vi.fn(),
303
+ };
304
+ const result = await mockMiddleware.checkFeature('audit_logging');
305
+ expect(result.valid).toBe(true);
306
+ expect(result.warning).toContain('expires in 15 days');
307
+ expect(result.warning).toContain('Please renew');
308
+ });
309
+ it('should use singular day when 1 day remaining', async () => {
310
+ const mockMiddleware = {
311
+ checkFeature: vi.fn().mockResolvedValue({
312
+ valid: true,
313
+ warning: `Your license expires in 1 day. Please renew to avoid service interruption.`,
314
+ }),
315
+ checkTool: vi.fn(),
316
+ getLicenseInfo: vi.fn(),
317
+ invalidateCache: vi.fn(),
318
+ };
319
+ const result = await mockMiddleware.checkFeature('audit_logging');
320
+ expect(result.warning).toContain('1 day');
321
+ expect(result.warning).not.toContain('1 days');
322
+ });
323
+ it('should not return warning when license expires in more than 30 days', async () => {
324
+ const mockMiddleware = {
325
+ checkFeature: vi.fn().mockResolvedValue({
326
+ valid: true,
327
+ warning: undefined,
328
+ }),
329
+ checkTool: vi.fn(),
330
+ getLicenseInfo: vi.fn(),
331
+ invalidateCache: vi.fn(),
332
+ };
333
+ const result = await mockMiddleware.checkFeature('audit_logging');
334
+ expect(result.valid).toBe(true);
335
+ expect(result.warning).toBeUndefined();
336
+ });
337
+ it('should not return warning when expiresAt is undefined', async () => {
338
+ const mockMiddleware = {
339
+ checkFeature: vi.fn().mockResolvedValue({
340
+ valid: true,
341
+ warning: undefined,
342
+ }),
343
+ checkTool: vi.fn(),
344
+ getLicenseInfo: vi.fn().mockResolvedValue({
345
+ valid: true,
346
+ tier: 'team',
347
+ features: ['private_skills'],
348
+ expiresAt: undefined,
349
+ }),
350
+ invalidateCache: vi.fn(),
351
+ };
352
+ const result = await mockMiddleware.checkFeature('private_skills');
353
+ expect(result.valid).toBe(true);
354
+ expect(result.warning).toBeUndefined();
355
+ });
356
+ });
357
+ });
358
+ describe('with mocked enterprise validator', () => {
359
+ it('should validate team license features', async () => {
360
+ const mockValidator = {
361
+ validate: vi.fn().mockResolvedValue({
362
+ valid: true,
363
+ license: {
364
+ tier: 'team',
365
+ features: ['private_skills', 'team_workspaces'],
366
+ customerId: 'test-customer',
367
+ issuedAt: new Date(),
368
+ expiresAt: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000),
369
+ },
370
+ }),
371
+ hasFeature: vi.fn().mockResolvedValue(true),
372
+ };
373
+ // Test the validator mock structure matches expected interface
374
+ const validationResult = await mockValidator.validate('test-key');
375
+ expect(validationResult.valid).toBe(true);
376
+ expect(validationResult.license?.tier).toBe('team');
377
+ expect(validationResult.license?.features).toContain('private_skills');
378
+ expect(validationResult.license?.features).toContain('team_workspaces');
379
+ expect(mockValidator.validate).toHaveBeenCalledWith('test-key');
380
+ });
381
+ it('should validate enterprise license features', async () => {
382
+ const mockValidator = {
383
+ validate: vi.fn().mockResolvedValue({
384
+ valid: true,
385
+ license: {
386
+ tier: 'enterprise',
387
+ features: [
388
+ 'private_skills',
389
+ 'team_workspaces',
390
+ 'sso_saml',
391
+ 'audit_logging',
392
+ 'rbac',
393
+ ],
394
+ customerId: 'enterprise-customer',
395
+ issuedAt: new Date(),
396
+ expiresAt: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000),
397
+ },
398
+ }),
399
+ hasFeature: vi.fn().mockImplementation((_key, feature) => {
400
+ const enterpriseFeatures = [
401
+ 'private_skills',
402
+ 'team_workspaces',
403
+ 'sso_saml',
404
+ 'audit_logging',
405
+ 'rbac',
406
+ ];
407
+ return Promise.resolve(enterpriseFeatures.includes(feature));
408
+ }),
409
+ };
410
+ // Validate enterprise license structure
411
+ const validationResult = await mockValidator.validate('enterprise-key');
412
+ expect(validationResult.valid).toBe(true);
413
+ expect(validationResult.license?.tier).toBe('enterprise');
414
+ expect(validationResult.license?.features).toContain('sso_saml');
415
+ expect(validationResult.license?.features).toContain('audit_logging');
416
+ expect(validationResult.license?.features).toContain('rbac');
417
+ // Test hasFeature method
418
+ expect(await mockValidator.hasFeature('enterprise-key', 'sso_saml')).toBe(true);
419
+ expect(await mockValidator.hasFeature('enterprise-key', 'audit_logging')).toBe(true);
420
+ expect(await mockValidator.hasFeature('enterprise-key', 'unknown_feature')).toBe(false);
421
+ });
422
+ it('should handle validation failure', async () => {
423
+ const mockValidator = {
424
+ validate: vi.fn().mockResolvedValue({
425
+ valid: false,
426
+ error: { code: 'INVALID_LICENSE', message: 'License expired' },
427
+ }),
428
+ hasFeature: vi.fn().mockResolvedValue(false),
429
+ };
430
+ // Test validation failure
431
+ const validationResult = await mockValidator.validate('expired-key');
432
+ expect(validationResult.valid).toBe(false);
433
+ expect(validationResult.error?.code).toBe('INVALID_LICENSE');
434
+ expect(validationResult.error?.message).toBe('License expired');
435
+ expect(validationResult.license).toBeUndefined();
436
+ // hasFeature should return false for invalid license
437
+ expect(await mockValidator.hasFeature('expired-key', 'any_feature')).toBe(false);
438
+ });
439
+ it('should handle validation exception', async () => {
440
+ const mockValidator = {
441
+ validate: vi.fn().mockRejectedValue(new Error('Network error')),
442
+ hasFeature: vi.fn().mockRejectedValue(new Error('Network error')),
443
+ };
444
+ // Test validation exception handling
445
+ await expect(mockValidator.validate('test-key')).rejects.toThrow('Network error');
446
+ await expect(mockValidator.hasFeature('test-key', 'feature')).rejects.toThrow('Network error');
447
+ });
448
+ it('should verify LicenseInfo structure matches enterprise license', async () => {
449
+ const mockEnterpriseLicense = {
450
+ tier: 'enterprise',
451
+ features: ['sso_saml', 'audit_logging'],
452
+ customerId: 'test-customer',
453
+ issuedAt: new Date('2024-01-01'),
454
+ expiresAt: new Date('2025-01-01'),
455
+ };
456
+ // Convert to middleware LicenseInfo format (as done in getLicenseInfo)
457
+ const licenseInfo = {
458
+ valid: true,
459
+ tier: mockEnterpriseLicense.tier,
460
+ features: mockEnterpriseLicense.features,
461
+ expiresAt: mockEnterpriseLicense.expiresAt,
462
+ organizationId: mockEnterpriseLicense.customerId,
463
+ };
464
+ expect(licenseInfo.valid).toBe(true);
465
+ expect(licenseInfo.tier).toBe('enterprise');
466
+ expect(licenseInfo.features).toEqual(['sso_saml', 'audit_logging']);
467
+ expect(licenseInfo.expiresAt).toEqual(new Date('2025-01-01'));
468
+ expect(licenseInfo.organizationId).toBe('test-customer');
469
+ });
470
+ });
471
+ describe('Tool Feature Mapping Integration', () => {
472
+ it('should cover all documented tool names', () => {
473
+ // These are the core tools from the MCP server
474
+ const coreTools = [
475
+ 'search',
476
+ 'get_skill',
477
+ 'install_skill',
478
+ 'uninstall_skill',
479
+ 'skill_recommend',
480
+ 'skill_validate',
481
+ 'skill_compare',
482
+ 'skill_suggest',
483
+ ];
484
+ for (const tool of coreTools) {
485
+ expect(tool in TOOL_FEATURES).toBe(true);
486
+ expect(TOOL_FEATURES[tool]).toBeNull(); // All core tools should be community
487
+ }
488
+ });
489
+ it('should have consistent tier assignments', () => {
490
+ // Verify that enterprise features are truly enterprise-level
491
+ const enterpriseFeatures = Object.entries(FEATURE_TIERS)
492
+ .filter(([, tier]) => tier === 'enterprise')
493
+ .map(([feature]) => feature);
494
+ // SSO, audit, and RBAC should all be enterprise
495
+ expect(enterpriseFeatures).toContain('sso_saml');
496
+ expect(enterpriseFeatures).toContain('audit_logging');
497
+ expect(enterpriseFeatures).toContain('rbac');
498
+ });
499
+ });
500
+ //# sourceMappingURL=license.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license.test.js","sourceRoot":"","sources":["../../../../src/__tests__/middleware/license.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Tests for SMI-581: MCP Search Tool
3
+ * Updated for SMI-789: Wire to SearchService
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=search.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/search.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Tests for SMI-581: MCP Search Tool
3
+ * Updated for SMI-789: Wire to SearchService
4
+ */
5
+ import { describe, it, expect, beforeAll, afterAll } from 'vitest';
6
+ import { executeSearch, formatSearchResults } from '../tools/search.js';
7
+ import { SkillsmithError } from '@skillsmith/core';
8
+ import { createSeededTestContext } from './test-utils.js';
9
+ let context;
10
+ beforeAll(() => {
11
+ context = createSeededTestContext();
12
+ });
13
+ afterAll(() => {
14
+ context.db.close();
15
+ });
16
+ describe('Search Tool', () => {
17
+ describe('executeSearch', () => {
18
+ it('should return results for valid query', async () => {
19
+ const result = await executeSearch({ query: 'commit' }, context);
20
+ expect(result.results).toBeDefined();
21
+ expect(result.results.length).toBeGreaterThan(0);
22
+ expect(result.total).toBeGreaterThan(0);
23
+ expect(result.query).toBe('commit');
24
+ expect(result.timing.totalMs).toBeGreaterThanOrEqual(0);
25
+ });
26
+ it('should filter by category', async () => {
27
+ const result = await executeSearch({
28
+ query: 'test',
29
+ category: 'testing',
30
+ }, context);
31
+ // With real search, we filter by category
32
+ expect(result.results.length).toBeGreaterThanOrEqual(0);
33
+ });
34
+ it('should filter by trust tier', async () => {
35
+ const result = await executeSearch({
36
+ query: 'anthropic',
37
+ trust_tier: 'verified',
38
+ }, context);
39
+ result.results.forEach((skill) => {
40
+ expect(skill.trustTier).toBe('verified');
41
+ });
42
+ });
43
+ it('should filter by minimum score', async () => {
44
+ const result = await executeSearch({
45
+ query: 'commit',
46
+ min_score: 90,
47
+ }, context);
48
+ result.results.forEach((skill) => {
49
+ expect(skill.score).toBeGreaterThanOrEqual(90);
50
+ });
51
+ });
52
+ it('should sort results by relevance', async () => {
53
+ const result = await executeSearch({ query: 'commit' }, context);
54
+ // Results are sorted by BM25 rank, not score
55
+ expect(result.results.length).toBeGreaterThanOrEqual(0);
56
+ });
57
+ it('should limit results to 10', async () => {
58
+ const result = await executeSearch({ query: 'test' }, context);
59
+ expect(result.results.length).toBeLessThanOrEqual(10);
60
+ });
61
+ it('should throw error for empty query', async () => {
62
+ await expect(executeSearch({ query: '' }, context)).rejects.toThrow(SkillsmithError);
63
+ });
64
+ it('should throw error for query less than 2 characters', async () => {
65
+ await expect(executeSearch({ query: 'a' }, context)).rejects.toThrow(SkillsmithError);
66
+ });
67
+ it('should throw error for invalid min_score', async () => {
68
+ await expect(executeSearch({ query: 'test', min_score: 150 }, context)).rejects.toThrow(SkillsmithError);
69
+ });
70
+ });
71
+ describe('formatSearchResults', () => {
72
+ it('should format results for terminal display', async () => {
73
+ const result = await executeSearch({ query: 'commit' }, context);
74
+ const formatted = formatSearchResults(result);
75
+ expect(formatted).toContain('Search Results');
76
+ expect(formatted).toContain('commit');
77
+ });
78
+ it('should show helpful message when no results', async () => {
79
+ const result = await executeSearch({ query: 'xyznonexistent123' }, context);
80
+ const formatted = formatSearchResults(result);
81
+ expect(formatted).toContain('No skills found');
82
+ expect(formatted).toContain('Suggestions:');
83
+ });
84
+ });
85
+ });
86
+ //# sourceMappingURL=search.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.test.js","sourceRoot":"","sources":["../../../src/__tests__/search.test.ts"],"names":[],"mappings":"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"}