@skillsmith/mcp-server 0.4.13 → 0.5.1

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 (407) hide show
  1. package/CHANGELOG.md +37 -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 +34 -2
  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/compare.types.js +1 -1
  176. package/dist/src/tools/compare.types.js.map +1 -1
  177. package/dist/src/tools/compliance-tools.service.test.js +6 -4
  178. package/dist/src/tools/compliance-tools.service.test.js.map +1 -1
  179. package/dist/src/tools/get-skill.d.ts.map +1 -1
  180. package/dist/src/tools/get-skill.js +1 -1
  181. package/dist/src/tools/get-skill.js.map +1 -1
  182. package/dist/src/tools/install.backup-gc.d.ts +61 -0
  183. package/dist/src/tools/install.backup-gc.d.ts.map +1 -0
  184. package/dist/src/tools/install.backup-gc.js +166 -0
  185. package/dist/src/tools/install.backup-gc.js.map +1 -0
  186. package/dist/src/tools/install.conflict-helpers.d.ts +29 -2
  187. package/dist/src/tools/install.conflict-helpers.d.ts.map +1 -1
  188. package/dist/src/tools/install.conflict-helpers.js +37 -4
  189. package/dist/src/tools/install.conflict-helpers.js.map +1 -1
  190. package/dist/src/tools/install.d.ts +15 -1
  191. package/dist/src/tools/install.d.ts.map +1 -1
  192. package/dist/src/tools/install.js +168 -8
  193. package/dist/src/tools/install.js.map +1 -1
  194. package/dist/src/tools/install.ledger-replay.d.ts +52 -0
  195. package/dist/src/tools/install.ledger-replay.d.ts.map +1 -0
  196. package/dist/src/tools/install.ledger-replay.js +88 -0
  197. package/dist/src/tools/install.ledger-replay.js.map +1 -0
  198. package/dist/src/tools/install.namespace-gate.d.ts +68 -0
  199. package/dist/src/tools/install.namespace-gate.d.ts.map +1 -0
  200. package/dist/src/tools/install.namespace-gate.js +129 -0
  201. package/dist/src/tools/install.namespace-gate.js.map +1 -0
  202. package/dist/src/tools/install.test.js +136 -1
  203. package/dist/src/tools/install.test.js.map +1 -1
  204. package/dist/src/tools/install.tool.d.ts +17 -0
  205. package/dist/src/tools/install.tool.d.ts.map +1 -1
  206. package/dist/src/tools/install.tool.js +19 -1
  207. package/dist/src/tools/install.tool.js.map +1 -1
  208. package/dist/src/tools/install.types.d.ts +35 -1
  209. package/dist/src/tools/install.types.d.ts.map +1 -1
  210. package/dist/src/tools/install.types.js +24 -2
  211. package/dist/src/tools/install.types.js.map +1 -1
  212. package/dist/src/tools/namespace-audit/telemetry.d.ts +80 -0
  213. package/dist/src/tools/namespace-audit/telemetry.d.ts.map +1 -0
  214. package/dist/src/tools/namespace-audit/telemetry.js +129 -0
  215. package/dist/src/tools/namespace-audit/telemetry.js.map +1 -0
  216. package/dist/src/tools/outdated.test.js +2 -2
  217. package/dist/src/tools/outdated.test.js.map +1 -1
  218. package/dist/src/tools/publish-private.test.js +2 -2
  219. package/dist/src/tools/publish-private.test.js.map +1 -1
  220. package/dist/src/tools/recommend.types.d.ts +2 -2
  221. package/dist/src/tools/recommend.types.js +1 -1
  222. package/dist/src/tools/recommend.types.js.map +1 -1
  223. package/dist/src/tools/search.d.ts +2 -2
  224. package/dist/src/tools/search.d.ts.map +1 -1
  225. package/dist/src/tools/search.js +3 -3
  226. package/dist/src/tools/search.js.map +1 -1
  227. package/dist/src/tools/skill-audit.test.js +2 -2
  228. package/dist/src/tools/skill-audit.test.js.map +1 -1
  229. package/dist/src/tools/skill-diff.d.ts +1 -1
  230. package/dist/src/tools/skill-inventory-audit.d.ts +67 -0
  231. package/dist/src/tools/skill-inventory-audit.d.ts.map +1 -0
  232. package/dist/src/tools/skill-inventory-audit.js +112 -0
  233. package/dist/src/tools/skill-inventory-audit.js.map +1 -0
  234. package/dist/src/tools/skill-inventory-audit.types.d.ts +67 -0
  235. package/dist/src/tools/skill-inventory-audit.types.d.ts.map +1 -0
  236. package/dist/src/tools/skill-inventory-audit.types.js +14 -0
  237. package/dist/src/tools/skill-inventory-audit.types.js.map +1 -0
  238. package/dist/src/tools/skill-pack-audit.d.ts.map +1 -1
  239. package/dist/src/tools/skill-pack-audit.helpers.d.ts.map +1 -1
  240. package/dist/src/tools/skill-pack-audit.helpers.js +15 -2
  241. package/dist/src/tools/skill-pack-audit.helpers.js.map +1 -1
  242. package/dist/src/tools/skill-pack-audit.js +15 -1
  243. package/dist/src/tools/skill-pack-audit.js.map +1 -1
  244. package/dist/src/tools/skill-rescan.d.ts.map +1 -1
  245. package/dist/src/tools/skill-rescan.js +4 -2
  246. package/dist/src/tools/skill-rescan.js.map +1 -1
  247. package/dist/src/tools/suggest.d.ts +2 -2
  248. package/dist/src/tools/uninstall.d.ts +1 -1
  249. package/dist/src/tools/uninstall.d.ts.map +1 -1
  250. package/dist/src/tools/uninstall.js +17 -3
  251. package/dist/src/tools/uninstall.js.map +1 -1
  252. package/dist/src/tools/validate.types.d.ts +10 -1
  253. package/dist/src/tools/validate.types.d.ts.map +1 -1
  254. package/dist/src/tools/validate.types.js +11 -2
  255. package/dist/src/tools/validate.types.js.map +1 -1
  256. package/dist/src/utils/installed-skills.d.ts.map +1 -1
  257. package/dist/src/utils/installed-skills.js +8 -6
  258. package/dist/src/utils/installed-skills.js.map +1 -1
  259. package/dist/src/utils/local-inventory.d.ts +29 -0
  260. package/dist/src/utils/local-inventory.d.ts.map +1 -0
  261. package/dist/src/utils/local-inventory.helpers.d.ts +96 -0
  262. package/dist/src/utils/local-inventory.helpers.d.ts.map +1 -0
  263. package/dist/src/utils/local-inventory.helpers.js +279 -0
  264. package/dist/src/utils/local-inventory.helpers.js.map +1 -0
  265. package/dist/src/utils/local-inventory.js +202 -0
  266. package/dist/src/utils/local-inventory.js.map +1 -0
  267. package/dist/src/utils/local-inventory.types.d.ts +100 -0
  268. package/dist/src/utils/local-inventory.types.d.ts.map +1 -0
  269. package/dist/src/utils/local-inventory.types.js +9 -0
  270. package/dist/src/utils/local-inventory.types.js.map +1 -0
  271. package/dist/src/webhooks/stripe-webhook-endpoint.d.ts +12 -0
  272. package/dist/src/webhooks/stripe-webhook-endpoint.d.ts.map +1 -1
  273. package/dist/src/webhooks/stripe-webhook-endpoint.js +30 -9
  274. package/dist/src/webhooks/stripe-webhook-endpoint.js.map +1 -1
  275. package/dist/src/webhooks/webhook-endpoint.d.ts +13 -0
  276. package/dist/src/webhooks/webhook-endpoint.d.ts.map +1 -1
  277. package/dist/src/webhooks/webhook-endpoint.js +31 -9
  278. package/dist/src/webhooks/webhook-endpoint.js.map +1 -1
  279. package/dist/tests/compare.test.js +5 -5
  280. package/dist/tests/compare.test.js.map +1 -1
  281. package/dist/tests/context-async-listeners.test.d.ts +12 -0
  282. package/dist/tests/context-async-listeners.test.d.ts.map +1 -0
  283. package/dist/tests/context-async-listeners.test.js +62 -0
  284. package/dist/tests/context-async-listeners.test.js.map +1 -0
  285. package/dist/tests/e2e/compare.e2e.test.js +9 -3
  286. package/dist/tests/e2e/compare.e2e.test.js.map +1 -1
  287. package/dist/tests/e2e/install-flow.e2e.test.js +9 -3
  288. package/dist/tests/e2e/install-flow.e2e.test.js.map +1 -1
  289. package/dist/tests/e2e/recommend.e2e.test.js +9 -3
  290. package/dist/tests/e2e/recommend.e2e.test.js.map +1 -1
  291. package/dist/tests/e2e/skill-flow.e2e.test.js +17 -5
  292. package/dist/tests/e2e/skill-flow.e2e.test.js.map +1 -1
  293. package/dist/tests/e2e/suggest.e2e.test.js +11 -3
  294. package/dist/tests/e2e/suggest.e2e.test.js.map +1 -1
  295. package/dist/tests/install-assets.test.d.ts +16 -0
  296. package/dist/tests/install-assets.test.d.ts.map +1 -0
  297. package/dist/tests/install-assets.test.js +72 -0
  298. package/dist/tests/install-assets.test.js.map +1 -0
  299. package/dist/tests/integration/audit-roundtrip.test.d.ts +29 -0
  300. package/dist/tests/integration/audit-roundtrip.test.d.ts.map +1 -0
  301. package/dist/tests/integration/audit-roundtrip.test.js +214 -0
  302. package/dist/tests/integration/audit-roundtrip.test.js.map +1 -0
  303. package/dist/tests/integration/install-namespace.integration.test.d.ts +14 -0
  304. package/dist/tests/integration/install-namespace.integration.test.d.ts.map +1 -0
  305. package/dist/tests/integration/install-namespace.integration.test.js +414 -0
  306. package/dist/tests/integration/install-namespace.integration.test.js.map +1 -0
  307. package/dist/tests/performance/search-performance.test.js +9 -3
  308. package/dist/tests/performance/search-performance.test.js.map +1 -1
  309. package/dist/tests/tool-descriptions.test.d.ts +16 -0
  310. package/dist/tests/tool-descriptions.test.d.ts.map +1 -0
  311. package/dist/tests/tool-descriptions.test.js +63 -0
  312. package/dist/tests/tool-descriptions.test.js.map +1 -0
  313. package/dist/tests/tools.test.js +5 -5
  314. package/dist/tests/tools.test.js.map +1 -1
  315. package/dist/tests/unit/apply-namespace-rename.test.d.ts +24 -0
  316. package/dist/tests/unit/apply-namespace-rename.test.d.ts.map +1 -0
  317. package/dist/tests/unit/apply-namespace-rename.test.js +205 -0
  318. package/dist/tests/unit/apply-namespace-rename.test.js.map +1 -0
  319. package/dist/tests/unit/apply-recommended-edit.test.d.ts +28 -0
  320. package/dist/tests/unit/apply-recommended-edit.test.d.ts.map +1 -0
  321. package/dist/tests/unit/apply-recommended-edit.test.js +229 -0
  322. package/dist/tests/unit/apply-recommended-edit.test.js.map +1 -0
  323. package/dist/tests/unit/audit-history.test.d.ts +11 -0
  324. package/dist/tests/unit/audit-history.test.d.ts.map +1 -0
  325. package/dist/tests/unit/audit-history.test.js +183 -0
  326. package/dist/tests/unit/audit-history.test.js.map +1 -0
  327. package/dist/tests/unit/audit-report-writer.test.d.ts +7 -0
  328. package/dist/tests/unit/audit-report-writer.test.d.ts.map +1 -0
  329. package/dist/tests/unit/audit-report-writer.test.js +249 -0
  330. package/dist/tests/unit/audit-report-writer.test.js.map +1 -0
  331. package/dist/tests/unit/audit-tool-dispatch.test.d.ts +17 -0
  332. package/dist/tests/unit/audit-tool-dispatch.test.d.ts.map +1 -0
  333. package/dist/tests/unit/audit-tool-dispatch.test.js +133 -0
  334. package/dist/tests/unit/audit-tool-dispatch.test.js.map +1 -0
  335. package/dist/tests/unit/collision-detector.semantic.test.d.ts +12 -0
  336. package/dist/tests/unit/collision-detector.semantic.test.d.ts.map +1 -0
  337. package/dist/tests/unit/collision-detector.semantic.test.js +281 -0
  338. package/dist/tests/unit/collision-detector.semantic.test.js.map +1 -0
  339. package/dist/tests/unit/collision-detector.test.d.ts +8 -0
  340. package/dist/tests/unit/collision-detector.test.d.ts.map +1 -0
  341. package/dist/tests/unit/collision-detector.test.js +266 -0
  342. package/dist/tests/unit/collision-detector.test.js.map +1 -0
  343. package/dist/tests/unit/edit-applier.test.d.ts +17 -0
  344. package/dist/tests/unit/edit-applier.test.d.ts.map +1 -0
  345. package/dist/tests/unit/edit-applier.test.js +165 -0
  346. package/dist/tests/unit/edit-applier.test.js.map +1 -0
  347. package/dist/tests/unit/edit-suggester.fixtures.d.ts +38 -0
  348. package/dist/tests/unit/edit-suggester.fixtures.d.ts.map +1 -0
  349. package/dist/tests/unit/edit-suggester.fixtures.js +84 -0
  350. package/dist/tests/unit/edit-suggester.fixtures.js.map +1 -0
  351. package/dist/tests/unit/edit-suggester.test.d.ts +17 -0
  352. package/dist/tests/unit/edit-suggester.test.d.ts.map +1 -0
  353. package/dist/tests/unit/edit-suggester.test.js +356 -0
  354. package/dist/tests/unit/edit-suggester.test.js.map +1 -0
  355. package/dist/tests/unit/framework-adapter.test.d.ts +30 -0
  356. package/dist/tests/unit/framework-adapter.test.d.ts.map +1 -0
  357. package/dist/tests/unit/framework-adapter.test.js +221 -0
  358. package/dist/tests/unit/framework-adapter.test.js.map +1 -0
  359. package/dist/tests/unit/install-preflight.test.d.ts +17 -0
  360. package/dist/tests/unit/install-preflight.test.d.ts.map +1 -0
  361. package/dist/tests/unit/install-preflight.test.js +270 -0
  362. package/dist/tests/unit/install-preflight.test.js.map +1 -0
  363. package/dist/tests/unit/install.backup-gc.test.d.ts +18 -0
  364. package/dist/tests/unit/install.backup-gc.test.d.ts.map +1 -0
  365. package/dist/tests/unit/install.backup-gc.test.js +177 -0
  366. package/dist/tests/unit/install.backup-gc.test.js.map +1 -0
  367. package/dist/tests/unit/install.ledger-replay.test.d.ts +12 -0
  368. package/dist/tests/unit/install.ledger-replay.test.d.ts.map +1 -0
  369. package/dist/tests/unit/install.ledger-replay.test.js +98 -0
  370. package/dist/tests/unit/install.ledger-replay.test.js.map +1 -0
  371. package/dist/tests/unit/local-inventory.test.d.ts +8 -0
  372. package/dist/tests/unit/local-inventory.test.d.ts.map +1 -0
  373. package/dist/tests/unit/local-inventory.test.js +165 -0
  374. package/dist/tests/unit/local-inventory.test.js.map +1 -0
  375. package/dist/tests/unit/namespace-audit-telemetry.test.d.ts +10 -0
  376. package/dist/tests/unit/namespace-audit-telemetry.test.d.ts.map +1 -0
  377. package/dist/tests/unit/namespace-audit-telemetry.test.js +215 -0
  378. package/dist/tests/unit/namespace-audit-telemetry.test.js.map +1 -0
  379. package/dist/tests/unit/namespace-overrides.test.d.ts +18 -0
  380. package/dist/tests/unit/namespace-overrides.test.d.ts.map +1 -0
  381. package/dist/tests/unit/namespace-overrides.test.js +210 -0
  382. package/dist/tests/unit/namespace-overrides.test.js.map +1 -0
  383. package/dist/tests/unit/rename-engine.test.d.ts +26 -0
  384. package/dist/tests/unit/rename-engine.test.d.ts.map +1 -0
  385. package/dist/tests/unit/rename-engine.test.js +367 -0
  386. package/dist/tests/unit/rename-engine.test.js.map +1 -0
  387. package/dist/tests/unit/skill-inventory-audit.test.d.ts +20 -0
  388. package/dist/tests/unit/skill-inventory-audit.test.d.ts.map +1 -0
  389. package/dist/tests/unit/skill-inventory-audit.test.js +299 -0
  390. package/dist/tests/unit/skill-inventory-audit.test.js.map +1 -0
  391. package/dist/tests/unit/skill-pack-audit.helpers.test.d.ts +11 -0
  392. package/dist/tests/unit/skill-pack-audit.helpers.test.d.ts.map +1 -0
  393. package/dist/tests/unit/skill-pack-audit.helpers.test.js +61 -0
  394. package/dist/tests/unit/skill-pack-audit.helpers.test.js.map +1 -0
  395. package/dist/tests/unit/skill-pack-audit.test.js +1 -1
  396. package/dist/tests/unit/skill-pack-audit.test.js.map +1 -1
  397. package/dist/tests/unit/suggestion-chain.test.d.ts +17 -0
  398. package/dist/tests/unit/suggestion-chain.test.d.ts.map +1 -0
  399. package/dist/tests/unit/suggestion-chain.test.js +191 -0
  400. package/dist/tests/unit/suggestion-chain.test.js.map +1 -0
  401. package/dist/tests/webhooks/standalone-shutdown.test.d.ts +12 -0
  402. package/dist/tests/webhooks/standalone-shutdown.test.d.ts.map +1 -0
  403. package/dist/tests/webhooks/standalone-shutdown.test.js +91 -0
  404. package/dist/tests/webhooks/standalone-shutdown.test.js.map +1 -0
  405. package/package.json +17 -4
  406. package/server.json +3 -3
  407. package/src/assets/skills/skillsmith/SKILL.md +109 -80
