@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,99 @@
1
+ /**
2
+ * @fileoverview Install pre-flight namespace check (SMI-4588 Wave 2 Step 5, PR #3).
3
+ * @module @skillsmith/mcp-server/audit/install-preflight
4
+ *
5
+ * Detects namespace collisions between an in-flight install candidate and
6
+ * the user's existing local inventory BEFORE any side effects. Returns both
7
+ * a non-blocking `warnings[]` shape (for `power_user` / `governance` modes)
8
+ * AND a blocking `pendingCollision` envelope (for `preventative` mode). The
9
+ * mode gate lives in the install.ts caller — this module is pure detection
10
+ * + suggestion generation + audit-history persistence.
11
+ *
12
+ * Plan §3 + §Step 5 + Edits 2/3/6/7.
13
+ *
14
+ * Inventory contract (Edit 7):
15
+ * - `existingInventory` — pre-candidate snapshot, passed to
16
+ * `generateSuggestionChain` (chain self-collides at tier 1 otherwise).
17
+ * - `augmentedInventory` — existing + the synthesized candidate, passed to
18
+ * `detectCollisions`. Filtering to flags involving the candidate keeps
19
+ * pre-existing collisions from re-surfacing on every install.
20
+ *
21
+ * Failure model (Edit 2):
22
+ * - Pre-flight scanner failure (ledger malformed unrecoverably, fs error,
23
+ * unexpected throw) is ALWAYS non-blocking. The caller treats `warnings:
24
+ * [], pendingCollision: null` as a degraded-but-clean pass and proceeds
25
+ * with the install.
26
+ *
27
+ * Edit 6 — `readLedger()` may throw `namespace.ledger.version_unsupported`.
28
+ * The pre-flight catches it and degrades to non-blocking; bubbling would
29
+ * brick installs after a ledger downgrade.
30
+ */
31
+ import type { AuditId, InventoryEntry } from './collision-detector.types.js';
32
+ import type { NamespaceWarning, PendingCollision } from './namespace-audit.types.js';
33
+ import type { AuditMode, Tier } from '@skillsmith/core/config/audit-mode';
34
+ /**
35
+ * One synthesized candidate skill being considered for install. The
36
+ * pre-flight builds an `InventoryEntry` for it so the existing
37
+ * `detectCollisions` pipeline can compare it against the user's inventory.
38
+ */
39
+ export interface CandidateSkill {
40
+ /** Skill identifier post-install (e.g. `"code-helper"`). */
41
+ identifier: string;
42
+ /**
43
+ * Path the skill WILL occupy post-install. The pre-flight runs before
44
+ * the install touches disk, so this is a projected path used for
45
+ * suggestion-chain `authorPath` derivation. Real on-disk state is not
46
+ * inspected here.
47
+ */
48
+ projectedSourcePath: string;
49
+ /** Optional Skillsmith manifest skillId (`<author>/<name>`). */
50
+ skillId?: string | null;
51
+ /** Optional `meta.author` slug (`anthropic`) — flows to suggestion chain. */
52
+ author?: string | null;
53
+ /** Optional `meta.tags` for the suggestion-chain tag fallback. */
54
+ tags?: string[];
55
+ /** Optional `meta.description` (round-tripped for audit-history). */
56
+ description?: string;
57
+ /**
58
+ * Pack-domain hint (e.g. `codehelper`) used at chain tier 2/3. The install
59
+ * caller derives this from the registry response or manifest; pre-flight
60
+ * passes it through unchanged.
61
+ */
62
+ packDomain?: string | null;
63
+ }
64
+ export interface RunInstallPreflightInput {
65
+ /** Pre-candidate snapshot of `~/.claude/{skills,commands,agents}` + CLAUDE.md. */
66
+ existingInventory: ReadonlyArray<InventoryEntry>;
67
+ /** Synthesized candidate skill being considered for install. */
68
+ candidate: CandidateSkill;
69
+ /** Resolved audit mode (`'preventative'` blocks install in caller). */
70
+ mode: AuditMode;
71
+ /** Subscription tier (drives default mode for the inner detector run). */
72
+ tier: Tier;
73
+ }
74
+ export interface RunInstallPreflightResult {
75
+ /** Non-blocking warnings (`power_user` / `governance` mode shape). */
76
+ warnings: NamespaceWarning[];
77
+ /**
78
+ * Blocking envelope for `preventative` mode. Populated only when at
79
+ * least one candidate-related collision is detected. Caller decides
80
+ * whether to surface it based on `mode`.
81
+ */
82
+ pendingCollision: PendingCollision | null;
83
+ /**
84
+ * ULID written to audit history. Bubbled explicitly per Edit 7 so the
85
+ * install caller does not re-derive it for telemetry / ledger linkage.
86
+ */
87
+ auditId: AuditId;
88
+ }
89
+ /**
90
+ * Run the install pre-flight. Pure function over `existingInventory` +
91
+ * `candidate`; emits an audit-history entry as a side effect so the agent's
92
+ * later `apply_namespace_rename` call can re-derive context via `auditId`.
93
+ *
94
+ * Failure model: any unexpected throw inside this function returns the
95
+ * degraded shape (`warnings: []`, `pendingCollision: null`, fresh
96
+ * `auditId`) — the install MUST proceed when the detector breaks (Edit 2).
97
+ */
98
+ export declare function runInstallPreflight(input: RunInstallPreflightInput): Promise<RunInstallPreflightResult>;
99
+ //# sourceMappingURL=install-preflight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-preflight.d.ts","sourceRoot":"","sources":["../../../src/audit/install-preflight.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,OAAO,KAAK,EACV,OAAO,EAKP,cAAc,EAEf,MAAM,+BAA+B,CAAA;AACtC,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAEpF,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAA;AAOzE;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAA;IAClB;;;;;OAKG;IACH,mBAAmB,EAAE,MAAM,CAAA;IAC3B,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,wBAAwB;IACvC,kFAAkF;IAClF,iBAAiB,EAAE,aAAa,CAAC,cAAc,CAAC,CAAA;IAChD,gEAAgE;IAChE,SAAS,EAAE,cAAc,CAAA;IACzB,uEAAuE;IACvE,IAAI,EAAE,SAAS,CAAA;IACf,0EAA0E;IAC1E,IAAI,EAAE,IAAI,CAAA;CACX;AAED,MAAM,WAAW,yBAAyB;IACxC,sEAAsE;IACtE,QAAQ,EAAE,gBAAgB,EAAE,CAAA;IAC5B;;;;OAIG;IACH,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAA;IACzC;;;OAGG;IACH,OAAO,EAAE,OAAO,CAAA;CACjB;AA4KD;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,yBAAyB,CAAC,CAgHpC"}
@@ -0,0 +1,320 @@
1
+ /**
2
+ * @fileoverview Install pre-flight namespace check (SMI-4588 Wave 2 Step 5, PR #3).
3
+ * @module @skillsmith/mcp-server/audit/install-preflight
4
+ *
5
+ * Detects namespace collisions between an in-flight install candidate and
6
+ * the user's existing local inventory BEFORE any side effects. Returns both
7
+ * a non-blocking `warnings[]` shape (for `power_user` / `governance` modes)
8
+ * AND a blocking `pendingCollision` envelope (for `preventative` mode). The
9
+ * mode gate lives in the install.ts caller — this module is pure detection
10
+ * + suggestion generation + audit-history persistence.
11
+ *
12
+ * Plan §3 + §Step 5 + Edits 2/3/6/7.
13
+ *
14
+ * Inventory contract (Edit 7):
15
+ * - `existingInventory` — pre-candidate snapshot, passed to
16
+ * `generateSuggestionChain` (chain self-collides at tier 1 otherwise).
17
+ * - `augmentedInventory` — existing + the synthesized candidate, passed to
18
+ * `detectCollisions`. Filtering to flags involving the candidate keeps
19
+ * pre-existing collisions from re-surfacing on every install.
20
+ *
21
+ * Failure model (Edit 2):
22
+ * - Pre-flight scanner failure (ledger malformed unrecoverably, fs error,
23
+ * unexpected throw) is ALWAYS non-blocking. The caller treats `warnings:
24
+ * [], pendingCollision: null` as a degraded-but-clean pass and proceeds
25
+ * with the install.
26
+ *
27
+ * Edit 6 — `readLedger()` may throw `namespace.ledger.version_unsupported`.
28
+ * The pre-flight catches it and degrades to non-blocking; bubbling would
29
+ * brick installs after a ledger downgrade.
30
+ */
31
+ import { detectCollisions } from './collision-detector.js';
32
+ import { newAuditId, writeAuditHistory } from './audit-history.js';
33
+ import { generateSuggestionChain } from './suggestion-chain.js';
34
+ import { runEditSuggester } from './edit-suggester.js';
35
+ /**
36
+ * Synthesize an `InventoryEntry` for the candidate skill. Mirrors the
37
+ * shape `scanLocalInventory` produces for `~/.claude/skills/*`.
38
+ */
39
+ function synthesizeCandidateEntry(candidate) {
40
+ return {
41
+ kind: 'skill',
42
+ source_path: candidate.projectedSourcePath,
43
+ identifier: candidate.identifier,
44
+ triggerSurface: [candidate.identifier],
45
+ meta: {
46
+ author: candidate.author ?? undefined,
47
+ tags: candidate.tags,
48
+ description: candidate.description,
49
+ },
50
+ };
51
+ }
52
+ /**
53
+ * Filter detector flags to those that involve the candidate skill. The
54
+ * user has already accepted any pre-existing collisions; only newly
55
+ * introduced ones surface at install time.
56
+ */
57
+ function flagInvolvesCandidate(flag, candidatePath) {
58
+ if (flag.kind === 'exact') {
59
+ return flag.entries.some((e) => e.source_path === candidatePath);
60
+ }
61
+ if (flag.kind === 'generic') {
62
+ return flag.entry.source_path === candidatePath;
63
+ }
64
+ // semantic
65
+ return flag.entryA.source_path === candidatePath || flag.entryB.source_path === candidatePath;
66
+ }
67
+ /**
68
+ * Find the inventory entry on the OTHER side of a flag — the entry the
69
+ * candidate collides with. Used when constructing `RenameSuggestion`
70
+ * shapes whose `entry` field points at the candidate (so the apply path
71
+ * mutates the candidate, not the existing entry).
72
+ */
73
+ function candidateEntryFromFlag(flag, candidatePath) {
74
+ if (flag.kind === 'exact') {
75
+ return flag.entries.find((e) => e.source_path === candidatePath) ?? null;
76
+ }
77
+ if (flag.kind === 'generic') {
78
+ return flag.entry;
79
+ }
80
+ return flag.entryA.source_path === candidatePath ? flag.entryA : flag.entryB;
81
+ }
82
+ /**
83
+ * Pick the apply-action for the candidate based on its kind. The candidate
84
+ * is always synthesized as `kind: 'skill'`; this stays a switch so future
85
+ * candidate kinds (commands, agents added at install time) are supported.
86
+ */
87
+ function actionForEntry(entry) {
88
+ switch (entry.kind) {
89
+ case 'command':
90
+ return 'rename_command_file';
91
+ case 'agent':
92
+ return 'rename_agent_file';
93
+ case 'skill':
94
+ case 'claude_md_rule':
95
+ default:
96
+ return 'rename_skill_dir_and_frontmatter';
97
+ }
98
+ }
99
+ /**
100
+ * Build a `RenameSuggestion` for the candidate, picking the first
101
+ * non-colliding chain candidate as `suggested`. Falls back to chain
102
+ * candidate[0] when all collide (the agent surfaces the chain via
103
+ * `pendingCollision.suggestionChain`).
104
+ */
105
+ function buildCandidateSuggestion(args) {
106
+ const chain = generateSuggestionChain({
107
+ token: args.candidate.identifier,
108
+ author: args.candidate.author ?? null,
109
+ packDomain: args.candidate.packDomain ?? null,
110
+ tagFallback: args.candidate.tags?.[0] ?? null,
111
+ authorPath: args.candidate.projectedSourcePath,
112
+ existingInventory: args.existingInventory,
113
+ });
114
+ // First non-colliding candidate, or fall back to first slot when all
115
+ // collide (caller surfaces `chainExhausted` separately).
116
+ const lowercaseInventory = new Set(args.existingInventory.map((e) => e.identifier.toLowerCase()));
117
+ const firstFree = chain.candidates.find((c) => !lowercaseInventory.has(c.toLowerCase()));
118
+ const suggested = firstFree ?? chain.candidates[0] ?? args.candidate.identifier;
119
+ const reason = buildReason(args.flag, args.candidate.projectedSourcePath);
120
+ return {
121
+ suggestion: {
122
+ collisionId: args.flag.collisionId,
123
+ entry: args.candidateEntry,
124
+ currentName: args.candidate.identifier,
125
+ suggested,
126
+ applyAction: actionForEntry(args.candidateEntry),
127
+ reason,
128
+ },
129
+ chain: chain.candidates,
130
+ exhausted: chain.exhausted,
131
+ };
132
+ }
133
+ function buildReason(flag, candidatePath) {
134
+ if (flag.kind === 'exact') {
135
+ // Exclude the candidate from the rendered list so the message reads
136
+ // as "X collides with the existing entries", not "X collides with X
137
+ // and the existing entries".
138
+ const others = flag.entries
139
+ .filter((e) => e.source_path !== candidatePath)
140
+ .map((e) => `${e.kind}:${e.identifier}`)
141
+ .join(', ');
142
+ return `exact collision with ${others}`;
143
+ }
144
+ if (flag.kind === 'generic') {
145
+ return `generic-token flag (${flag.matchedTokens.join(', ')})`;
146
+ }
147
+ return `semantic overlap (cosine ${flag.cosineScore.toFixed(2)}) with ${flag.entryB.identifier}`;
148
+ }
149
+ /**
150
+ * Filter out the candidate skill's own prior on-disk presence from the
151
+ * inventory snapshot.
152
+ *
153
+ * On reinstall (`force: true`), `scanLocalInventory` returns an entry for
154
+ * the already-installed skill at `<projectedSourcePath>/SKILL.md`. If we
155
+ * left it in `existingInventory`, the augmented inventory would contain
156
+ * both the prior entry AND the synthesized candidate with the same
157
+ * `identifier`, and `detectExactCollisions` would surface a false-positive
158
+ * "namespace collision" that blocks reinstall in `preventative` mode.
159
+ *
160
+ * The reinstall flow is owned by `install.conflict.ts` (three-way merge,
161
+ * backup, force semantics). Pre-flight is for *new* namespace conflicts
162
+ * with *other* skills, not for the candidate's own prior copy.
163
+ */
164
+ function excludeSelfReinstall(existing, candidate) {
165
+ const candidateDir = candidate.projectedSourcePath;
166
+ const candidateIdentifier = candidate.identifier.toLowerCase();
167
+ return existing.filter((entry) => {
168
+ if (entry.kind !== 'skill')
169
+ return true;
170
+ if (entry.identifier.toLowerCase() !== candidateIdentifier)
171
+ return true;
172
+ // Skill entries' source_path is `<dir>/SKILL.md`; match by parent dir.
173
+ // Also accept exact-equality for forward-compat with future synthesis
174
+ // shapes that may use the directory path directly.
175
+ if (entry.source_path === candidateDir)
176
+ return false;
177
+ if (entry.source_path.startsWith(`${candidateDir}/`))
178
+ return false;
179
+ return true;
180
+ });
181
+ }
182
+ /**
183
+ * Run the install pre-flight. Pure function over `existingInventory` +
184
+ * `candidate`; emits an audit-history entry as a side effect so the agent's
185
+ * later `apply_namespace_rename` call can re-derive context via `auditId`.
186
+ *
187
+ * Failure model: any unexpected throw inside this function returns the
188
+ * degraded shape (`warnings: []`, `pendingCollision: null`, fresh
189
+ * `auditId`) — the install MUST proceed when the detector breaks (Edit 2).
190
+ */
191
+ export async function runInstallPreflight(input) {
192
+ const { existingInventory, candidate, mode, tier } = input;
193
+ // Allocate the audit id up front so the degraded path returns a valid
194
+ // ULID even when the inner detector throws before producing a result.
195
+ const auditId = newAuditId();
196
+ let inventoryWithoutSelf;
197
+ let augmentedInventory;
198
+ let result;
199
+ try {
200
+ // Exclude the candidate's own prior on-disk copy (reinstall) so the
201
+ // detector doesn't surface it as a namespace collision against itself.
202
+ inventoryWithoutSelf = excludeSelfReinstall(existingInventory, candidate);
203
+ const candidateEntry = synthesizeCandidateEntry(candidate);
204
+ augmentedInventory = [...inventoryWithoutSelf, candidateEntry];
205
+ result = await detectCollisions(augmentedInventory, {
206
+ auditId,
207
+ tier,
208
+ auditModeOverride: mode,
209
+ });
210
+ }
211
+ catch (err) {
212
+ // Edit 2: pre-flight failure is always non-blocking. Log + degrade.
213
+ // The catch covers `excludeSelfReinstall` (rejects non-iterable
214
+ // inputs), `synthesizeCandidateEntry`, the spread, AND
215
+ // `detectCollisions`. Any pre-flight failure → install proceeds.
216
+ console.warn(`[install-preflight] detector failed (${err.message}); degrading to non-blocking pass`);
217
+ return { warnings: [], pendingCollision: null, auditId };
218
+ }
219
+ // Filter to flags involving the candidate. Pre-existing collisions are
220
+ // out of scope at install time.
221
+ const allFlags = [
222
+ ...result.exactCollisions,
223
+ ...result.genericFlags,
224
+ ...result.semanticCollisions,
225
+ ];
226
+ const candidateFlags = allFlags.filter((f) => flagInvolvesCandidate(f, candidate.projectedSourcePath));
227
+ if (candidateFlags.length === 0) {
228
+ // Clean candidate. Persist the audit history (zero-flag run) so the
229
+ // agent's later inspection by auditId still resolves; absence of an
230
+ // audit file would be ambiguous.
231
+ await tryWriteAuditHistory(result);
232
+ return { warnings: [], pendingCollision: null, auditId };
233
+ }
234
+ // SMI-4589 Wave 3: run the edit-suggester over the audit result (which
235
+ // already contains the candidate-augmented inventory). We attach the
236
+ // matching edit to each semantic NamespaceWarning by collisionId. Edge
237
+ // cases:
238
+ // - Edit-suggester throws → log + degrade to no edits (preserves the
239
+ // non-blocking install contract per Wave 2 Edit 2). Failure of the
240
+ // edit surface MUST NOT brick the install pre-flight.
241
+ // - Non-semantic warnings (`exact`, `generic`) never carry a
242
+ // recommendedEdit — the suggester only runs over semanticCollisions.
243
+ const editsByCollisionId = await collectRecommendedEdits(result);
244
+ // Build a NamespaceWarning + suggestion-chain for each candidate-related
245
+ // flag. We surface the first flag's chain in `pendingCollision` (the
246
+ // dominant collision); all flags surface in `warnings[]`.
247
+ const warnings = [];
248
+ let pendingCollision = null;
249
+ for (let i = 0; i < candidateFlags.length; i++) {
250
+ const flag = candidateFlags[i];
251
+ const candidateEntry = candidateEntryFromFlag(flag, candidate.projectedSourcePath);
252
+ if (!candidateEntry)
253
+ continue;
254
+ const built = buildCandidateSuggestion({
255
+ flag,
256
+ candidate,
257
+ candidateEntry,
258
+ // Pass the self-excluded snapshot so the chain doesn't treat the
259
+ // candidate's own prior install (during a force-reinstall) as a
260
+ // colliding entry — that would force `chainExhausted: true` on
261
+ // every reinstall.
262
+ existingInventory: inventoryWithoutSelf,
263
+ });
264
+ const recommendedEdit = editsByCollisionId.get(flag.collisionId);
265
+ warnings.push({
266
+ collisionId: flag.collisionId,
267
+ kind: flag.kind,
268
+ severity: 'warning',
269
+ message: buildWarningMessage(flag, candidate, built.suggestion.suggested),
270
+ suggestion: built.suggestion,
271
+ auditId,
272
+ recommendedEdit,
273
+ });
274
+ // First candidate-flag becomes the pendingCollision envelope.
275
+ if (i === 0) {
276
+ pendingCollision = {
277
+ auditId,
278
+ suggestedRename: built.suggestion,
279
+ suggestionChain: built.chain,
280
+ chainExhausted: built.exhausted,
281
+ remediationHint: "call apply_namespace_rename({ auditId, action: 'apply' }) then re-invoke install_skill",
282
+ };
283
+ }
284
+ }
285
+ await tryWriteAuditHistory(result);
286
+ return { warnings, pendingCollision, auditId };
287
+ }
288
+ function buildWarningMessage(flag, candidate, suggested) {
289
+ const reason = buildReason(flag, candidate.projectedSourcePath);
290
+ return `Namespace ${flag.kind} collision installing "${candidate.identifier}": ${reason}. Suggested rename: "${suggested}".`;
291
+ }
292
+ /**
293
+ * SMI-4589 Wave 3: collect recommended edits indexed by collisionId.
294
+ * Edit-suggester failure degrades silently to an empty map — the
295
+ * non-blocking install contract from Wave 2 Edit 2 extends here.
296
+ */
297
+ async function collectRecommendedEdits(result) {
298
+ try {
299
+ const recommendedEdits = await runEditSuggester(result);
300
+ return new Map(recommendedEdits.map((e) => [e.collisionId, e]));
301
+ }
302
+ catch (err) {
303
+ console.warn(`[install-preflight] edit-suggester failed (${err.message}); proceeding without prose edits`);
304
+ return new Map();
305
+ }
306
+ }
307
+ /**
308
+ * Persist the audit history. Errors here are logged + swallowed — pre-flight
309
+ * is non-blocking (Edit 2), and a missing audit file degrades the agent's
310
+ * later `apply_namespace_rename` lookup but does not break install.
311
+ */
312
+ async function tryWriteAuditHistory(result) {
313
+ try {
314
+ await writeAuditHistory(result);
315
+ }
316
+ catch (err) {
317
+ console.warn(`[install-preflight] writeAuditHistory failed (${err.message}); auditId will be unrecoverable but install proceeds`);
318
+ }
319
+ }
320
+ //# sourceMappingURL=install-preflight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-preflight.js","sourceRoot":"","sources":["../../../src/audit/install-preflight.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * @fileoverview Shared namespace-audit type vocabulary (SMI-4588 Wave 2 Step 1, PR #1).
3
+ * @module @skillsmith/mcp-server/audit/namespace-audit.types
4
+ *
5
+ * `NamespaceWarning` and `PendingCollision` live here — not in
6
+ * `tools/install.types.ts` and not in `audit/install-preflight.ts` — to break
7
+ * the `tools → audit → tools` cycle that would otherwise form between
8
+ * `install-preflight.ts` (which constructs them) and `install.types.ts`
9
+ * (which embeds them in `InstallResult`). The shared file is depended on by
10
+ * both sides; neither side depends on the other.
11
+ *
12
+ * Wave 2 plan §4 + Edit 3 — placed in Step 1 so PRs #3/#4 import without
13
+ * rework.
14
+ *
15
+ * `RenameSuggestion` is imported from `./rename-engine.types.js` (PR #2). The
16
+ * PR #1 forward-declaration shim has been retired now that the canonical
17
+ * type ships alongside the rename engine.
18
+ */
19
+ import type { CollisionId } from './collision-detector.types.js';
20
+ import type { RenameSuggestion } from './rename-engine.types.js';
21
+ import type { RecommendedEdit } from './edit-suggester.types.js';
22
+ /**
23
+ * A non-blocking namespace collision surfaced by the install pre-flight
24
+ * (Wave 2 PR #3). `power_user` and `governance` modes return one of these
25
+ * per detected collision in `InstallResult.warnings[]`; the agent surfaces
26
+ * the suggestion to the user but the install still proceeds.
27
+ */
28
+ export interface NamespaceWarning {
29
+ /** Stable across audit runs — derived via `deriveCollisionId`. */
30
+ collisionId: CollisionId;
31
+ /** Matches the source collision flag's `kind`. */
32
+ kind: 'exact' | 'generic' | 'semantic';
33
+ /** Always `'warning'` — `NamespaceWarning` never blocks install. */
34
+ severity: 'warning';
35
+ /** User-facing message (rendered verbatim to the agent). */
36
+ message: string;
37
+ /**
38
+ * Suggested rename for the agent to surface. Constructed by
39
+ * `generateRenameSuggestions` (Wave 2 PR #2). Walking the suggestion
40
+ * chain is the agent's job — `suggestion` is the first non-colliding
41
+ * candidate.
42
+ */
43
+ suggestion: RenameSuggestion;
44
+ /**
45
+ * FK to the audit history written by `runInstallPreflight` (PR #3). Lets
46
+ * a later `apply_namespace_rename` call (Wave 4) re-read the original
47
+ * suggestion without re-running detection.
48
+ */
49
+ auditId: string;
50
+ /**
51
+ * SMI-4589 Wave 3: optional prose-edit recommendation surfaced for
52
+ * `description_overlap` semantic collisions. The agent surfaces the
53
+ * `RecommendedEdit` alongside the rename suggestion; rename may not
54
+ * be the right remediation when descriptions semantically overlap.
55
+ *
56
+ * Per the per-template gate ratified 2026-05-01, only
57
+ * `add_domain_qualifier`-pattern edits populate this field in v1.
58
+ * `kind: 'exact'` and `kind: 'generic'` warnings never carry a
59
+ * recommended edit (they're text-identifier collisions, not prose).
60
+ */
61
+ recommendedEdit?: RecommendedEdit;
62
+ }
63
+ /**
64
+ * Blocking-mode envelope for `audit_mode: 'preventative'` installs (Wave 2
65
+ * PR #3, decision #2). When pre-flight detects a collision, `install_skill`
66
+ * returns `installComplete: false` plus this envelope. The agent calls
67
+ * `apply_namespace_rename({ auditId, action: 'apply' })` (Wave 4) and then
68
+ * re-invokes `install_skill`.
69
+ *
70
+ * The `suggestionChain[]` carries up to 3 ordered candidates per
71
+ * decision #11; the agent walks the chain and picks the first non-colliding
72
+ * one. `chainExhausted` is `true` when all 3 collide and the agent must
73
+ * escalate to the human via `customName`.
74
+ */
75
+ export interface PendingCollision {
76
+ /** ULID — passed back to `apply_namespace_rename`. */
77
+ auditId: string;
78
+ /**
79
+ * First non-colliding candidate from `generateSuggestionChain`. The agent
80
+ * surfaces this to the user as the recommended rename.
81
+ */
82
+ suggestedRename: RenameSuggestion;
83
+ /**
84
+ * Up to 3 candidates from `generateSuggestionChain` (decision #11). The
85
+ * agent has the full chain so it can present alternatives without
86
+ * re-querying.
87
+ */
88
+ suggestionChain: string[];
89
+ /**
90
+ * `true` when all 3 chain candidates collide. The agent must escalate to
91
+ * the human and call `apply_namespace_rename({ customName: '…' })`.
92
+ */
93
+ chainExhausted: boolean;
94
+ /**
95
+ * Human-readable remediation hint, e.g.
96
+ * `"call apply_namespace_rename({ auditId, action: 'apply' }) then re-invoke install_skill"`.
97
+ */
98
+ remediationHint: string;
99
+ }
100
+ //# sourceMappingURL=namespace-audit.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"namespace-audit.types.d.ts","sourceRoot":"","sources":["../../../src/audit/namespace-audit.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAMhE;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,WAAW,EAAE,WAAW,CAAA;IACxB,kDAAkD;IAClD,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,UAAU,CAAA;IACtC,oEAAoE;IACpE,QAAQ,EAAE,SAAS,CAAA;IACnB,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAA;IACf;;;;;OAKG;IACH,UAAU,EAAE,gBAAgB,CAAA;IAC5B;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;;;;;OAUG;IACH,eAAe,CAAC,EAAE,eAAe,CAAA;CAClC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,eAAe,EAAE,gBAAgB,CAAA;IACjC;;;;OAIG;IACH,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAA;IACvB;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAA;CACxB"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @fileoverview Shared namespace-audit type vocabulary (SMI-4588 Wave 2 Step 1, PR #1).
3
+ * @module @skillsmith/mcp-server/audit/namespace-audit.types
4
+ *
5
+ * `NamespaceWarning` and `PendingCollision` live here — not in
6
+ * `tools/install.types.ts` and not in `audit/install-preflight.ts` — to break
7
+ * the `tools → audit → tools` cycle that would otherwise form between
8
+ * `install-preflight.ts` (which constructs them) and `install.types.ts`
9
+ * (which embeds them in `InstallResult`). The shared file is depended on by
10
+ * both sides; neither side depends on the other.
11
+ *
12
+ * Wave 2 plan §4 + Edit 3 — placed in Step 1 so PRs #3/#4 import without
13
+ * rework.
14
+ *
15
+ * `RenameSuggestion` is imported from `./rename-engine.types.js` (PR #2). The
16
+ * PR #1 forward-declaration shim has been retired now that the canonical
17
+ * type ships alongside the rename engine.
18
+ */
19
+ export {};
20
+ //# sourceMappingURL=namespace-audit.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"namespace-audit.types.js","sourceRoot":"","sources":["../../../src/audit/namespace-audit.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @fileoverview Atomic reader/writer for the namespace-overrides ledger
3
+ * (SMI-4588 Wave 2 Step 1, PR #1).
4
+ * @module @skillsmith/mcp-server/audit/namespace-overrides
5
+ *
6
+ * Persists `~/.skillsmith/namespace-overrides.json` — the load-bearing
7
+ * artifact that makes consumer-side namespace renames durable across pack
8
+ * version bumps. Conceptually equivalent to git's `rerere` but for
9
+ * namespace identifiers.
10
+ *
11
+ * Atomicity: every write goes through `<path>.tmp` + `fs.rename`. On read,
12
+ * a missing file degrades gracefully to an empty ledger; malformed JSON
13
+ * surfaces as a typed `namespace.ledger.malformed` discriminator (the
14
+ * caller decides whether to log + reset, never silently). A
15
+ * higher-than-supported `version` returns
16
+ * `namespace.ledger.version_unsupported` rather than a silent empty
17
+ * ledger — see plan §2 Edit 6.
18
+ *
19
+ * Concurrent-write boundary: last-write-wins on a single Node event loop
20
+ * via `<path>.tmp` + `fs.rename`. Multi-process scenarios (two MCP
21
+ * instances on the same machine) can lose one write under a tight race;
22
+ * documented as a known limitation in the plan. If multi-process safety
23
+ * becomes load-bearing, a future revision adds advisory locking via
24
+ * `proper-lockfile`.
25
+ */
26
+ import { type OverrideRecord, type OverridesLedger, type ReadLedgerResult } from './namespace-overrides.types.js';
27
+ export interface LedgerPathOptions {
28
+ /** Override the ledger path (default `~/.skillsmith/namespace-overrides.json`). */
29
+ ledgerPath?: string;
30
+ }
31
+ /**
32
+ * Read the ledger from disk and return a tagged union. Missing file →
33
+ * `{ kind: 'ok', ledger: <empty> }`. Malformed JSON →
34
+ * `{ kind: 'namespace.ledger.malformed', reason }`. `version > CURRENT_VERSION`
35
+ * → `{ kind: 'namespace.ledger.version_unsupported', found, expected }`.
36
+ *
37
+ * Callers that want the simpler "read or empty" semantics should use
38
+ * `readLedger()` (below) which collapses the discriminator.
39
+ */
40
+ export declare function readLedgerResult(opts?: LedgerPathOptions): Promise<ReadLedgerResult>;
41
+ /**
42
+ * Convenience wrapper: returns the ledger directly, collapsing the
43
+ * `malformed` branch to an empty ledger plus a `console.warn`. Higher-
44
+ * version files still bubble a thrown error — silently empty-ing a
45
+ * higher-version ledger would corrupt forward-compat (plan §2 Edit 6).
46
+ *
47
+ * For callers that need the typed discriminator, use `readLedgerResult`.
48
+ */
49
+ export declare function readLedger(opts?: LedgerPathOptions): Promise<OverridesLedger>;
50
+ /**
51
+ * Write the ledger atomically: `<path>.tmp` + `fs.rename`. Creates the
52
+ * parent directory on first run with `recursive: true` (mirrors
53
+ * audit-history.ts E-MISS-2 fix).
54
+ */
55
+ export declare function writeLedger(ledger: OverridesLedger, opts?: LedgerPathOptions): Promise<void>;
56
+ /**
57
+ * Pure helper: append a new override to a ledger and return a new copy.
58
+ * Original ledger is not mutated. The caller is responsible for
59
+ * persisting the result via `writeLedger` (separation of concerns —
60
+ * tests can build ledgers without touching disk).
61
+ *
62
+ * Idempotency: if an override with the same
63
+ * `(skillId, kind, originalIdentifier, renamedTo)` quadruple already
64
+ * exists, the input is returned unchanged. The caller can detect the
65
+ * no-op by reference equality (`appended === ledger`).
66
+ */
67
+ export declare function appendOverride(ledger: OverridesLedger, override: Omit<OverrideRecord, 'id' | 'appliedAt'>): OverridesLedger;
68
+ /**
69
+ * Pure lookup: find an override by `(skillId, kind, originalIdentifier)`.
70
+ * `skillId` may be omitted for local/unregistered artifacts; in that case
71
+ * only `kind` + `originalIdentifier` are matched. Returns the first match
72
+ * or `null`.
73
+ */
74
+ export declare function findOverride(ledger: OverridesLedger, query: {
75
+ skillId?: string | null;
76
+ kind?: OverrideRecord['kind'];
77
+ originalIdentifier: string;
78
+ }): OverrideRecord | null;
79
+ //# sourceMappingURL=namespace-overrides.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"namespace-overrides.d.ts","sourceRoot":"","sources":["../../../src/audit/namespace-overrides.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AASH,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,gCAAgC,CAAA;AAgBvC,MAAM,WAAW,iBAAiB;IAChC,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAUD;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA6D9F;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,eAAe,CAAC,CA0BvF;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,eAAe,EACvB,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,WAAW,CAAC,GACjD,eAAe,CAkBjB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAA;CAAE,GAC5F,cAAc,GAAG,IAAI,CAQvB"}