@skillsmith/mcp-server 0.4.13 → 0.5.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 (391) hide show
  1. package/CHANGELOG.md +32 -4
  2. package/README.md +89 -13
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/src/__tests__/compare.test.js +5 -5
  5. package/dist/src/__tests__/compare.test.js.map +1 -1
  6. package/dist/src/__tests__/context-listeners.test.d.ts +12 -0
  7. package/dist/src/__tests__/context-listeners.test.d.ts.map +1 -0
  8. package/dist/src/__tests__/context-listeners.test.js +87 -0
  9. package/dist/src/__tests__/context-listeners.test.js.map +1 -0
  10. package/dist/src/__tests__/context.test.js +84 -82
  11. package/dist/src/__tests__/context.test.js.map +1 -1
  12. package/dist/src/__tests__/get-skill.api-path.test.js +21 -14
  13. package/dist/src/__tests__/get-skill.api-path.test.js.map +1 -1
  14. package/dist/src/__tests__/get-skill.test.js +5 -5
  15. package/dist/src/__tests__/get-skill.test.js.map +1 -1
  16. package/dist/src/__tests__/index-local.test.js +5 -5
  17. package/dist/src/__tests__/index-local.test.js.map +1 -1
  18. package/dist/src/__tests__/recommend-online-path.test.js +5 -5
  19. package/dist/src/__tests__/recommend-online-path.test.js.map +1 -1
  20. package/dist/src/__tests__/recommend.test.js +9 -9
  21. package/dist/src/__tests__/recommend.test.js.map +1 -1
  22. package/dist/src/__tests__/search-compatible-with.test.d.ts +10 -0
  23. package/dist/src/__tests__/search-compatible-with.test.d.ts.map +1 -0
  24. package/dist/src/__tests__/search-compatible-with.test.js +96 -0
  25. package/dist/src/__tests__/search-compatible-with.test.js.map +1 -0
  26. package/dist/src/__tests__/search-online-path.test.js +5 -5
  27. package/dist/src/__tests__/search-online-path.test.js.map +1 -1
  28. package/dist/src/__tests__/search.test.js +16 -101
  29. package/dist/src/__tests__/search.test.js.map +1 -1
  30. package/dist/src/__tests__/test-utils.d.ts +18 -3
  31. package/dist/src/__tests__/test-utils.d.ts.map +1 -1
  32. package/dist/src/__tests__/test-utils.js +24 -7
  33. package/dist/src/__tests__/test-utils.js.map +1 -1
  34. package/dist/src/audit/audit-history.d.ts +77 -0
  35. package/dist/src/audit/audit-history.d.ts.map +1 -0
  36. package/dist/src/audit/audit-history.js +98 -0
  37. package/dist/src/audit/audit-history.js.map +1 -0
  38. package/dist/src/audit/audit-report-writer.d.ts +82 -0
  39. package/dist/src/audit/audit-report-writer.d.ts.map +1 -0
  40. package/dist/src/audit/audit-report-writer.js +241 -0
  41. package/dist/src/audit/audit-report-writer.js.map +1 -0
  42. package/dist/src/audit/audit-suggestions.d.ts +52 -0
  43. package/dist/src/audit/audit-suggestions.d.ts.map +1 -0
  44. package/dist/src/audit/audit-suggestions.js +90 -0
  45. package/dist/src/audit/audit-suggestions.js.map +1 -0
  46. package/dist/src/audit/bootstrap-unmanaged.d.ts +66 -0
  47. package/dist/src/audit/bootstrap-unmanaged.d.ts.map +1 -0
  48. package/dist/src/audit/bootstrap-unmanaged.js +91 -0
  49. package/dist/src/audit/bootstrap-unmanaged.js.map +1 -0
  50. package/dist/src/audit/collision-detector.d.ts +72 -0
  51. package/dist/src/audit/collision-detector.d.ts.map +1 -0
  52. package/dist/src/audit/collision-detector.helpers.d.ts +63 -0
  53. package/dist/src/audit/collision-detector.helpers.d.ts.map +1 -0
  54. package/dist/src/audit/collision-detector.helpers.js +141 -0
  55. package/dist/src/audit/collision-detector.helpers.js.map +1 -0
  56. package/dist/src/audit/collision-detector.js +172 -0
  57. package/dist/src/audit/collision-detector.js.map +1 -0
  58. package/dist/src/audit/collision-detector.semantic.helpers.d.ts +49 -0
  59. package/dist/src/audit/collision-detector.semantic.helpers.d.ts.map +1 -0
  60. package/dist/src/audit/collision-detector.semantic.helpers.js +121 -0
  61. package/dist/src/audit/collision-detector.semantic.helpers.js.map +1 -0
  62. package/dist/src/audit/collision-detector.types.d.ts +70 -0
  63. package/dist/src/audit/collision-detector.types.d.ts.map +1 -0
  64. package/dist/src/audit/collision-detector.types.js +9 -0
  65. package/dist/src/audit/collision-detector.types.js.map +1 -0
  66. package/dist/src/audit/edit-applier.d.ts +64 -0
  67. package/dist/src/audit/edit-applier.d.ts.map +1 -0
  68. package/dist/src/audit/edit-applier.js +233 -0
  69. package/dist/src/audit/edit-applier.js.map +1 -0
  70. package/dist/src/audit/edit-applier.types.d.ts +72 -0
  71. package/dist/src/audit/edit-applier.types.d.ts.map +1 -0
  72. package/dist/src/audit/edit-applier.types.js +13 -0
  73. package/dist/src/audit/edit-applier.types.js.map +1 -0
  74. package/dist/src/audit/edit-suggester.d.ts +63 -0
  75. package/dist/src/audit/edit-suggester.d.ts.map +1 -0
  76. package/dist/src/audit/edit-suggester.js +326 -0
  77. package/dist/src/audit/edit-suggester.js.map +1 -0
  78. package/dist/src/audit/edit-suggester.types.d.ts +148 -0
  79. package/dist/src/audit/edit-suggester.types.d.ts.map +1 -0
  80. package/dist/src/audit/edit-suggester.types.js +17 -0
  81. package/dist/src/audit/edit-suggester.types.js.map +1 -0
  82. package/dist/src/audit/framework-adapter.d.ts +54 -0
  83. package/dist/src/audit/framework-adapter.d.ts.map +1 -0
  84. package/dist/src/audit/framework-adapter.js +251 -0
  85. package/dist/src/audit/framework-adapter.js.map +1 -0
  86. package/dist/src/audit/framework-adapter.types.d.ts +162 -0
  87. package/dist/src/audit/framework-adapter.types.d.ts.map +1 -0
  88. package/dist/src/audit/framework-adapter.types.js +31 -0
  89. package/dist/src/audit/framework-adapter.types.js.map +1 -0
  90. package/dist/src/audit/index.d.ts +46 -0
  91. package/dist/src/audit/index.d.ts.map +1 -0
  92. package/dist/src/audit/index.js +44 -0
  93. package/dist/src/audit/index.js.map +1 -0
  94. package/dist/src/audit/install-preflight.d.ts +99 -0
  95. package/dist/src/audit/install-preflight.d.ts.map +1 -0
  96. package/dist/src/audit/install-preflight.js +320 -0
  97. package/dist/src/audit/install-preflight.js.map +1 -0
  98. package/dist/src/audit/namespace-audit.types.d.ts +100 -0
  99. package/dist/src/audit/namespace-audit.types.d.ts.map +1 -0
  100. package/dist/src/audit/namespace-audit.types.js +20 -0
  101. package/dist/src/audit/namespace-audit.types.js.map +1 -0
  102. package/dist/src/audit/namespace-overrides.d.ts +79 -0
  103. package/dist/src/audit/namespace-overrides.d.ts.map +1 -0
  104. package/dist/src/audit/namespace-overrides.js +228 -0
  105. package/dist/src/audit/namespace-overrides.js.map +1 -0
  106. package/dist/src/audit/namespace-overrides.types.d.ts +115 -0
  107. package/dist/src/audit/namespace-overrides.types.d.ts.map +1 -0
  108. package/dist/src/audit/namespace-overrides.types.js +26 -0
  109. package/dist/src/audit/namespace-overrides.types.js.map +1 -0
  110. package/dist/src/audit/rename-engine.apply-paths.d.ts +54 -0
  111. package/dist/src/audit/rename-engine.apply-paths.d.ts.map +1 -0
  112. package/dist/src/audit/rename-engine.apply-paths.js +126 -0
  113. package/dist/src/audit/rename-engine.apply-paths.js.map +1 -0
  114. package/dist/src/audit/rename-engine.d.ts +59 -0
  115. package/dist/src/audit/rename-engine.d.ts.map +1 -0
  116. package/dist/src/audit/rename-engine.helpers.d.ts +63 -0
  117. package/dist/src/audit/rename-engine.helpers.d.ts.map +1 -0
  118. package/dist/src/audit/rename-engine.helpers.js +224 -0
  119. package/dist/src/audit/rename-engine.helpers.js.map +1 -0
  120. package/dist/src/audit/rename-engine.js +393 -0
  121. package/dist/src/audit/rename-engine.js.map +1 -0
  122. package/dist/src/audit/rename-engine.types.d.ts +157 -0
  123. package/dist/src/audit/rename-engine.types.d.ts.map +1 -0
  124. package/dist/src/audit/rename-engine.types.js +15 -0
  125. package/dist/src/audit/rename-engine.types.js.map +1 -0
  126. package/dist/src/audit/run-inventory-audit.d.ts +95 -0
  127. package/dist/src/audit/run-inventory-audit.d.ts.map +1 -0
  128. package/dist/src/audit/run-inventory-audit.js +245 -0
  129. package/dist/src/audit/run-inventory-audit.js.map +1 -0
  130. package/dist/src/audit/suggestion-chain.d.ts +89 -0
  131. package/dist/src/audit/suggestion-chain.d.ts.map +1 -0
  132. package/dist/src/audit/suggestion-chain.js +121 -0
  133. package/dist/src/audit/suggestion-chain.js.map +1 -0
  134. package/dist/src/audit-tool-dispatch.d.ts +61 -0
  135. package/dist/src/audit-tool-dispatch.d.ts.map +1 -0
  136. package/dist/src/audit-tool-dispatch.js +114 -0
  137. package/dist/src/audit-tool-dispatch.js.map +1 -0
  138. package/dist/src/index.js +1 -1
  139. package/dist/src/index.js.map +1 -1
  140. package/dist/src/indexer/LocalIndexer.d.ts +8 -1
  141. package/dist/src/indexer/LocalIndexer.d.ts.map +1 -1
  142. package/dist/src/indexer/LocalIndexer.js +42 -38
  143. package/dist/src/indexer/LocalIndexer.js.map +1 -1
  144. package/dist/src/middleware/__tests__/license.gate.test.js +21 -2
  145. package/dist/src/middleware/__tests__/license.gate.test.js.map +1 -1
  146. package/dist/src/middleware/license.gate.d.ts +14 -0
  147. package/dist/src/middleware/license.gate.d.ts.map +1 -1
  148. package/dist/src/middleware/license.gate.js +52 -1
  149. package/dist/src/middleware/license.gate.js.map +1 -1
  150. package/dist/src/onboarding/install-assets.d.ts.map +1 -1
  151. package/dist/src/onboarding/install-assets.js +11 -5
  152. package/dist/src/onboarding/install-assets.js.map +1 -1
  153. package/dist/src/tool-dispatch.d.ts.map +1 -1
  154. package/dist/src/tool-dispatch.js +6 -4
  155. package/dist/src/tool-dispatch.js.map +1 -1
  156. package/dist/src/tools/analytics.service.test.js +6 -4
  157. package/dist/src/tools/analytics.service.test.js.map +1 -1
  158. package/dist/src/tools/apply-namespace-rename.d.ts +71 -0
  159. package/dist/src/tools/apply-namespace-rename.d.ts.map +1 -0
  160. package/dist/src/tools/apply-namespace-rename.js +137 -0
  161. package/dist/src/tools/apply-namespace-rename.js.map +1 -0
  162. package/dist/src/tools/apply-namespace-rename.types.d.ts +46 -0
  163. package/dist/src/tools/apply-namespace-rename.types.d.ts.map +1 -0
  164. package/dist/src/tools/apply-namespace-rename.types.js +9 -0
  165. package/dist/src/tools/apply-namespace-rename.types.js.map +1 -0
  166. package/dist/src/tools/apply-recommended-edit.d.ts +50 -0
  167. package/dist/src/tools/apply-recommended-edit.d.ts.map +1 -0
  168. package/dist/src/tools/apply-recommended-edit.js +112 -0
  169. package/dist/src/tools/apply-recommended-edit.js.map +1 -0
  170. package/dist/src/tools/apply-recommended-edit.types.d.ts +49 -0
  171. package/dist/src/tools/apply-recommended-edit.types.d.ts.map +1 -0
  172. package/dist/src/tools/apply-recommended-edit.types.js +14 -0
  173. package/dist/src/tools/apply-recommended-edit.types.js.map +1 -0
  174. package/dist/src/tools/audit-tools.d.ts +4 -4
  175. package/dist/src/tools/compliance-tools.service.test.js +6 -4
  176. package/dist/src/tools/compliance-tools.service.test.js.map +1 -1
  177. package/dist/src/tools/install.backup-gc.d.ts +61 -0
  178. package/dist/src/tools/install.backup-gc.d.ts.map +1 -0
  179. package/dist/src/tools/install.backup-gc.js +166 -0
  180. package/dist/src/tools/install.backup-gc.js.map +1 -0
  181. package/dist/src/tools/install.conflict-helpers.d.ts +29 -2
  182. package/dist/src/tools/install.conflict-helpers.d.ts.map +1 -1
  183. package/dist/src/tools/install.conflict-helpers.js +37 -4
  184. package/dist/src/tools/install.conflict-helpers.js.map +1 -1
  185. package/dist/src/tools/install.d.ts +15 -1
  186. package/dist/src/tools/install.d.ts.map +1 -1
  187. package/dist/src/tools/install.js +162 -7
  188. package/dist/src/tools/install.js.map +1 -1
  189. package/dist/src/tools/install.ledger-replay.d.ts +52 -0
  190. package/dist/src/tools/install.ledger-replay.d.ts.map +1 -0
  191. package/dist/src/tools/install.ledger-replay.js +88 -0
  192. package/dist/src/tools/install.ledger-replay.js.map +1 -0
  193. package/dist/src/tools/install.namespace-gate.d.ts +68 -0
  194. package/dist/src/tools/install.namespace-gate.d.ts.map +1 -0
  195. package/dist/src/tools/install.namespace-gate.js +129 -0
  196. package/dist/src/tools/install.namespace-gate.js.map +1 -0
  197. package/dist/src/tools/install.test.js +71 -1
  198. package/dist/src/tools/install.test.js.map +1 -1
  199. package/dist/src/tools/install.tool.d.ts +17 -0
  200. package/dist/src/tools/install.tool.d.ts.map +1 -1
  201. package/dist/src/tools/install.tool.js +19 -1
  202. package/dist/src/tools/install.tool.js.map +1 -1
  203. package/dist/src/tools/install.types.d.ts +35 -1
  204. package/dist/src/tools/install.types.d.ts.map +1 -1
  205. package/dist/src/tools/install.types.js +24 -2
  206. package/dist/src/tools/install.types.js.map +1 -1
  207. package/dist/src/tools/namespace-audit/telemetry.d.ts +80 -0
  208. package/dist/src/tools/namespace-audit/telemetry.d.ts.map +1 -0
  209. package/dist/src/tools/namespace-audit/telemetry.js +129 -0
  210. package/dist/src/tools/namespace-audit/telemetry.js.map +1 -0
  211. package/dist/src/tools/outdated.test.js +2 -2
  212. package/dist/src/tools/outdated.test.js.map +1 -1
  213. package/dist/src/tools/publish-private.test.js +2 -2
  214. package/dist/src/tools/publish-private.test.js.map +1 -1
  215. package/dist/src/tools/recommend.types.d.ts +2 -2
  216. package/dist/src/tools/search.d.ts +2 -2
  217. package/dist/src/tools/search.js +3 -3
  218. package/dist/src/tools/search.js.map +1 -1
  219. package/dist/src/tools/skill-audit.test.js +2 -2
  220. package/dist/src/tools/skill-audit.test.js.map +1 -1
  221. package/dist/src/tools/skill-diff.d.ts +1 -1
  222. package/dist/src/tools/skill-inventory-audit.d.ts +67 -0
  223. package/dist/src/tools/skill-inventory-audit.d.ts.map +1 -0
  224. package/dist/src/tools/skill-inventory-audit.js +112 -0
  225. package/dist/src/tools/skill-inventory-audit.js.map +1 -0
  226. package/dist/src/tools/skill-inventory-audit.types.d.ts +67 -0
  227. package/dist/src/tools/skill-inventory-audit.types.d.ts.map +1 -0
  228. package/dist/src/tools/skill-inventory-audit.types.js +14 -0
  229. package/dist/src/tools/skill-inventory-audit.types.js.map +1 -0
  230. package/dist/src/tools/skill-pack-audit.d.ts.map +1 -1
  231. package/dist/src/tools/skill-pack-audit.helpers.d.ts.map +1 -1
  232. package/dist/src/tools/skill-pack-audit.helpers.js +15 -2
  233. package/dist/src/tools/skill-pack-audit.helpers.js.map +1 -1
  234. package/dist/src/tools/skill-pack-audit.js +15 -1
  235. package/dist/src/tools/skill-pack-audit.js.map +1 -1
  236. package/dist/src/tools/skill-rescan.d.ts.map +1 -1
  237. package/dist/src/tools/skill-rescan.js +4 -2
  238. package/dist/src/tools/skill-rescan.js.map +1 -1
  239. package/dist/src/tools/suggest.d.ts +2 -2
  240. package/dist/src/tools/uninstall.d.ts +1 -1
  241. package/dist/src/tools/uninstall.d.ts.map +1 -1
  242. package/dist/src/tools/uninstall.js +17 -3
  243. package/dist/src/tools/uninstall.js.map +1 -1
  244. package/dist/src/tools/validate.types.d.ts +10 -1
  245. package/dist/src/tools/validate.types.d.ts.map +1 -1
  246. package/dist/src/tools/validate.types.js +10 -1
  247. package/dist/src/tools/validate.types.js.map +1 -1
  248. package/dist/src/utils/installed-skills.d.ts.map +1 -1
  249. package/dist/src/utils/installed-skills.js +8 -6
  250. package/dist/src/utils/installed-skills.js.map +1 -1
  251. package/dist/src/utils/local-inventory.d.ts +29 -0
  252. package/dist/src/utils/local-inventory.d.ts.map +1 -0
  253. package/dist/src/utils/local-inventory.helpers.d.ts +96 -0
  254. package/dist/src/utils/local-inventory.helpers.d.ts.map +1 -0
  255. package/dist/src/utils/local-inventory.helpers.js +279 -0
  256. package/dist/src/utils/local-inventory.helpers.js.map +1 -0
  257. package/dist/src/utils/local-inventory.js +202 -0
  258. package/dist/src/utils/local-inventory.js.map +1 -0
  259. package/dist/src/utils/local-inventory.types.d.ts +100 -0
  260. package/dist/src/utils/local-inventory.types.d.ts.map +1 -0
  261. package/dist/src/utils/local-inventory.types.js +9 -0
  262. package/dist/src/utils/local-inventory.types.js.map +1 -0
  263. package/dist/src/webhooks/stripe-webhook-endpoint.d.ts +12 -0
  264. package/dist/src/webhooks/stripe-webhook-endpoint.d.ts.map +1 -1
  265. package/dist/src/webhooks/stripe-webhook-endpoint.js +30 -9
  266. package/dist/src/webhooks/stripe-webhook-endpoint.js.map +1 -1
  267. package/dist/src/webhooks/webhook-endpoint.d.ts +13 -0
  268. package/dist/src/webhooks/webhook-endpoint.d.ts.map +1 -1
  269. package/dist/src/webhooks/webhook-endpoint.js +31 -9
  270. package/dist/src/webhooks/webhook-endpoint.js.map +1 -1
  271. package/dist/tests/compare.test.js +5 -5
  272. package/dist/tests/compare.test.js.map +1 -1
  273. package/dist/tests/context-async-listeners.test.d.ts +12 -0
  274. package/dist/tests/context-async-listeners.test.d.ts.map +1 -0
  275. package/dist/tests/context-async-listeners.test.js +62 -0
  276. package/dist/tests/context-async-listeners.test.js.map +1 -0
  277. package/dist/tests/e2e/compare.e2e.test.js +9 -3
  278. package/dist/tests/e2e/compare.e2e.test.js.map +1 -1
  279. package/dist/tests/e2e/install-flow.e2e.test.js +9 -3
  280. package/dist/tests/e2e/install-flow.e2e.test.js.map +1 -1
  281. package/dist/tests/e2e/recommend.e2e.test.js +9 -3
  282. package/dist/tests/e2e/recommend.e2e.test.js.map +1 -1
  283. package/dist/tests/e2e/skill-flow.e2e.test.js +17 -5
  284. package/dist/tests/e2e/skill-flow.e2e.test.js.map +1 -1
  285. package/dist/tests/e2e/suggest.e2e.test.js +11 -3
  286. package/dist/tests/e2e/suggest.e2e.test.js.map +1 -1
  287. package/dist/tests/integration/audit-roundtrip.test.d.ts +29 -0
  288. package/dist/tests/integration/audit-roundtrip.test.d.ts.map +1 -0
  289. package/dist/tests/integration/audit-roundtrip.test.js +214 -0
  290. package/dist/tests/integration/audit-roundtrip.test.js.map +1 -0
  291. package/dist/tests/integration/install-namespace.integration.test.d.ts +14 -0
  292. package/dist/tests/integration/install-namespace.integration.test.d.ts.map +1 -0
  293. package/dist/tests/integration/install-namespace.integration.test.js +414 -0
  294. package/dist/tests/integration/install-namespace.integration.test.js.map +1 -0
  295. package/dist/tests/performance/search-performance.test.js +9 -3
  296. package/dist/tests/performance/search-performance.test.js.map +1 -1
  297. package/dist/tests/tools.test.js +5 -5
  298. package/dist/tests/tools.test.js.map +1 -1
  299. package/dist/tests/unit/apply-namespace-rename.test.d.ts +24 -0
  300. package/dist/tests/unit/apply-namespace-rename.test.d.ts.map +1 -0
  301. package/dist/tests/unit/apply-namespace-rename.test.js +205 -0
  302. package/dist/tests/unit/apply-namespace-rename.test.js.map +1 -0
  303. package/dist/tests/unit/apply-recommended-edit.test.d.ts +28 -0
  304. package/dist/tests/unit/apply-recommended-edit.test.d.ts.map +1 -0
  305. package/dist/tests/unit/apply-recommended-edit.test.js +229 -0
  306. package/dist/tests/unit/apply-recommended-edit.test.js.map +1 -0
  307. package/dist/tests/unit/audit-history.test.d.ts +11 -0
  308. package/dist/tests/unit/audit-history.test.d.ts.map +1 -0
  309. package/dist/tests/unit/audit-history.test.js +183 -0
  310. package/dist/tests/unit/audit-history.test.js.map +1 -0
  311. package/dist/tests/unit/audit-report-writer.test.d.ts +7 -0
  312. package/dist/tests/unit/audit-report-writer.test.d.ts.map +1 -0
  313. package/dist/tests/unit/audit-report-writer.test.js +249 -0
  314. package/dist/tests/unit/audit-report-writer.test.js.map +1 -0
  315. package/dist/tests/unit/audit-tool-dispatch.test.d.ts +17 -0
  316. package/dist/tests/unit/audit-tool-dispatch.test.d.ts.map +1 -0
  317. package/dist/tests/unit/audit-tool-dispatch.test.js +133 -0
  318. package/dist/tests/unit/audit-tool-dispatch.test.js.map +1 -0
  319. package/dist/tests/unit/collision-detector.semantic.test.d.ts +12 -0
  320. package/dist/tests/unit/collision-detector.semantic.test.d.ts.map +1 -0
  321. package/dist/tests/unit/collision-detector.semantic.test.js +281 -0
  322. package/dist/tests/unit/collision-detector.semantic.test.js.map +1 -0
  323. package/dist/tests/unit/collision-detector.test.d.ts +8 -0
  324. package/dist/tests/unit/collision-detector.test.d.ts.map +1 -0
  325. package/dist/tests/unit/collision-detector.test.js +266 -0
  326. package/dist/tests/unit/collision-detector.test.js.map +1 -0
  327. package/dist/tests/unit/edit-applier.test.d.ts +17 -0
  328. package/dist/tests/unit/edit-applier.test.d.ts.map +1 -0
  329. package/dist/tests/unit/edit-applier.test.js +165 -0
  330. package/dist/tests/unit/edit-applier.test.js.map +1 -0
  331. package/dist/tests/unit/edit-suggester.fixtures.d.ts +38 -0
  332. package/dist/tests/unit/edit-suggester.fixtures.d.ts.map +1 -0
  333. package/dist/tests/unit/edit-suggester.fixtures.js +84 -0
  334. package/dist/tests/unit/edit-suggester.fixtures.js.map +1 -0
  335. package/dist/tests/unit/edit-suggester.test.d.ts +17 -0
  336. package/dist/tests/unit/edit-suggester.test.d.ts.map +1 -0
  337. package/dist/tests/unit/edit-suggester.test.js +356 -0
  338. package/dist/tests/unit/edit-suggester.test.js.map +1 -0
  339. package/dist/tests/unit/framework-adapter.test.d.ts +30 -0
  340. package/dist/tests/unit/framework-adapter.test.d.ts.map +1 -0
  341. package/dist/tests/unit/framework-adapter.test.js +221 -0
  342. package/dist/tests/unit/framework-adapter.test.js.map +1 -0
  343. package/dist/tests/unit/install-preflight.test.d.ts +17 -0
  344. package/dist/tests/unit/install-preflight.test.d.ts.map +1 -0
  345. package/dist/tests/unit/install-preflight.test.js +270 -0
  346. package/dist/tests/unit/install-preflight.test.js.map +1 -0
  347. package/dist/tests/unit/install.backup-gc.test.d.ts +18 -0
  348. package/dist/tests/unit/install.backup-gc.test.d.ts.map +1 -0
  349. package/dist/tests/unit/install.backup-gc.test.js +177 -0
  350. package/dist/tests/unit/install.backup-gc.test.js.map +1 -0
  351. package/dist/tests/unit/install.ledger-replay.test.d.ts +12 -0
  352. package/dist/tests/unit/install.ledger-replay.test.d.ts.map +1 -0
  353. package/dist/tests/unit/install.ledger-replay.test.js +98 -0
  354. package/dist/tests/unit/install.ledger-replay.test.js.map +1 -0
  355. package/dist/tests/unit/local-inventory.test.d.ts +8 -0
  356. package/dist/tests/unit/local-inventory.test.d.ts.map +1 -0
  357. package/dist/tests/unit/local-inventory.test.js +165 -0
  358. package/dist/tests/unit/local-inventory.test.js.map +1 -0
  359. package/dist/tests/unit/namespace-audit-telemetry.test.d.ts +10 -0
  360. package/dist/tests/unit/namespace-audit-telemetry.test.d.ts.map +1 -0
  361. package/dist/tests/unit/namespace-audit-telemetry.test.js +215 -0
  362. package/dist/tests/unit/namespace-audit-telemetry.test.js.map +1 -0
  363. package/dist/tests/unit/namespace-overrides.test.d.ts +18 -0
  364. package/dist/tests/unit/namespace-overrides.test.d.ts.map +1 -0
  365. package/dist/tests/unit/namespace-overrides.test.js +210 -0
  366. package/dist/tests/unit/namespace-overrides.test.js.map +1 -0
  367. package/dist/tests/unit/rename-engine.test.d.ts +26 -0
  368. package/dist/tests/unit/rename-engine.test.d.ts.map +1 -0
  369. package/dist/tests/unit/rename-engine.test.js +367 -0
  370. package/dist/tests/unit/rename-engine.test.js.map +1 -0
  371. package/dist/tests/unit/skill-inventory-audit.test.d.ts +20 -0
  372. package/dist/tests/unit/skill-inventory-audit.test.d.ts.map +1 -0
  373. package/dist/tests/unit/skill-inventory-audit.test.js +299 -0
  374. package/dist/tests/unit/skill-inventory-audit.test.js.map +1 -0
  375. package/dist/tests/unit/skill-pack-audit.helpers.test.d.ts +11 -0
  376. package/dist/tests/unit/skill-pack-audit.helpers.test.d.ts.map +1 -0
  377. package/dist/tests/unit/skill-pack-audit.helpers.test.js +61 -0
  378. package/dist/tests/unit/skill-pack-audit.helpers.test.js.map +1 -0
  379. package/dist/tests/unit/skill-pack-audit.test.js +1 -1
  380. package/dist/tests/unit/skill-pack-audit.test.js.map +1 -1
  381. package/dist/tests/unit/suggestion-chain.test.d.ts +17 -0
  382. package/dist/tests/unit/suggestion-chain.test.d.ts.map +1 -0
  383. package/dist/tests/unit/suggestion-chain.test.js +191 -0
  384. package/dist/tests/unit/suggestion-chain.test.js.map +1 -0
  385. package/dist/tests/webhooks/standalone-shutdown.test.d.ts +12 -0
  386. package/dist/tests/webhooks/standalone-shutdown.test.d.ts.map +1 -0
  387. package/dist/tests/webhooks/standalone-shutdown.test.js +91 -0
  388. package/dist/tests/webhooks/standalone-shutdown.test.js.map +1 -0
  389. package/package.json +17 -4
  390. package/server.json +3 -3
  391. package/src/assets/skills/skillsmith/SKILL.md +2 -2