@@ -0,0 +1,82 @@
1
+ /**
2
+ * @fileoverview Markdown audit-report writer for SMI-4587 Wave 1 Step 7/8.
3
+ * @module @skillsmith/mcp-server/audit/audit-report-writer
4
+ *
5
+ * Renders an `InventoryAuditResult` into the markdown report stored at
6
+ * `~/.skillsmith/audits/<auditId>/report.md`. Atomic via tmp-file +
7
+ * `fs.rename` (mirrors `audit-history.ts`).
8
+ *
9
+ * Sections, in order (plan §446):
10
+ * 1. Summary header — auditId, generated-at, totals
11
+ * 2. CLAUDE.md scan caveat — only when any inventory entry is
12
+ * `kind: 'claude_md_rule'` (D-ANTI-1)
13
+ * 3. Exact collisions — each lists involved entries with absolute paths
14
+ * 4. Generic flags — matched tokens, suggested rename if any
15
+ * 5. Semantic collisions — cosine score, overlapping phrases
16
+ * 6. Recommended edits — Wave 3 plumbing; Wave 1 emits a placeholder
17
+ *
18
+ * Wave 2/4 import this writer via `@skillsmith/mcp-server/audit` (Step 9
19
+ * barrel).
20
+ */
21
+ import type { InventoryAuditResult } from './collision-detector.types.js';
22
+ import type { RenameSuggestion } from './rename-engine.types.js';
23
+ import type { RecommendedEdit } from './edit-suggester.types.js';
24
+ export interface AuditReportRenderOptions {
25
+ /**
26
+ * Override the report's "Generated" timestamp. Defaults to a fresh
27
+ * `new Date()` at render time. Tests pin this to keep snapshots
28
+ * deterministic; production callers pass nothing.
29
+ */
30
+ generatedAt?: Date;
31
+ /**
32
+ * Per-collision rename suggestions to render in the "Recommended edits"
33
+ * section (SMI-4588 Wave 2 PR #4 / Step 8). When provided AND non-empty,
34
+ * the writer replaces the Wave 1 placeholder with a table of
35
+ * `currentName → suggested` pairs plus a copy-paste-ready CLI
36
+ * invocation per row. Pass nothing (or an empty array) to keep the
37
+ * Wave 1 placeholder behavior — backward-compatible with existing
38
+ * audit-report consumers.
39
+ *
40
+ * Wave 4 wires this from `runInstallPreflight` /
41
+ * `generateRenameSuggestions` outputs; Wave 2 ships only the
42
+ * rendering surface.
43
+ */
44
+ renameSuggestions?: ReadonlyArray<RenameSuggestion>;
45
+ /**
46
+ * Recommended prose edits to render in the "Recommended Edits"
47
+ * section (SMI-4589 Wave 3). When provided AND non-empty, the writer
48
+ * renders each edit as a `diff` fenced markdown block per plan §2.
49
+ * Pass nothing (or an empty array) to omit the section entirely.
50
+ *
51
+ * Wave 4 wires this from `runEditSuggester` outputs; Wave 3 ships
52
+ * only the rendering surface here. Per the per-template gate
53
+ * ratified 2026-05-01, only `add_domain_qualifier`-pattern edits
54
+ * surface in v1; failing-template edits are absent from
55
+ * `runEditSuggester`'s output entirely.
56
+ */
57
+ recommendedEdits?: ReadonlyArray<RecommendedEdit>;
58
+ }
59
+ export interface AuditReportWriteOptions extends AuditReportRenderOptions {
60
+ /**
61
+ * Per-audit directory (sibling of `result.json`). The writer assumes the
62
+ * directory already exists — `writeAuditHistory` creates it.
63
+ */
64
+ auditDir: string;
65
+ }
66
+ export interface AuditReportWriteResult {
67
+ /** Absolute path to the rendered `report.md`. */
68
+ reportPath: string;
69
+ }
70
+ /**
71
+ * Render an `InventoryAuditResult` into the audit-report markdown body.
72
+ * Pure — no IO. Exposed so tests can inspect the output without round-
73
+ * tripping through the filesystem.
74
+ */
75
+ export declare function renderAuditReport(result: InventoryAuditResult, opts?: AuditReportRenderOptions): string;
76
+ /**
77
+ * Persist the rendered report to `<auditDir>/report.md`. Atomic via
78
+ * tmp-file + `fs.rename`, matching the audit-history writer's contract so
79
+ * concurrent readers never observe a partially-written file.
80
+ */
81
+ export declare function writeAuditReport(result: InventoryAuditResult, opts: AuditReportWriteOptions): Promise<AuditReportWriteResult>;
82
+ //# sourceMappingURL=audit-report-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-report-writer.d.ts","sourceRoot":"","sources":["../../../src/audit/audit-report-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,OAAO,KAAK,EAIV,oBAAoB,EAErB,MAAM,+BAA+B,CAAA;AAEtC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAEhE,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,WAAW,CAAC,EAAE,IAAI,CAAA;IAClB;;;;;;;;;;;;OAYG;IACH,iBAAiB,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAA;IACnD;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAA;CAClD;AAED,MAAM,WAAW,uBAAwB,SAAQ,wBAAwB;IACvE;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,oBAAoB,EAC5B,IAAI,GAAE,wBAA6B,GAClC,MAAM,CAoCR;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,oBAAoB,EAC5B,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,sBAAsB,CAAC,CAYjC"}
@@ -0,0 +1,241 @@
1
+ /**
2
+ * @fileoverview Markdown audit-report writer for SMI-4587 Wave 1 Step 7/8.
3
+ * @module @skillsmith/mcp-server/audit/audit-report-writer
4
+ *
5
+ * Renders an `InventoryAuditResult` into the markdown report stored at
6
+ * `~/.skillsmith/audits/<auditId>/report.md`. Atomic via tmp-file +
7
+ * `fs.rename` (mirrors `audit-history.ts`).
8
+ *
9
+ * Sections, in order (plan §446):
10
+ * 1. Summary header — auditId, generated-at, totals
11
+ * 2. CLAUDE.md scan caveat — only when any inventory entry is
12
+ * `kind: 'claude_md_rule'` (D-ANTI-1)
13
+ * 3. Exact collisions — each lists involved entries with absolute paths
14
+ * 4. Generic flags — matched tokens, suggested rename if any
15
+ * 5. Semantic collisions — cosine score, overlapping phrases
16
+ * 6. Recommended edits — Wave 3 plumbing; Wave 1 emits a placeholder
17
+ *
18
+ * Wave 2/4 import this writer via `@skillsmith/mcp-server/audit` (Step 9
19
+ * barrel).
20
+ */
21
+ import * as fs from 'node:fs/promises';
22
+ import * as path from 'node:path';
23
+ /**
24
+ * Render an `InventoryAuditResult` into the audit-report markdown body.
25
+ * Pure — no IO. Exposed so tests can inspect the output without round-
26
+ * tripping through the filesystem.
27
+ */
28
+ export function renderAuditReport(result, opts = {}) {
29
+ const generatedAt = opts.generatedAt ?? new Date();
30
+ const sections = [];
31
+ sections.push(renderSummaryHeader(result, generatedAt));
32
+ if (containsClaudeMdRule(result)) {
33
+ sections.push(renderClaudeMdCaveat());
34
+ }
35
+ if (result.exactCollisions.length > 0) {
36
+ sections.push(renderExactCollisions(result.exactCollisions));
37
+ }
38
+ if (result.genericFlags.length > 0) {
39
+ sections.push(renderGenericFlags(result.genericFlags));
40
+ }
41
+ if (result.semanticCollisions.length > 0) {
42
+ sections.push(renderSemanticCollisions(result.semanticCollisions));
43
+ }
44
+ sections.push(renderRecommendedEdits(opts.renameSuggestions, result.auditId));
45
+ // SMI-4589 Wave 3: prose-edit suggestions render in their own section
46
+ // immediately after the Wave 2 rename-suggestion section. Empty input
47
+ // omits the section entirely (no placeholder text — keeps the report
48
+ // tight when no semantic collisions fired).
49
+ if (opts.recommendedEdits && opts.recommendedEdits.length > 0) {
50
+ sections.push(renderRecommendedEditsSection(opts.recommendedEdits));
51
+ }
52
+ // Single trailing newline. `trimEnd()` (not `/\n+$/`) is intentional —
53
+ // see SMI-4733: any non-`\n` trailing whitespace that leaks in is
54
+ // acceptable to strip in an ASCII report, and the non-regex form
55
+ // sidesteps polynomial backtracking flagged by CodeQL.
56
+ return sections.join('\n').trimEnd() + '\n';
57
+ }
58
+ /**
59
+ * Persist the rendered report to `<auditDir>/report.md`. Atomic via
60
+ * tmp-file + `fs.rename`, matching the audit-history writer's contract so
61
+ * concurrent readers never observe a partially-written file.
62
+ */
63
+ export async function writeAuditReport(result, opts) {
64
+ const reportPath = path.join(opts.auditDir, 'report.md');
65
+ const tmpPath = `${reportPath}.tmp`;
66
+ await fs.mkdir(opts.auditDir, { recursive: true });
67
+ const body = renderAuditReport(result, {
68
+ generatedAt: opts.generatedAt,
69
+ renameSuggestions: opts.renameSuggestions,
70
+ recommendedEdits: opts.recommendedEdits,
71
+ });
72
+ await fs.writeFile(tmpPath, body, 'utf-8');
73
+ await fs.rename(tmpPath, reportPath);
74
+ return { reportPath };
75
+ }
76
+ // ---------------------------------------------------------------------------
77
+ // Section renderers
78
+ // ---------------------------------------------------------------------------
79
+ function renderSummaryHeader(result, generatedAt) {
80
+ const lines = [];
81
+ lines.push(`# Skillsmith Namespace Audit — ${result.auditId}`);
82
+ lines.push('');
83
+ lines.push(`- Generated: ${generatedAt.toISOString()}`);
84
+ lines.push(`- Total entries scanned: ${result.summary.totalEntries}`);
85
+ lines.push(`- Total flags: ${result.summary.totalFlags}`);
86
+ lines.push(` - Errors (exact collisions): ${result.summary.errorCount}`);
87
+ lines.push(` - Warnings (generic + semantic): ${result.summary.warningCount}`);
88
+ lines.push(`- Audit duration: ${result.summary.durationMs.toFixed(2)}ms`);
89
+ lines.push('');
90
+ return lines.join('\n');
91
+ }
92
+ function renderClaudeMdCaveat() {
93
+ const lines = [];
94
+ lines.push('## CLAUDE.md scan caveat');
95
+ lines.push('');
96
+ lines.push('This audit included trigger phrases extracted from `CLAUDE.md` rules. ');
97
+ lines.push('Phrase extraction is heuristic — false-positives are possible when a ');
98
+ lines.push('rule is phrased imperatively ("when X, do Y") without intending to ');
99
+ lines.push('overlap with a skill trigger. Review collisions involving ');
100
+ lines.push('`claude_md_rule` entries before applying any rename.');
101
+ lines.push('');
102
+ return lines.join('\n');
103
+ }
104
+ function renderExactCollisions(flags) {
105
+ const lines = [];
106
+ lines.push('## Exact collisions');
107
+ lines.push('');
108
+ for (const flag of flags) {
109
+ lines.push(`### \`${flag.identifier}\` (${flag.entries.length} entries)`);
110
+ lines.push('');
111
+ lines.push(`- Severity: **${flag.severity}**`);
112
+ lines.push(`- Collision id: \`${flag.collisionId}\``);
113
+ lines.push(`- Reason: ${flag.reason}`);
114
+ lines.push('- Involved entries:');
115
+ for (const entry of flag.entries) {
116
+ lines.push(` - [${entry.kind}] ${entry.source_path}`);
117
+ }
118
+ lines.push('');
119
+ }
120
+ return lines.join('\n');
121
+ }
122
+ function renderGenericFlags(flags) {
123
+ const lines = [];
124
+ lines.push('## Generic-token flags');
125
+ lines.push('');
126
+ for (const flag of flags) {
127
+ lines.push(`### \`${flag.identifier}\``);
128
+ lines.push('');
129
+ lines.push(`- Severity: **${flag.severity}**`);
130
+ lines.push(`- Collision id: \`${flag.collisionId}\``);
131
+ lines.push(`- Source: ${flag.entry.source_path}`);
132
+ lines.push(`- Matched generic tokens: ${formatTokens(flag.matchedTokens)}`);
133
+ lines.push(`- Reason: ${flag.reason}`);
134
+ lines.push('');
135
+ }
136
+ return lines.join('\n');
137
+ }
138
+ function renderSemanticCollisions(flags) {
139
+ const lines = [];
140
+ lines.push('## Semantic collisions');
141
+ lines.push('');
142
+ for (const flag of flags) {
143
+ lines.push(`### ${describeEntry(flag.entryA)} ↔ ${describeEntry(flag.entryB)}`);
144
+ lines.push('');
145
+ lines.push(`- Severity: **${flag.severity}**`);
146
+ lines.push(`- Collision id: \`${flag.collisionId}\``);
147
+ lines.push(`- Cosine score: ${flag.cosineScore.toFixed(3)}`);
148
+ lines.push(`- Reason: ${flag.reason}`);
149
+ lines.push(`- Entry A: ${flag.entryA.source_path}`);
150
+ lines.push(`- Entry B: ${flag.entryB.source_path}`);
151
+ if (flag.overlappingPhrases.length > 0) {
152
+ lines.push('- Overlapping phrases:');
153
+ for (const pair of flag.overlappingPhrases) {
154
+ lines.push(` - "${pair.phrase1}" ↔ "${pair.phrase2}" (sim ${pair.similarity.toFixed(3)})`);
155
+ }
156
+ }
157
+ lines.push('');
158
+ }
159
+ return lines.join('\n');
160
+ }
161
+ function renderRecommendedEdits(suggestions, auditId) {
162
+ const lines = [];
163
+ lines.push('## Recommended edits');
164
+ lines.push('');
165
+ if (!suggestions || suggestions.length === 0) {
166
+ // Wave 1 placeholder preserved for backward compatibility — no
167
+ // suggestion data was passed in.
168
+ lines.push('_No automated edits suggested in Wave 1._');
169
+ lines.push('');
170
+ return lines.join('\n');
171
+ }
172
+ // Wave 2 PR #4 (Step 8): render a markdown table of rename suggestions
173
+ // with copy-paste-ready CLI invocations. Wave 4 wires the actual CLI;
174
+ // this writer just renders the suggestion text.
175
+ lines.push('| Current name | Suggested rename | Apply action | Apply command |');
176
+ lines.push('|---|---|---|---|');
177
+ for (const suggestion of suggestions) {
178
+ const cmd = `\`sklx audit collisions apply ${auditId} ${suggestion.collisionId}\``;
179
+ lines.push(`| \`${suggestion.currentName}\` | \`${suggestion.suggested}\` | ${suggestion.applyAction} | ${cmd} |`);
180
+ }
181
+ lines.push('');
182
+ for (const suggestion of suggestions) {
183
+ lines.push(`### \`${suggestion.currentName}\` → \`${suggestion.suggested}\``);
184
+ lines.push('');
185
+ lines.push(`- Collision id: \`${suggestion.collisionId}\``);
186
+ lines.push(`- Reason: ${suggestion.reason}`);
187
+ lines.push(`- Source: ${suggestion.entry.source_path}`);
188
+ lines.push('');
189
+ }
190
+ return lines.join('\n');
191
+ }
192
+ /**
193
+ * SMI-4589 Wave 3: render the prose-edit suggestions section. Each edit
194
+ * becomes a markdown block with file/lineRange metadata and a `diff`
195
+ * fenced code block showing the before/after pair with `-`/`+` line
196
+ * prefixes — renders with syntax highlighting in GitHub / VSCode.
197
+ *
198
+ * Plan §2 mandates the diff block format over separate before/after
199
+ * plain-text blocks because the unified-diff form gives free
200
+ * highlighting and a familiar review surface.
201
+ */
202
+ function renderRecommendedEditsSection(edits) {
203
+ const lines = [];
204
+ lines.push('## Recommended Edits');
205
+ lines.push('');
206
+ for (const edit of edits) {
207
+ lines.push(`### Recommended edit: differentiate from \`${edit.otherEntry.identifier}\``);
208
+ lines.push('');
209
+ lines.push(`**File**: \`${edit.filePath}\``);
210
+ lines.push(`**Lines**: ${edit.lineRange.start}-${edit.lineRange.end}`);
211
+ lines.push(`**Pattern**: \`${edit.pattern}\` (${edit.applyMode})`);
212
+ lines.push('');
213
+ lines.push('```diff');
214
+ for (const beforeLine of edit.before.split('\n')) {
215
+ lines.push(`-${beforeLine}`);
216
+ }
217
+ for (const afterLine of edit.after.split('\n')) {
218
+ lines.push(`+${afterLine}`);
219
+ }
220
+ lines.push('```');
221
+ lines.push('');
222
+ lines.push(`**Why**: ${edit.rationale}`);
223
+ lines.push('');
224
+ }
225
+ return lines.join('\n');
226
+ }
227
+ // ---------------------------------------------------------------------------
228
+ // Helpers
229
+ // ---------------------------------------------------------------------------
230
+ function containsClaudeMdRule(result) {
231
+ return result.inventory.some((e) => e.kind === 'claude_md_rule');
232
+ }
233
+ function describeEntry(entry) {
234
+ return `\`${entry.identifier}\` (${entry.kind})`;
235
+ }
236
+ function formatTokens(tokens) {
237
+ if (tokens.length === 0)
238
+ return '_none_';
239
+ return tokens.map((t) => `\`${t}\``).join(', ');
240
+ }
241
+ //# sourceMappingURL=audit-report-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-report-writer.js","sourceRoot":"","sources":["../../../src/audit/audit-report-writer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @fileoverview Per-audit suggestion persistence (SMI-4590 Wave 4 PR 4).
3
+ * @module @skillsmith/mcp-server/audit/audit-suggestions
4
+ *
5
+ * Persists `RenameSuggestion[]` (Wave 2) + `RecommendedEdit[]` (Wave 3)
6
+ * alongside the existing `~/.skillsmith/audits/<auditId>/result.json`
7
+ * (Wave 1, see `audit-history.ts`). The `apply_namespace_rename` and
8
+ * `apply_recommended_edit` MCP tools (this PR) read this file to look up
9
+ * the suggestion that corresponds to a `(auditId, collisionId)` pair.
10
+ *
11
+ * File layout: `<auditDir>/suggestions.json` — atomic via tmp-file +
12
+ * `fs.rename`, mirroring `audit-history.ts`. Schema is versioned so a
13
+ * future PR can extend the persisted shape without breaking older
14
+ * audit dirs.
15
+ *
16
+ * Why a sibling file (vs. extending `result.json`):
17
+ * - `result.json` is keyed by `InventoryAuditResult` shape (Wave 1
18
+ * barrel surface). Extending it pulls Wave 2/3 types into Wave 1's
19
+ * persistence layer.
20
+ * - The CLI (PR 5) wants to render `result.json` as-is for
21
+ * `--report-only` callers; suggestions live alongside but aren't
22
+ * part of the inventory snapshot.
23
+ */
24
+ import type { RecommendedEdit } from './edit-suggester.types.js';
25
+ import type { RenameSuggestion } from './rename-engine.types.js';
26
+ /** Persisted shape. `version: 1` is the only supported schema. */
27
+ export interface AuditSuggestionsFile {
28
+ version: 1;
29
+ auditId: string;
30
+ renameSuggestions: RenameSuggestion[];
31
+ recommendedEdits: RecommendedEdit[];
32
+ }
33
+ export interface AuditSuggestionsOptions {
34
+ /** Override the audits root (default `~/.skillsmith/audits`). */
35
+ auditsDir?: string;
36
+ }
37
+ /**
38
+ * Persist the suggestion arrays for `auditId` to
39
+ * `<auditsDir>/<auditId>/suggestions.json`. Atomic. Creates the per-audit
40
+ * directory if missing (matches `writeAuditHistory` semantics).
41
+ */
42
+ export declare function writeAuditSuggestions(auditId: string, renameSuggestions: ReadonlyArray<RenameSuggestion>, recommendedEdits: ReadonlyArray<RecommendedEdit>, opts?: AuditSuggestionsOptions): Promise<{
43
+ suggestionsPath: string;
44
+ }>;
45
+ /**
46
+ * Read back the persisted suggestions for `auditId`. Returns `null` for
47
+ * unknown / missing audit dirs and for malformed / wrong-version files.
48
+ * Callers treat the absence as "no suggestions"; the apply-tools surface
49
+ * a typed error when the lookup is required but returns null.
50
+ */
51
+ export declare function readAuditSuggestions(auditId: string, opts?: AuditSuggestionsOptions): Promise<AuditSuggestionsFile | null>;
52
+ //# sourceMappingURL=audit-suggestions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-suggestions.d.ts","sourceRoot":"","sources":["../../../src/audit/audit-suggestions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAIhE,kEAAkE;AAClE,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,CAAC,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,iBAAiB,EAAE,gBAAgB,EAAE,CAAA;IACrC,gBAAgB,EAAE,eAAe,EAAE,CAAA;CACpC;AAED,MAAM,WAAW,uBAAuB;IACtC,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,MAAM,EACf,iBAAiB,EAAE,aAAa,CAAC,gBAAgB,CAAC,EAClD,gBAAgB,EAAE,aAAa,CAAC,eAAe,CAAC,EAChD,IAAI,GAAE,uBAA4B,GACjC,OAAO,CAAC;IAAE,eAAe,EAAE,MAAM,CAAA;CAAE,CAAC,CAkBtC;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,uBAA4B,GACjC,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAoBtC"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * @fileoverview Per-audit suggestion persistence (SMI-4590 Wave 4 PR 4).
3
+ * @module @skillsmith/mcp-server/audit/audit-suggestions
4
+ *
5
+ * Persists `RenameSuggestion[]` (Wave 2) + `RecommendedEdit[]` (Wave 3)
6
+ * alongside the existing `~/.skillsmith/audits/<auditId>/result.json`
7
+ * (Wave 1, see `audit-history.ts`). The `apply_namespace_rename` and
8
+ * `apply_recommended_edit` MCP tools (this PR) read this file to look up
9
+ * the suggestion that corresponds to a `(auditId, collisionId)` pair.
10
+ *
11
+ * File layout: `<auditDir>/suggestions.json` — atomic via tmp-file +
12
+ * `fs.rename`, mirroring `audit-history.ts`. Schema is versioned so a
13
+ * future PR can extend the persisted shape without breaking older
14
+ * audit dirs.
15
+ *
16
+ * Why a sibling file (vs. extending `result.json`):
17
+ * - `result.json` is keyed by `InventoryAuditResult` shape (Wave 1
18
+ * barrel surface). Extending it pulls Wave 2/3 types into Wave 1's
19
+ * persistence layer.
20
+ * - The CLI (PR 5) wants to render `result.json` as-is for
21
+ * `--report-only` callers; suggestions live alongside but aren't
22
+ * part of the inventory snapshot.
23
+ */
24
+ import * as fs from 'node:fs/promises';
25
+ import * as os from 'node:os';
26
+ import * as path from 'node:path';
27
+ const DEFAULT_AUDITS_DIR = path.join(os.homedir(), '.skillsmith', 'audits');
28
+ /**
29
+ * Persist the suggestion arrays for `auditId` to
30
+ * `<auditsDir>/<auditId>/suggestions.json`. Atomic. Creates the per-audit
31
+ * directory if missing (matches `writeAuditHistory` semantics).
32
+ */
33
+ export async function writeAuditSuggestions(auditId, renameSuggestions, recommendedEdits, opts = {}) {
34
+ const auditsDir = opts.auditsDir ?? DEFAULT_AUDITS_DIR;
35
+ const auditDir = path.join(auditsDir, auditId);
36
+ const suggestionsPath = path.join(auditDir, 'suggestions.json');
37
+ const tmpPath = `${suggestionsPath}.tmp`;
38
+ await fs.mkdir(auditDir, { recursive: true });
39
+ const payload = {
40
+ version: 1,
41
+ auditId,
42
+ renameSuggestions: [...renameSuggestions],
43
+ recommendedEdits: [...recommendedEdits],
44
+ };
45
+ await fs.writeFile(tmpPath, JSON.stringify(payload, null, 2), 'utf-8');
46
+ await fs.rename(tmpPath, suggestionsPath);
47
+ return { suggestionsPath };
48
+ }
49
+ /**
50
+ * Read back the persisted suggestions for `auditId`. Returns `null` for
51
+ * unknown / missing audit dirs and for malformed / wrong-version files.
52
+ * Callers treat the absence as "no suggestions"; the apply-tools surface
53
+ * a typed error when the lookup is required but returns null.
54
+ */
55
+ export async function readAuditSuggestions(auditId, opts = {}) {
56
+ const auditsDir = opts.auditsDir ?? DEFAULT_AUDITS_DIR;
57
+ const suggestionsPath = path.join(auditsDir, auditId, 'suggestions.json');
58
+ let raw;
59
+ try {
60
+ raw = await fs.readFile(suggestionsPath, 'utf-8');
61
+ }
62
+ catch {
63
+ return null;
64
+ }
65
+ let parsed;
66
+ try {
67
+ parsed = JSON.parse(raw);
68
+ }
69
+ catch {
70
+ return null;
71
+ }
72
+ if (!isAuditSuggestionsFile(parsed))
73
+ return null;
74
+ return parsed;
75
+ }
76
+ function isAuditSuggestionsFile(v) {
77
+ if (!v || typeof v !== 'object')
78
+ return false;
79
+ const obj = v;
80
+ if (obj.version !== 1)
81
+ return false;
82
+ if (typeof obj.auditId !== 'string' || obj.auditId.length === 0)
83
+ return false;
84
+ if (!Array.isArray(obj.renameSuggestions))
85
+ return false;
86
+ if (!Array.isArray(obj.recommendedEdits))
87
+ return false;
88
+ return true;
89
+ }
90
+ //# sourceMappingURL=audit-suggestions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-suggestions.js","sourceRoot":"","sources":["../../../src/audit/audit-suggestions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * @fileoverview Bootstrap unmanaged skills for SMI-4587 Wave 1 Step 6a.
3
+ * @module @skillsmith/mcp-server/audit/bootstrap-unmanaged
4
+ *
5
+ * Iterates over inventory entries and registers any unmanaged SKILL.md
6
+ * via `index_local`. Failures are converted into typed `warnings[]`
7
+ * entries (`namespace.inventory.bootstrap_failed`) — never thrown — so
8
+ * the audit run can complete even when individual bootstrap calls fail
9
+ * (decision #12 in plan).
10
+ *
11
+ * Wave 1 PR #4 (Step 8 / NEW-E-2) wires the real `indexLocalSkill` core
12
+ * helper as the default `bootstrapFn` — replacing PR #3's no-op stub. The
13
+ * MCP-side `parseFrontmatter` is injected so behaviour matches the
14
+ * existing `LocalIndexer` path bit-for-bit.
15
+ *
16
+ * "Unmanaged" = `kind: 'skill'` AND `meta.author` is undefined (i.e.,
17
+ * the skill is not registered in `~/.skillsmith/manifest.json`).
18
+ */
19
+ import type { InventoryEntry, ScanWarning } from '../utils/local-inventory.types.js';
20
+ /**
21
+ * Per-entry bootstrap callback. Implementations register the skill with
22
+ * `index_local` (or the future `indexLocalSkill` core helper) and return
23
+ * void on success. Throwing converts to a typed warning, never a hard
24
+ * fail.
25
+ */
26
+ export type BootstrapFn = (entry: InventoryEntry) => Promise<void>;
27
+ export interface BootstrapUnmanagedOptions {
28
+ /**
29
+ * Bootstrap callback. Defaults to {@link defaultIndexLocalSkillBootstrap}
30
+ * (PR #4 / NEW-E-2 wiring) which delegates to the real `indexLocalSkill`
31
+ * core helper. Tests can substitute a vi.fn() to assert call counts and
32
+ * exercise the failure-warning path.
33
+ */
34
+ bootstrapFn?: BootstrapFn;
35
+ /** Optional logger sink for non-fatal diagnostics (debug-level). */
36
+ logger?: {
37
+ debug?: (msg: string, meta?: unknown) => void;
38
+ };
39
+ }
40
+ export interface BootstrapUnmanagedResult {
41
+ /** Number of entries that were considered unmanaged candidates. */
42
+ attempted: number;
43
+ /** Subset of `attempted` that completed without throwing. */
44
+ succeeded: number;
45
+ /** Warnings produced by failed bootstrap attempts (one per failure). */
46
+ warnings: ScanWarning[];
47
+ }
48
+ /**
49
+ * Identify unmanaged SKILL.md entries — `kind: 'skill'` with no
50
+ * `meta.author` (i.e., not registered in `~/.skillsmith/manifest.json`).
51
+ * Exported so tests + future callers can re-use the predicate.
52
+ */
53
+ export declare function isUnmanagedSkill(entry: InventoryEntry): boolean;
54
+ /**
55
+ * Run the bootstrap pass over an inventory snapshot.
56
+ *
57
+ * Contract:
58
+ * - Never throws. Per-entry failures convert to a `ScanWarning` with
59
+ * code `namespace.inventory.bootstrap_failed`.
60
+ * - Always returns; callers can append `result.warnings` onto the
61
+ * audit-level warnings array.
62
+ * - Pure aside from the `bootstrapFn` side effect; safe to invoke in
63
+ * dry-run / unit-test mode by supplying a no-op `bootstrapFn`.
64
+ */
65
+ export declare function bootstrapUnmanagedSkills(inventory: ReadonlyArray<InventoryEntry>, opts?: BootstrapUnmanagedOptions): Promise<BootstrapUnmanagedResult>;
66
+ //# sourceMappingURL=bootstrap-unmanaged.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap-unmanaged.d.ts","sourceRoot":"","sources":["../../../src/audit/bootstrap-unmanaged.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAA;AAIpF;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAElE,MAAM,WAAW,yBAAyB;IACxC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,oEAAoE;IACpE,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE,CAAA;CAC3D;AAED,MAAM,WAAW,wBAAwB;IACvC,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAA;IACjB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAA;IACjB,wEAAwE;IACxE,QAAQ,EAAE,WAAW,EAAE,CAAA;CACxB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAE/D;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,aAAa,CAAC,cAAc,CAAC,EACxC,IAAI,GAAE,yBAA8B,GACnC,OAAO,CAAC,wBAAwB,CAAC,CA+BnC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * @fileoverview Bootstrap unmanaged skills for SMI-4587 Wave 1 Step 6a.
3
+ * @module @skillsmith/mcp-server/audit/bootstrap-unmanaged
4
+ *
5
+ * Iterates over inventory entries and registers any unmanaged SKILL.md
6
+ * via `index_local`. Failures are converted into typed `warnings[]`
7
+ * entries (`namespace.inventory.bootstrap_failed`) — never thrown — so
8
+ * the audit run can complete even when individual bootstrap calls fail
9
+ * (decision #12 in plan).
10
+ *
11
+ * Wave 1 PR #4 (Step 8 / NEW-E-2) wires the real `indexLocalSkill` core
12
+ * helper as the default `bootstrapFn` — replacing PR #3's no-op stub. The
13
+ * MCP-side `parseFrontmatter` is injected so behaviour matches the
14
+ * existing `LocalIndexer` path bit-for-bit.
15
+ *
16
+ * "Unmanaged" = `kind: 'skill'` AND `meta.author` is undefined (i.e.,
17
+ * the skill is not registered in `~/.skillsmith/manifest.json`).
18
+ */
19
+ import { indexLocalSkill } from '@skillsmith/core';
20
+ import { WARNING_CODES } from '../utils/local-inventory.helpers.js';
21
+ import { parseFrontmatter } from '../indexer/FrontmatterParser.js';
22
+ /**
23
+ * Identify unmanaged SKILL.md entries — `kind: 'skill'` with no
24
+ * `meta.author` (i.e., not registered in `~/.skillsmith/manifest.json`).
25
+ * Exported so tests + future callers can re-use the predicate.
26
+ */
27
+ export function isUnmanagedSkill(entry) {
28
+ return entry.kind === 'skill' && !entry.meta?.author;
29
+ }
30
+ /**
31
+ * Run the bootstrap pass over an inventory snapshot.
32
+ *
33
+ * Contract:
34
+ * - Never throws. Per-entry failures convert to a `ScanWarning` with
35
+ * code `namespace.inventory.bootstrap_failed`.
36
+ * - Always returns; callers can append `result.warnings` onto the
37
+ * audit-level warnings array.
38
+ * - Pure aside from the `bootstrapFn` side effect; safe to invoke in
39
+ * dry-run / unit-test mode by supplying a no-op `bootstrapFn`.
40
+ */
41
+ export async function bootstrapUnmanagedSkills(inventory, opts = {}) {
42
+ const bootstrapFn = opts.bootstrapFn ?? defaultIndexLocalSkillBootstrap;
43
+ const warnings = [];
44
+ let attempted = 0;
45
+ let succeeded = 0;
46
+ for (const entry of inventory) {
47
+ if (!isUnmanagedSkill(entry))
48
+ continue;
49
+ attempted++;
50
+ try {
51
+ await bootstrapFn(entry);
52
+ succeeded++;
53
+ }
54
+ catch (err) {
55
+ const message = err instanceof Error ? err.message : String(err);
56
+ warnings.push({
57
+ code: WARNING_CODES.BOOTSTRAP_FAILED,
58
+ message: `bootstrap failed for ${entry.source_path}: ${message}`,
59
+ context: {
60
+ source_path: entry.source_path,
61
+ identifier: entry.identifier,
62
+ error: message,
63
+ },
64
+ });
65
+ opts.logger?.debug?.('bootstrap_failed', {
66
+ source_path: entry.source_path,
67
+ error: message,
68
+ });
69
+ }
70
+ }
71
+ return { attempted, succeeded, warnings };
72
+ }
73
+ /**
74
+ * Default bootstrap implementation (SMI-4587 Wave 1 PR #4 / NEW-E-2).
75
+ *
76
+ * Delegates to `indexLocalSkill` from `@skillsmith/core/skills/index-local`
77
+ * with the MCP-side `parseFrontmatter` injected so we keep parity with the
78
+ * existing `LocalIndexer` path. Synchronous filesystem reads inside the
79
+ * core helper are wrapped in `Promise.resolve()` so the audit pipeline can
80
+ * await uniformly.
81
+ *
82
+ * Errors propagate upward — `bootstrapUnmanagedSkills` converts them into
83
+ * typed `ScanWarning` entries with code
84
+ * `namespace.inventory.bootstrap_failed`.
85
+ */
86
+ async function defaultIndexLocalSkillBootstrap(entry) {
87
+ await Promise.resolve(indexLocalSkill(entry.source_path, {
88
+ parseFrontmatter,
89
+ }));
90
+ }
91
+ //# sourceMappingURL=bootstrap-unmanaged.js.map