@@ -0,0 +1,356 @@
1
+ /**
2
+ * @fileoverview Unit tests for SMI-4589 Wave 3 — edit-suggester core (10 cases).
3
+ * @module @skillsmith/mcp-server/tests/unit/edit-suggester
4
+ *
5
+ * Covers the 10 cases enumerated in
6
+ * `docs/internal/implementation/smi-4589-edit-suggester.md` §Tests.
7
+ * Apply-path tests (registry rejection + apply success/stale-before)
8
+ * live in `edit-applier.test.ts` to keep both files under the 500-LOC
9
+ * pre-commit gate.
10
+ *
11
+ * Per-template gate (ratified 2026-05-01): only `add_domain_qualifier`
12
+ * (4.10/5) ships in v1. Cases 2-3 assert the failing templates produce
13
+ * NO `RecommendedEdit` from `runEditSuggester` — they're absent from
14
+ * Wave 3 output entirely per plan R-4/R-8.
15
+ */
16
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
17
+ import * as fs from 'node:fs';
18
+ import * as os from 'node:os';
19
+ import * as path from 'node:path';
20
+ import { runEditSuggester } from '../../src/audit/edit-suggester.js';
21
+ import { makeAuditResult, makeEntry, makeSemanticFlag, writeSkillMd, } from './edit-suggester.fixtures.js';
22
+ let TEST_HOME;
23
+ let ORIGINAL_HOME;
24
+ beforeEach(() => {
25
+ TEST_HOME = fs.mkdtempSync(path.join(os.tmpdir(), 'skillsmith-edit-suggester-'));
26
+ ORIGINAL_HOME = process.env['HOME'];
27
+ process.env['HOME'] = TEST_HOME;
28
+ });
29
+ afterEach(() => {
30
+ if (ORIGINAL_HOME !== undefined) {
31
+ process.env['HOME'] = ORIGINAL_HOME;
32
+ }
33
+ else {
34
+ delete process.env['HOME'];
35
+ }
36
+ if (TEST_HOME && fs.existsSync(TEST_HOME)) {
37
+ fs.rmSync(TEST_HOME, { recursive: true, force: true });
38
+ }
39
+ });
40
+ describe('runEditSuggester — case 1: add_domain_qualifier fires for asymmetric tags', () => {
41
+ it('emits a RecommendedEdit with `for <tag> tasks` injected after the trigger verb', async () => {
42
+ const fileA = writeSkillMd(TEST_HOME, {
43
+ identifier: 'release-tools',
44
+ description: 'Use when deploying to production. Handles release notes.',
45
+ tag: 'anthropic',
46
+ });
47
+ const fileB = writeSkillMd(TEST_HOME, {
48
+ identifier: 'release-helper',
49
+ description: 'Use when deploying for the release pipeline. Handles changelogs.',
50
+ tag: 'community',
51
+ });
52
+ const entryA = makeEntry({
53
+ source_path: fileA,
54
+ identifier: 'release-tools',
55
+ description: 'Use when deploying to production. Handles release notes.',
56
+ tag: 'anthropic',
57
+ });
58
+ const entryB = makeEntry({
59
+ source_path: fileB,
60
+ identifier: 'release-helper',
61
+ description: 'Use when deploying for the release pipeline. Handles changelogs.',
62
+ tag: 'community',
63
+ });
64
+ const result = makeAuditResult([
65
+ makeSemanticFlag({ collisionId: 'coll-01', entryA, entryB, cosineScore: 0.82 }),
66
+ ]);
67
+ const edits = await runEditSuggester(result);
68
+ expect(edits).toHaveLength(1);
69
+ const edit = edits[0];
70
+ expect(edit.pattern).toBe('add_domain_qualifier');
71
+ expect(edit.category).toBe('description_overlap');
72
+ expect(edit.applyMode).toBe('apply_with_confirmation');
73
+ expect(edit.applyAction).toBe('recommended_edit');
74
+ expect(edit.after).toContain('for anthropic tasks');
75
+ expect(edit.before).not.toContain('for anthropic tasks');
76
+ expect(edit.otherEntry.identifier).toBe('release-helper');
77
+ expect(edit.collisionId).toBe('coll-01');
78
+ expect(edit.rationale).toContain('cosine 0.82');
79
+ });
80
+ });
81
+ describe('runEditSuggester — case 2: narrow_scope-shape collision emits NO edit (template not registered)', () => {
82
+ it('returns empty when no entry has a unique tag', async () => {
83
+ const fileA = writeSkillMd(TEST_HOME, {
84
+ identifier: 'deployer-a',
85
+ description: 'Use when deploying releases.',
86
+ tag: 'shared',
87
+ });
88
+ const fileB = writeSkillMd(TEST_HOME, {
89
+ identifier: 'deployer-b',
90
+ description: 'Use when deploying releases.',
91
+ tag: 'shared',
92
+ });
93
+ const entryA = makeEntry({
94
+ source_path: fileA,
95
+ identifier: 'deployer-a',
96
+ description: 'Use when deploying releases.',
97
+ tag: 'shared',
98
+ });
99
+ const entryB = makeEntry({
100
+ source_path: fileB,
101
+ identifier: 'deployer-b',
102
+ description: 'Use when deploying releases.',
103
+ tag: 'shared',
104
+ });
105
+ const result = makeAuditResult([
106
+ makeSemanticFlag({ collisionId: 'coll-narrow-shape', entryA, entryB }),
107
+ ]);
108
+ const edits = await runEditSuggester(result);
109
+ expect(edits).toHaveLength(0);
110
+ });
111
+ });
112
+ describe('runEditSuggester — case 3: reword_trigger_verb-shape (CLAUDE.md) emits NO edit', () => {
113
+ it('returns empty for claude_md_rule entries (template not registered in v1)', async () => {
114
+ const claudeMdPath = path.join(TEST_HOME, 'CLAUDE.md');
115
+ fs.writeFileSync(claudeMdPath, '## Trigger phrases\n- Use when deploying\n- Use when deploying\n', 'utf-8');
116
+ const entryA = {
117
+ kind: 'claude_md_rule',
118
+ source_path: claudeMdPath,
119
+ identifier: 'rule-a',
120
+ triggerSurface: ['Use when deploying'],
121
+ meta: { description: 'Use when deploying' },
122
+ };
123
+ const entryB = {
124
+ kind: 'claude_md_rule',
125
+ source_path: claudeMdPath,
126
+ identifier: 'rule-b',
127
+ triggerSurface: ['Use when deploying'],
128
+ meta: { description: 'Use when deploying' },
129
+ };
130
+ const result = makeAuditResult([
131
+ makeSemanticFlag({ collisionId: 'coll-claude-md', entryA, entryB }),
132
+ ]);
133
+ const edits = await runEditSuggester(result);
134
+ expect(edits).toHaveLength(0);
135
+ });
136
+ });
137
+ describe('runEditSuggester — case 4: flag matching no template skipped, others still produce edits', () => {
138
+ it('isolates per-flag dispatch — non-matching flag does not poison matching flag', async () => {
139
+ const fileA = writeSkillMd(TEST_HOME, {
140
+ identifier: 'release-tools',
141
+ description: 'Use when deploying to production.',
142
+ tag: 'anthropic',
143
+ });
144
+ const fileB = writeSkillMd(TEST_HOME, {
145
+ identifier: 'release-helper',
146
+ description: 'Use when deploying for the release pipeline.',
147
+ tag: 'community',
148
+ });
149
+ const entryA = makeEntry({
150
+ source_path: fileA,
151
+ identifier: 'release-tools',
152
+ description: 'Use when deploying to production.',
153
+ tag: 'anthropic',
154
+ });
155
+ const entryB = makeEntry({
156
+ source_path: fileB,
157
+ identifier: 'release-helper',
158
+ description: 'Use when deploying for the release pipeline.',
159
+ tag: 'community',
160
+ });
161
+ const entryC = makeEntry({
162
+ source_path: fileA,
163
+ identifier: 'shared-c',
164
+ description: 'Use when deploying releases.',
165
+ tag: 'shared',
166
+ });
167
+ const entryD = makeEntry({
168
+ source_path: fileB,
169
+ identifier: 'shared-d',
170
+ description: 'Use when deploying releases.',
171
+ tag: 'shared',
172
+ });
173
+ const result = makeAuditResult([
174
+ makeSemanticFlag({ collisionId: 'coll-match', entryA, entryB }),
175
+ makeSemanticFlag({ collisionId: 'coll-skip', entryA: entryC, entryB: entryD }),
176
+ ]);
177
+ const edits = await runEditSuggester(result);
178
+ expect(edits).toHaveLength(1);
179
+ expect(edits[0].collisionId).toBe('coll-match');
180
+ });
181
+ });
182
+ describe('runEditSuggester — case 5: line-range extraction matches file content byte-for-byte', () => {
183
+ it("`before` snippet equals fileLines.slice(start-1, end).join('\\n')", async () => {
184
+ const fileA = writeSkillMd(TEST_HOME, {
185
+ identifier: 'release-tools',
186
+ description: 'Use when deploying to production.',
187
+ tag: 'anthropic',
188
+ });
189
+ const fileB = writeSkillMd(TEST_HOME, {
190
+ identifier: 'release-helper',
191
+ description: 'Use when deploying for the release pipeline.',
192
+ tag: 'community',
193
+ });
194
+ const entryA = makeEntry({
195
+ source_path: fileA,
196
+ identifier: 'release-tools',
197
+ description: 'Use when deploying to production.',
198
+ tag: 'anthropic',
199
+ });
200
+ const entryB = makeEntry({
201
+ source_path: fileB,
202
+ identifier: 'release-helper',
203
+ description: 'Use when deploying for the release pipeline.',
204
+ tag: 'community',
205
+ });
206
+ const result = makeAuditResult([makeSemanticFlag({ collisionId: 'coll-byte', entryA, entryB })]);
207
+ const edits = await runEditSuggester(result);
208
+ expect(edits).toHaveLength(1);
209
+ const edit = edits[0];
210
+ const fileLines = fs.readFileSync(edit.filePath, 'utf-8').split('\n');
211
+ const startIdx = edit.lineRange.start - 1;
212
+ const endIdx = edit.lineRange.end - 1;
213
+ const reconstructed = fileLines.slice(startIdx, endIdx + 1).join('\n');
214
+ expect(edit.before).toBe(reconstructed);
215
+ });
216
+ });
217
+ describe('runEditSuggester — case 6: multiple flags on the same file produce independent edits', () => {
218
+ it('emits one RecommendedEdit per matching flag, stable in input order', async () => {
219
+ const fileA = writeSkillMd(TEST_HOME, {
220
+ identifier: 'release-tools',
221
+ description: 'Use when deploying to production.',
222
+ tag: 'anthropic',
223
+ });
224
+ const fileB = writeSkillMd(TEST_HOME, {
225
+ identifier: 'release-helper-1',
226
+ description: 'Use when deploying for stage one.',
227
+ tag: 'community',
228
+ });
229
+ const fileC = writeSkillMd(TEST_HOME, {
230
+ identifier: 'release-helper-2',
231
+ description: 'Use when deploying for stage two.',
232
+ tag: 'enterprise',
233
+ });
234
+ const entryA = makeEntry({
235
+ source_path: fileA,
236
+ identifier: 'release-tools',
237
+ description: 'Use when deploying to production.',
238
+ tag: 'anthropic',
239
+ });
240
+ const entryB = makeEntry({
241
+ source_path: fileB,
242
+ identifier: 'release-helper-1',
243
+ description: 'Use when deploying for stage one.',
244
+ tag: 'community',
245
+ });
246
+ const entryC = makeEntry({
247
+ source_path: fileC,
248
+ identifier: 'release-helper-2',
249
+ description: 'Use when deploying for stage two.',
250
+ tag: 'enterprise',
251
+ });
252
+ const result = makeAuditResult([
253
+ makeSemanticFlag({ collisionId: 'coll-multi-1', entryA, entryB }),
254
+ makeSemanticFlag({ collisionId: 'coll-multi-2', entryA, entryB: entryC }),
255
+ ]);
256
+ const edits = await runEditSuggester(result);
257
+ expect(edits.length).toBeGreaterThanOrEqual(2);
258
+ expect(edits[0].collisionId).toBe('coll-multi-1');
259
+ expect(edits[1].collisionId).toBe('coll-multi-2');
260
+ });
261
+ });
262
+ describe('runEditSuggester — case 7: applyMode is apply_with_confirmation for shipped template', () => {
263
+ it("returned edit's applyMode equals 'apply_with_confirmation'", async () => {
264
+ const fileA = writeSkillMd(TEST_HOME, {
265
+ identifier: 'release-tools',
266
+ description: 'Use when deploying to production.',
267
+ tag: 'anthropic',
268
+ });
269
+ const fileB = writeSkillMd(TEST_HOME, {
270
+ identifier: 'release-helper',
271
+ description: 'Use when deploying releases.',
272
+ tag: 'community',
273
+ });
274
+ const entryA = makeEntry({
275
+ source_path: fileA,
276
+ identifier: 'release-tools',
277
+ description: 'Use when deploying to production.',
278
+ tag: 'anthropic',
279
+ });
280
+ const entryB = makeEntry({
281
+ source_path: fileB,
282
+ identifier: 'release-helper',
283
+ description: 'Use when deploying releases.',
284
+ tag: 'community',
285
+ });
286
+ const result = makeAuditResult([makeSemanticFlag({ collisionId: 'coll-mode', entryA, entryB })]);
287
+ const edits = await runEditSuggester(result);
288
+ expect(edits).toHaveLength(1);
289
+ expect(edits[0].applyMode).toBe('apply_with_confirmation');
290
+ });
291
+ });
292
+ describe('runEditSuggester — case 8: otherEntry cross-references the partner', () => {
293
+ it('otherEntry.identifier matches the partner in the original SemanticCollisionFlag', async () => {
294
+ const fileA = writeSkillMd(TEST_HOME, {
295
+ identifier: 'tool-alpha',
296
+ description: 'Use when running alpha workflows.',
297
+ tag: 'alpha-only',
298
+ });
299
+ const fileB = writeSkillMd(TEST_HOME, {
300
+ identifier: 'tool-beta',
301
+ description: 'Use when running beta workflows.',
302
+ tag: 'beta-only',
303
+ });
304
+ const entryA = makeEntry({
305
+ source_path: fileA,
306
+ identifier: 'tool-alpha',
307
+ description: 'Use when running alpha workflows.',
308
+ tag: 'alpha-only',
309
+ });
310
+ const entryB = makeEntry({
311
+ source_path: fileB,
312
+ identifier: 'tool-beta',
313
+ description: 'Use when running beta workflows.',
314
+ tag: 'beta-only',
315
+ });
316
+ const result = makeAuditResult([
317
+ makeSemanticFlag({ collisionId: 'coll-other', entryA, entryB }),
318
+ ]);
319
+ const edits = await runEditSuggester(result);
320
+ expect(edits).toHaveLength(1);
321
+ const edit = edits[0];
322
+ expect(edit.otherEntry.identifier).toBe('tool-beta');
323
+ expect(edit.otherEntry.sourcePath).toBe(fileB);
324
+ });
325
+ });
326
+ describe('runEditSuggester — case 9: missing file produces no exception, no edit', () => {
327
+ it('soft-warns and skips when source_path does not exist', async () => {
328
+ const missingPath = path.join(TEST_HOME, 'does-not-exist', 'SKILL.md');
329
+ const partnerPath = path.join(TEST_HOME, 'also-missing', 'SKILL.md');
330
+ const entryA = makeEntry({
331
+ source_path: missingPath,
332
+ identifier: 'phantom-a',
333
+ description: 'Use when running phantom tasks.',
334
+ tag: 'phantom',
335
+ });
336
+ const entryB = makeEntry({
337
+ source_path: partnerPath,
338
+ identifier: 'phantom-b',
339
+ description: 'Use when running phantom tasks.',
340
+ tag: 'partner',
341
+ });
342
+ const result = makeAuditResult([
343
+ makeSemanticFlag({ collisionId: 'coll-missing', entryA, entryB }),
344
+ ]);
345
+ const edits = await runEditSuggester(result);
346
+ expect(edits).toHaveLength(0);
347
+ });
348
+ });
349
+ describe('runEditSuggester — case 10: empty semanticCollisions short-circuits', () => {
350
+ it('returns empty array with no I/O', async () => {
351
+ const result = makeAuditResult([]);
352
+ const edits = await runEditSuggester(result);
353
+ expect(edits).toEqual([]);
354
+ });
355
+ });
356
+ //# sourceMappingURL=edit-suggester.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-suggester.test.js","sourceRoot":"","sources":["../../../tests/unit/edit-suggester.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @fileoverview Unit tests for SMI-4590 Wave 4 PR 2/6 — FrameworkAdapter
3
+ * seam + claudeCodeAdapter (v1).
4
+ * @module @skillsmith/mcp-server/tests/unit/framework-adapter
5
+ *
6
+ * Plan: docs/internal/implementation/smi-4590-cli-mcp-framework-adapter.md §5,
7
+ * §Tests §framework-adapter.test.ts.
8
+ *
9
+ * Coverage:
10
+ * 1. `claudeCodeAdapter.name === 'claude-code'` + `describesFiles()` non-empty.
11
+ * 2. `scanPaths()` returns valid `InventoryEntry[]` matching Wave 1's output.
12
+ * 3. `applyAction({kind:'rename', from, to})` performs a raw `fs.rename`.
13
+ * 4. `applyAction({kind:'inline-edit', searchMode:'literal', ...})` mutates
14
+ * the file via Wave 3's applyRecommendedEdit (registered template only).
15
+ * 5. `applyAction({kind:'inline-edit', searchMode:'regex', ...})` throws
16
+ * `namespace.adapter.unsupported_search_mode` and the file is unchanged.
17
+ * 6. Convenience wrapper `applyRename(entry, newName, { auditId })` runs
18
+ * Wave 2's applyRename flow (backup + ledger + rename) for a command file.
19
+ * 7. Convenience wrapper `applyEdit(edit, { auditId })` round-trips through
20
+ * `applyAction` and mutates the file.
21
+ * 8. Conformance: `claudeCodeAdapter` satisfies `FrameworkAdapter` (compile-
22
+ * time guard via the `const adapter: FrameworkAdapter = claudeCodeAdapter`
23
+ * assignment in this file).
24
+ * 9. Inline-edit with missing `auditId` rejects with
25
+ * `namespace.adapter.missing_context`.
26
+ * 10. Inline-edit with non-registered `pattern` rejects with
27
+ * `namespace.adapter.template_not_in_apply_registry`.
28
+ */
29
+ export {};
30
+ //# sourceMappingURL=framework-adapter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework-adapter.test.d.ts","sourceRoot":"","sources":["../../../tests/unit/framework-adapter.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG"}
@@ -0,0 +1,221 @@
1
+ /**
2
+ * @fileoverview Unit tests for SMI-4590 Wave 4 PR 2/6 — FrameworkAdapter
3
+ * seam + claudeCodeAdapter (v1).
4
+ * @module @skillsmith/mcp-server/tests/unit/framework-adapter
5
+ *
6
+ * Plan: docs/internal/implementation/smi-4590-cli-mcp-framework-adapter.md §5,
7
+ * §Tests §framework-adapter.test.ts.
8
+ *
9
+ * Coverage:
10
+ * 1. `claudeCodeAdapter.name === 'claude-code'` + `describesFiles()` non-empty.
11
+ * 2. `scanPaths()` returns valid `InventoryEntry[]` matching Wave 1's output.
12
+ * 3. `applyAction({kind:'rename', from, to})` performs a raw `fs.rename`.
13
+ * 4. `applyAction({kind:'inline-edit', searchMode:'literal', ...})` mutates
14
+ * the file via Wave 3's applyRecommendedEdit (registered template only).
15
+ * 5. `applyAction({kind:'inline-edit', searchMode:'regex', ...})` throws
16
+ * `namespace.adapter.unsupported_search_mode` and the file is unchanged.
17
+ * 6. Convenience wrapper `applyRename(entry, newName, { auditId })` runs
18
+ * Wave 2's applyRename flow (backup + ledger + rename) for a command file.
19
+ * 7. Convenience wrapper `applyEdit(edit, { auditId })` round-trips through
20
+ * `applyAction` and mutates the file.
21
+ * 8. Conformance: `claudeCodeAdapter` satisfies `FrameworkAdapter` (compile-
22
+ * time guard via the `const adapter: FrameworkAdapter = claudeCodeAdapter`
23
+ * assignment in this file).
24
+ * 9. Inline-edit with missing `auditId` rejects with
25
+ * `namespace.adapter.missing_context`.
26
+ * 10. Inline-edit with non-registered `pattern` rejects with
27
+ * `namespace.adapter.template_not_in_apply_registry`.
28
+ */
29
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
30
+ import * as fs from 'node:fs';
31
+ import * as os from 'node:os';
32
+ import * as path from 'node:path';
33
+ import { newAuditId } from '../../src/audit/audit-history.js';
34
+ import { claudeCodeAdapter, FrameworkAdapterError } from '../../src/audit/framework-adapter.js';
35
+ import { writeSkillMd } from './edit-suggester.fixtures.js';
36
+ // Compile-time conformance assertion. If `claudeCodeAdapter` ever drifts
37
+ // out of the `FrameworkAdapter` shape, this assignment will fail to
38
+ // type-check during the build step in CI.
39
+ const _conformance = claudeCodeAdapter;
40
+ void _conformance;
41
+ let TEST_HOME;
42
+ let ORIGINAL_HOME;
43
+ beforeEach(() => {
44
+ TEST_HOME = fs.mkdtempSync(path.join(os.tmpdir(), 'skillsmith-framework-adapter-'));
45
+ ORIGINAL_HOME = process.env['HOME'];
46
+ process.env['HOME'] = TEST_HOME;
47
+ });
48
+ afterEach(() => {
49
+ if (ORIGINAL_HOME !== undefined) {
50
+ process.env['HOME'] = ORIGINAL_HOME;
51
+ }
52
+ else {
53
+ delete process.env['HOME'];
54
+ }
55
+ if (TEST_HOME && fs.existsSync(TEST_HOME)) {
56
+ fs.rmSync(TEST_HOME, { recursive: true, force: true });
57
+ }
58
+ });
59
+ describe('claudeCodeAdapter — identity', () => {
60
+ it('has name "claude-code" and non-empty describesFiles()', () => {
61
+ expect(claudeCodeAdapter.name).toBe('claude-code');
62
+ const files = claudeCodeAdapter.describesFiles();
63
+ expect(files.length).toBeGreaterThan(0);
64
+ expect(files).toContain('~/.claude/skills/*/SKILL.md');
65
+ });
66
+ });
67
+ describe('claudeCodeAdapter.scanPaths', () => {
68
+ it('returns InventoryEntry[] from an empty home (no scan errors)', async () => {
69
+ const entries = await claudeCodeAdapter.scanPaths(TEST_HOME);
70
+ expect(Array.isArray(entries)).toBe(true);
71
+ // Empty .claude/ → no entries; the contract is just "Array of InventoryEntry".
72
+ expect(entries.every((e) => typeof e.identifier === 'string')).toBe(true);
73
+ });
74
+ it('discovers a SKILL.md created on disk and returns it as a kind:"skill" entry', async () => {
75
+ writeSkillMd(TEST_HOME, {
76
+ identifier: 'fixture-skill',
77
+ description: 'Use when deploying to staging',
78
+ });
79
+ const entries = await claudeCodeAdapter.scanPaths(TEST_HOME);
80
+ const skill = entries.find((e) => e.identifier === 'fixture-skill');
81
+ expect(skill).toBeDefined();
82
+ expect(skill?.kind).toBe('skill');
83
+ expect(skill?.source_path).toContain('SKILL.md');
84
+ });
85
+ });
86
+ describe('claudeCodeAdapter.applyAction — rename refusal (force-uses-applyRename)', () => {
87
+ it('refuses bare {kind:"rename"} dispatch with namespace.adapter.missing_context and leaves disk untouched', async () => {
88
+ const fromPath = path.join(TEST_HOME, 'src.md');
89
+ const toPath = path.join(TEST_HOME, 'dst.md');
90
+ fs.writeFileSync(fromPath, 'hello', 'utf-8');
91
+ await expect(claudeCodeAdapter.applyAction({
92
+ kind: 'rename',
93
+ from: fromPath,
94
+ to: toPath,
95
+ })).rejects.toMatchObject({
96
+ kind: 'namespace.adapter.missing_context',
97
+ });
98
+ // Disk untouched: refusing the bare path is the whole point — Wave 2's
99
+ // backup + ledger flow must not be bypassed.
100
+ expect(fs.existsSync(fromPath)).toBe(true);
101
+ expect(fs.existsSync(toPath)).toBe(false);
102
+ expect(fs.readFileSync(fromPath, 'utf-8')).toBe('hello');
103
+ });
104
+ });
105
+ describe('claudeCodeAdapter.applyAction — inline-edit', () => {
106
+ it('rejects searchMode "regex" with namespace.adapter.unsupported_search_mode and leaves the file untouched', async () => {
107
+ const filePath = path.join(TEST_HOME, 'doc.md');
108
+ const original = 'Use when deploying to staging';
109
+ fs.writeFileSync(filePath, original, 'utf-8');
110
+ await expect(claudeCodeAdapter.applyAction({
111
+ kind: 'inline-edit',
112
+ filePath,
113
+ search: 'deploying',
114
+ replace: 'shipping',
115
+ searchMode: 'regex',
116
+ auditId: newAuditId(),
117
+ pattern: 'add_domain_qualifier',
118
+ })).rejects.toMatchObject({
119
+ kind: 'namespace.adapter.unsupported_search_mode',
120
+ });
121
+ // File untouched.
122
+ expect(fs.readFileSync(filePath, 'utf-8')).toBe(original);
123
+ });
124
+ it('rejects literal-mode dispatch missing auditId with namespace.adapter.missing_context', async () => {
125
+ const filePath = path.join(TEST_HOME, 'doc.md');
126
+ fs.writeFileSync(filePath, 'Use when deploying', 'utf-8');
127
+ await expect(claudeCodeAdapter.applyAction({
128
+ kind: 'inline-edit',
129
+ filePath,
130
+ search: 'deploying',
131
+ replace: 'shipping',
132
+ searchMode: 'literal',
133
+ // auditId intentionally omitted
134
+ pattern: 'add_domain_qualifier',
135
+ })).rejects.toBeInstanceOf(FrameworkAdapterError);
136
+ });
137
+ it('rejects literal-mode dispatch with a non-registered pattern with namespace.adapter.template_not_in_apply_registry', async () => {
138
+ const filePath = path.join(TEST_HOME, 'doc.md');
139
+ fs.writeFileSync(filePath, 'Use when deploying', 'utf-8');
140
+ await expect(claudeCodeAdapter.applyAction({
141
+ kind: 'inline-edit',
142
+ filePath,
143
+ search: 'deploying',
144
+ replace: 'shipping',
145
+ searchMode: 'literal',
146
+ auditId: newAuditId(),
147
+ // narrow_scope is NOT in APPLY_TEMPLATE_REGISTRY in v1.
148
+ pattern: 'narrow_scope',
149
+ })).rejects.toMatchObject({
150
+ kind: 'namespace.adapter.template_not_in_apply_registry',
151
+ });
152
+ });
153
+ });
154
+ describe('claudeCodeAdapter.applyEdit — convenience wrapper round-trip', () => {
155
+ it('round-trips through applyAction and mutates the file (registered template)', async () => {
156
+ // Build a SKILL.md whose description contains the literal we want
157
+ // to edit. The applier requires byte-for-byte stale-before match.
158
+ const skillPath = writeSkillMd(TEST_HOME, {
159
+ identifier: 'roundtrip-fixture',
160
+ description: 'Use when deploying',
161
+ });
162
+ const original = fs.readFileSync(skillPath, 'utf-8');
163
+ expect(original).toContain('Use when deploying');
164
+ const auditId = newAuditId();
165
+ const edit = {
166
+ // The collisionId here is opaque — Wave 3 applier only uses it as
167
+ // the ledger FK, not to look up state. The convenience wrapper
168
+ // builds an InlineEditAction with `before` as the literal search.
169
+ collisionId: 'cid-roundtrip-0',
170
+ category: 'description_overlap',
171
+ pattern: 'add_domain_qualifier',
172
+ filePath: skillPath,
173
+ lineRange: { start: 1, end: 1 }, // recomputed by adapter; ignored by inline-edit translator
174
+ before: 'Use when deploying',
175
+ after: 'Use when deploying for release-tools tasks',
176
+ rationale: 'test',
177
+ applyAction: 'recommended_edit',
178
+ applyMode: 'apply_with_confirmation',
179
+ otherEntry: { identifier: 'other', sourcePath: '/tmp/other' },
180
+ };
181
+ expect(claudeCodeAdapter.applyEdit).toBeDefined();
182
+ await claudeCodeAdapter.applyEdit?.(edit, { auditId });
183
+ const updated = fs.readFileSync(skillPath, 'utf-8');
184
+ expect(updated).toContain('Use when deploying for release-tools tasks');
185
+ expect(updated).not.toBe(original);
186
+ });
187
+ });
188
+ describe('claudeCodeAdapter.applyRename — convenience wrapper for command files', () => {
189
+ it('renames a ~/.claude/commands/<name>.md via Wave 2 applyRename + ledger', async () => {
190
+ // Stage a command file at ~/.claude/commands/foo.md.
191
+ const commandsDir = path.join(TEST_HOME, '.claude', 'commands');
192
+ fs.mkdirSync(commandsDir, { recursive: true });
193
+ const fromPath = path.join(commandsDir, 'foo.md');
194
+ fs.writeFileSync(fromPath, '# /foo\n', 'utf-8');
195
+ const entry = {
196
+ kind: 'command',
197
+ source_path: fromPath,
198
+ identifier: 'foo',
199
+ triggerSurface: ['/foo'],
200
+ };
201
+ expect(claudeCodeAdapter.applyRename).toBeDefined();
202
+ await claudeCodeAdapter.applyRename?.(entry, 'mine-foo', {
203
+ auditId: newAuditId(),
204
+ });
205
+ const targetPath = path.join(commandsDir, 'mine-foo.md');
206
+ expect(fs.existsSync(fromPath)).toBe(false);
207
+ expect(fs.existsSync(targetPath)).toBe(true);
208
+ });
209
+ it('rejects rename of a claude_md_rule entry with namespace.adapter.unsupported_action', async () => {
210
+ const entry = {
211
+ kind: 'claude_md_rule',
212
+ source_path: path.join(TEST_HOME, '.claude', 'CLAUDE.md'),
213
+ identifier: 'rule-hash-stub',
214
+ triggerSurface: ['use when deploying'],
215
+ };
216
+ await expect(claudeCodeAdapter.applyRename?.(entry, 'whatever', {
217
+ auditId: newAuditId(),
218
+ })).rejects.toBeInstanceOf(FrameworkAdapterError);
219
+ });
220
+ });
221
+ //# sourceMappingURL=framework-adapter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework-adapter.test.js","sourceRoot":"","sources":["../../../tests/unit/framework-adapter.test.ts"],"names":[],"mappings":"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"}