@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
@@ -14,11 +14,17 @@
14
14
  * - Wires onProgress to MCP protocol notifications
15
15
  */
16
16
  import { SkillInstallationService, emitInstallEvent, } from '@skillsmith/core';
17
+ import { addLink, getInstallPath, resolveClientPath } from '@skillsmith/core/install';
18
+ import { resolveAuditMode, isAuditMode } from '@skillsmith/core/config/audit-mode';
17
19
  import { getToolContext } from '../context.js';
18
- import { installInputSchema } from './install.types.js';
20
+ import { CLAUDE_SKILLS_DIR, installInputSchema } from './install.types.js';
19
21
  import { loadManifest, lookupSkillFromRegistry } from './install.helpers.js';
22
+ import { FIELD_LIMITS } from './validate.types.js';
20
23
  // SMI-1867: Conflict resolution logic (extracted per governance review)
21
24
  import { checkForConflicts } from './install.conflict.js';
25
+ // SMI-4588 Wave 2 PR #3: namespace pre-flight + ledger replay + mode gate.
26
+ import { runNamespaceGate } from './install.namespace-gate.js';
27
+ import * as path from 'path';
22
28
  // SMI-2741: MCP tool definition extracted to companion file
23
29
  export { installTool } from './install.tool.js';
24
30
  export { default } from './install.tool.js';
@@ -57,7 +63,22 @@ function buildValidationError(message) {
57
63
  };
58
64
  }
59
65
  /**
60
- * Install a skill from GitHub to the local Claude Code skills directory.
66
+ * SMI-4737: structured tool-error envelope for `extractSkillName` throws.
67
+ * Adversarial `skillId` values that survive Zod's 512-char boundary but
68
+ * produce an over-cap (>128 char) extracted segment are rejected here so
69
+ * the throw never escapes the MCP handler. Mirrors the `buildValidationError`
70
+ * shape (application-level failure, not MCP protocol-level `isError`).
71
+ */
72
+ function buildInvalidSkillIdError(skillId, message) {
73
+ return {
74
+ success: false,
75
+ skillId,
76
+ installPath: '',
77
+ error: `invalid_skill_id: ${message}`,
78
+ };
79
+ }
80
+ /**
81
+ * Install a skill from GitHub to the local agent skills directory (~/.claude/skills/).
61
82
  *
62
83
  * Delegates core logic to SkillInstallationService from @skillsmith/core.
63
84
  * Adds MCP-specific conflict resolution (three-way merge, backup).
@@ -81,14 +102,53 @@ export async function installSkill(input, _context) {
81
102
  if (!parsed.success) {
82
103
  const message = parsed.error.issues
83
104
  .map((issue) => {
84
- const path = issue.path.length > 0 ? issue.path.join('.') : '<root>';
85
- return `${path}: ${issue.message}`;
105
+ // Renamed from `path` to `issuePath` to avoid shadowing the
106
+ // module-level `path` import (no-shadow hygiene).
107
+ const issuePath = issue.path.length > 0 ? issue.path.join('.') : '<root>';
108
+ return `${issuePath}: ${issue.message}`;
86
109
  })
87
110
  .join('; ');
88
111
  return buildValidationError(message);
89
112
  }
90
113
  const validInput = parsed.data;
114
+ // SMI-4588 Wave 2 PR #3: namespace pre-flight + mode gate. Runs BEFORE
115
+ // service construction so a `preventative`-mode collision short-circuits
116
+ // the install with no side effects. Pre-flight failure is non-blocking
117
+ // (Edit 2) — `runNamespaceGate` swallows internal throws and returns
118
+ // `decision: 'proceed'`.
119
+ // SMI-4737: extractSkillName (called via buildPreflightCandidate) throws on
120
+ // over-cap (>128 char) extracted segments; surface as structured envelope.
121
+ let candidate;
122
+ try {
123
+ candidate = buildPreflightCandidate(validInput.skillId);
124
+ }
125
+ catch (err) {
126
+ return buildInvalidSkillIdError(validInput.skillId, err instanceof Error ? err.message : String(err));
127
+ }
128
+ const tier = resolveCallerTier();
129
+ const auditMode = resolveAuditMode({
130
+ tier,
131
+ override: readAuditModeOverride(),
132
+ });
133
+ const gate = await runNamespaceGate({ candidate, mode: auditMode, tier });
134
+ if (gate.decision === 'block') {
135
+ // Decision #2: preventative mode blocks; agent must call
136
+ // `apply_namespace_rename` then re-invoke install. The skill is NOT
137
+ // touched on disk.
138
+ return {
139
+ success: false,
140
+ skillId: validInput.skillId,
141
+ installPath: '',
142
+ error: 'Namespace collision detected; install blocked in preventative audit mode.',
143
+ ...gate.resultPatch,
144
+ };
145
+ }
91
146
  const context = _context ?? getToolContext();
147
+ // SMI-4578: resolve target install directory. Explicit `client` arg
148
+ // wins; otherwise fall back to SKILLSMITH_CLIENT env (or claude-code).
149
+ const effectiveSkillsDir = validInput.client
150
+ ? getInstallPath(validInput.client)
151
+ : resolveClientPath();
92
152
  // SMI-3483: Create core service instance with MCP context wiring
93
153
  // SMI-3873: aiDefenceFeedback omitted -- MCP server cannot call Ruflo tools.
94
154
  const service = new SkillInstallationService({
@@ -98,6 +158,7 @@ export async function installSkill(input, _context) {
98
158
  registryLookup: new McpRegistryLookup(context),
99
159
  coInstallRecorder: context.coInstallRepository,
100
160
  sessionInstalledSkillIds: context.sessionInstalledSkillIds,
161
+ skillsDir: effectiveSkillsDir,
101
162
  });
102
163
  // SMI-1867: Pre-flight conflict check for reinstall with force
103
164
  // This is MCP-specific (three-way merge UI, backup, storeOriginal)
@@ -133,17 +194,111 @@ export async function installSkill(input, _context) {
133
194
  success: result.success,
134
195
  durationMs: Date.now() - installStart,
135
196
  });
197
+ // SMI-4578: fan-out to additional clients after primary install. Failures
198
+ // are logged but do NOT mark the overall install as failed — canonical
199
+ // install at `client` is already complete.
200
+ if (result.success && validInput.alsoLink.length > 0) {
201
+ const fromClient = validInput.client ?? 'claude-code';
202
+ const skillName = extractSkillName(validInput.skillId);
203
+ for (const target of validInput.alsoLink) {
204
+ if (target === fromClient)
205
+ continue;
206
+ try {
207
+ await addLink({
208
+ skillId: skillName,
209
+ fromClient,
210
+ toClient: target,
211
+ preferSymlink: validInput.symlink,
212
+ force: validInput.force,
213
+ });
214
+ }
215
+ catch (linkErr) {
216
+ // Best-effort fan-out — log but don't fail the install
217
+ console.error(`[install] alsoLink to ${target} failed:`, linkErr instanceof Error ? linkErr.message : String(linkErr));
218
+ }
219
+ }
220
+ }
221
+ // SMI-4588 Wave 2 PR #3: surface non-blocking namespace warnings (and
222
+ // installComplete=true marker) on `power_user` / `governance` paths.
223
+ // `pendingCollision` is intentionally not merged here — it is exclusive
224
+ // to the blocking-mode early return above.
225
+ if (gate.resultPatch.warnings && gate.resultPatch.warnings.length > 0) {
226
+ return {
227
+ ...result,
228
+ installComplete: gate.resultPatch.installComplete,
229
+ warnings: gate.resultPatch.warnings,
230
+ };
231
+ }
136
232
  return result;
137
233
  }
234
+ /**
235
+ * Build the `CandidateSkill` shape consumed by `runNamespaceGate`. The
236
+ * pre-flight runs before any disk write, so the path is projected.
237
+ *
238
+ * `extractSkillName` mirrors the manifest-key derivation used elsewhere in
239
+ * this file; the `skillId` is propagated when the input is a registry id
240
+ * (`<author>/<name>`) so ledger lookups key on the canonical form.
241
+ */
242
+ function buildPreflightCandidate(skillId) {
243
+ const skillName = extractSkillName(skillId);
244
+ const isRegistryId = skillId.includes('/') && !skillId.startsWith('https://');
245
+ const author = isRegistryId ? skillId.split('/')[0] : null;
246
+ return {
247
+ identifier: skillName,
248
+ projectedSourcePath: path.join(CLAUDE_SKILLS_DIR, skillName),
249
+ skillId: isRegistryId ? skillId : null,
250
+ author,
251
+ };
252
+ }
253
+ /**
254
+ * Resolve the caller's subscription tier for the audit-mode resolver.
255
+ * Reads `SKILLSMITH_TIER` env var; falls through to `'community'` (the
256
+ * resolver's fail-safe default) when unset or invalid. The MCP subprocess
257
+ * has no JWT context, so env var is the only signal available without
258
+ * cross-cutting changes (Wave 4 will revisit if richer tier resolution
259
+ * becomes load-bearing).
260
+ */
261
+ function resolveCallerTier() {
262
+ const raw = process.env['SKILLSMITH_TIER'];
263
+ if (raw === 'community' || raw === 'individual' || raw === 'team' || raw === 'enterprise') {
264
+ return raw;
265
+ }
266
+ return 'community';
267
+ }
268
+ /**
269
+ * Read the optional `SKILLSMITH_AUDIT_MODE` override. Invalid values fall
270
+ * through to `null` so the resolver applies the tier default.
271
+ */
272
+ function readAuditModeOverride() {
273
+ const raw = process.env['SKILLSMITH_AUDIT_MODE'];
274
+ return isAuditMode(raw) ? raw : null;
275
+ }
138
276
  /**
139
277
  * Best-effort skill name extraction for conflict pre-check.
140
278
  * Does not need to be perfect -- just needs to match manifest keys.
279
+ *
280
+ * SMI-4737: throws when the extracted segment exceeds `FIELD_LIMITS.token`
281
+ * (128 chars). Adversarial `skillId` inputs that survive the Zod 512-char
282
+ * boundary but produce an over-cap segment are rejected at the derivation
283
+ * site so they cannot reach `sanitizeSegment`'s defensive 256-char floor
284
+ * (SMI-4733). Caller sites must wrap in try/catch and surface a structured
285
+ * tool-error envelope; the throw must not escape the MCP handler.
286
+ *
287
+ * Exported for direct unit testing (SMI-4737 tests).
141
288
  */
142
- function extractSkillName(skillId) {
289
+ export function extractSkillName(skillId) {
290
+ let name;
143
291
  if (skillId.includes('/')) {
144
292
  const parts = skillId.split('/');
145
- return parts[parts.length - 1];
293
+ name = parts[parts.length - 1];
294
+ }
295
+ else {
296
+ name = skillId;
297
+ }
298
+ if (name.length > FIELD_LIMITS.token) {
299
+ throw new Error(`Extracted skill name exceeds ${FIELD_LIMITS.token} chars (got ${name.length}). ` +
300
+ `skillId: ${skillId.slice(0, 64)}${skillId.length > 64 ? '...' : ''}`);
146
301
  }
147
- return skillId;
302
+ return name;
148
303
  }
149
304
  //# sourceMappingURL=install.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/tools/install.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/tools/install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @fileoverview Ledger-replay rewriter for the install hot path
3
+ * (SMI-4588 Wave 2 Step 6, PR #3).
4
+ * @module @skillsmith/mcp-server/tools/install.ledger-replay
5
+ *
6
+ * Pure rewriter: takes an install candidate and the namespace-overrides
7
+ * ledger, returns the candidate rewritten to its previously-renamed
8
+ * identifier when a matching ledger entry exists. Conceptually identical
9
+ * to git's `rerere` — the user's prior manual rename is silently
10
+ * re-applied so a pack version bump never resurrects the original
11
+ * `/ship` filename.
12
+ *
13
+ * This module is deliberately pure (no fs, no side effects) so it can
14
+ * compose into the install hot path without changing the on-disk write
15
+ * timing. The caller (install.ts) loads the ledger once via
16
+ * `readLedger()` and passes it in, then runs pre-flight against the
17
+ * REWRITTEN candidate identifier — the rewrite must happen before
18
+ * collision detection so a previously-resolved collision doesn't
19
+ * re-surface as a fresh warning on every install.
20
+ *
21
+ * Plan §3 — install integration step 3 (ledger replay).
22
+ */
23
+ import type { OverrideRecord, OverridesLedger } from '../audit/namespace-overrides.types.js';
24
+ import type { CandidateSkill } from '../audit/install-preflight.js';
25
+ export interface LedgerReplayResult {
26
+ /** Candidate after applying any ledger overrides (`identifier`/`projectedSourcePath` rewritten). */
27
+ candidate: CandidateSkill;
28
+ /** Override entries that matched the candidate. Empty when no replay occurred. */
29
+ applied: OverrideRecord[];
30
+ }
31
+ /**
32
+ * Rewrite the candidate skill's identifier (and projected source path)
33
+ * when a matching ledger override exists. Match keys:
34
+ *
35
+ * - `(skillId, kind: 'skill', originalIdentifier === candidate.identifier)`
36
+ *
37
+ * When `candidate.skillId` is provided, the lookup is keyed against the
38
+ * Skillsmith manifest skillId (`<author>/<name>`). When omitted, the
39
+ * lookup falls back to identifier-only matching across all `skillId`s —
40
+ * the user's local override applies regardless of registration state.
41
+ *
42
+ * Multiple matches: applies them in iteration order. In practice only
43
+ * one entry per `(skillId, originalIdentifier)` exists thanks to
44
+ * `appendOverride`'s dedupe, but the loop is defensive against ledger
45
+ * mutation outside the writer (e.g., a user hand-edits the JSON).
46
+ *
47
+ * Returns the candidate unchanged when no entry matches OR the ledger is
48
+ * empty. Reference equality on `candidate` is preserved for the no-op
49
+ * branch so callers can detect "no replay happened" without recomputing.
50
+ */
51
+ export declare function applyLedgerReplay(candidate: CandidateSkill, ledger: OverridesLedger): LedgerReplayResult;
52
+ //# sourceMappingURL=install.ledger-replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.ledger-replay.d.ts","sourceRoot":"","sources":["../../../src/tools/install.ledger-replay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAA;AAC5F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAEnE,MAAM,WAAW,kBAAkB;IACjC,oGAAoG;IACpG,SAAS,EAAE,cAAc,CAAA;IACzB,kFAAkF;IAClF,OAAO,EAAE,cAAc,EAAE,CAAA;CAC1B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,cAAc,EACzB,MAAM,EAAE,eAAe,GACtB,kBAAkB,CA+CpB"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * @fileoverview Ledger-replay rewriter for the install hot path
3
+ * (SMI-4588 Wave 2 Step 6, PR #3).
4
+ * @module @skillsmith/mcp-server/tools/install.ledger-replay
5
+ *
6
+ * Pure rewriter: takes an install candidate and the namespace-overrides
7
+ * ledger, returns the candidate rewritten to its previously-renamed
8
+ * identifier when a matching ledger entry exists. Conceptually identical
9
+ * to git's `rerere` — the user's prior manual rename is silently
10
+ * re-applied so a pack version bump never resurrects the original
11
+ * `/ship` filename.
12
+ *
13
+ * This module is deliberately pure (no fs, no side effects) so it can
14
+ * compose into the install hot path without changing the on-disk write
15
+ * timing. The caller (install.ts) loads the ledger once via
16
+ * `readLedger()` and passes it in, then runs pre-flight against the
17
+ * REWRITTEN candidate identifier — the rewrite must happen before
18
+ * collision detection so a previously-resolved collision doesn't
19
+ * re-surface as a fresh warning on every install.
20
+ *
21
+ * Plan §3 — install integration step 3 (ledger replay).
22
+ */
23
+ import { findOverride } from '../audit/namespace-overrides.js';
24
+ /**
25
+ * Rewrite the candidate skill's identifier (and projected source path)
26
+ * when a matching ledger override exists. Match keys:
27
+ *
28
+ * - `(skillId, kind: 'skill', originalIdentifier === candidate.identifier)`
29
+ *
30
+ * When `candidate.skillId` is provided, the lookup is keyed against the
31
+ * Skillsmith manifest skillId (`<author>/<name>`). When omitted, the
32
+ * lookup falls back to identifier-only matching across all `skillId`s —
33
+ * the user's local override applies regardless of registration state.
34
+ *
35
+ * Multiple matches: applies them in iteration order. In practice only
36
+ * one entry per `(skillId, originalIdentifier)` exists thanks to
37
+ * `appendOverride`'s dedupe, but the loop is defensive against ledger
38
+ * mutation outside the writer (e.g., a user hand-edits the JSON).
39
+ *
40
+ * Returns the candidate unchanged when no entry matches OR the ledger is
41
+ * empty. Reference equality on `candidate` is preserved for the no-op
42
+ * branch so callers can detect "no replay happened" without recomputing.
43
+ */
44
+ export function applyLedgerReplay(candidate, ledger) {
45
+ if (ledger.overrides.length === 0) {
46
+ return { candidate, applied: [] };
47
+ }
48
+ const applied = [];
49
+ let workingIdentifier = candidate.identifier;
50
+ let workingPath = candidate.projectedSourcePath;
51
+ // Iterate until no more matches. Loop bound: ledger length (defensive).
52
+ for (let pass = 0; pass < ledger.overrides.length; pass++) {
53
+ const match = findOverride(ledger, {
54
+ skillId: candidate.skillId ?? undefined,
55
+ kind: 'skill',
56
+ originalIdentifier: workingIdentifier,
57
+ });
58
+ if (!match)
59
+ break;
60
+ // Avoid cycles: the same entry must not apply twice.
61
+ if (applied.some((a) => a.id === match.id))
62
+ break;
63
+ applied.push(match);
64
+ workingIdentifier = match.renamedTo;
65
+ // Project the post-replay source path under the same parent as the
66
+ // original projection. The ledger stores the absolute renamed path,
67
+ // but at install time the candidate may have a different parent
68
+ // (e.g. a `~/.claude/skills/<token>` projection). Replace only the
69
+ // basename so cross-host path migrations don't break replay.
70
+ const parentSep = workingPath.lastIndexOf('/');
71
+ workingPath =
72
+ parentSep === -1
73
+ ? match.renamedTo
74
+ : `${workingPath.slice(0, parentSep + 1)}${match.renamedTo}`;
75
+ }
76
+ if (applied.length === 0) {
77
+ return { candidate, applied: [] };
78
+ }
79
+ return {
80
+ candidate: {
81
+ ...candidate,
82
+ identifier: workingIdentifier,
83
+ projectedSourcePath: workingPath,
84
+ },
85
+ applied,
86
+ };
87
+ }
88
+ //# sourceMappingURL=install.ledger-replay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.ledger-replay.js","sourceRoot":"","sources":["../../../src/tools/install.ledger-replay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AAW9D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,iBAAiB,CAC/B,SAAyB,EACzB,MAAuB;IAEvB,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,CAAA;IACnC,CAAC;IAED,MAAM,OAAO,GAAqB,EAAE,CAAA;IACpC,IAAI,iBAAiB,GAAG,SAAS,CAAC,UAAU,CAAA;IAC5C,IAAI,WAAW,GAAG,SAAS,CAAC,mBAAmB,CAAA;IAE/C,wEAAwE;IACxE,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;QAC1D,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE;YACjC,OAAO,EAAE,SAAS,CAAC,OAAO,IAAI,SAAS;YACvC,IAAI,EAAE,OAAO;YACb,kBAAkB,EAAE,iBAAiB;SACtC,CAAC,CAAA;QACF,IAAI,CAAC,KAAK;YAAE,MAAK;QAEjB,qDAAqD;QACrD,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC;YAAE,MAAK;QAEjD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACnB,iBAAiB,GAAG,KAAK,CAAC,SAAS,CAAA;QACnC,mEAAmE;QACnE,oEAAoE;QACpE,gEAAgE;QAChE,mEAAmE;QACnE,6DAA6D;QAC7D,MAAM,SAAS,GAAG,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;QAC9C,WAAW;YACT,SAAS,KAAK,CAAC,CAAC;gBACd,CAAC,CAAC,KAAK,CAAC,SAAS;gBACjB,CAAC,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,SAAS,EAAE,CAAA;IAClE,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,CAAA;IACnC,CAAC;IAED,OAAO;QACL,SAAS,EAAE;YACT,GAAG,SAAS;YACZ,UAAU,EAAE,iBAAiB;YAC7B,mBAAmB,EAAE,WAAW;SACjC;QACD,OAAO;KACR,CAAA;AACH,CAAC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @fileoverview Namespace pre-flight + mode gate for the install hot path
3
+ * (SMI-4588 Wave 2 Step 6, PR #3).
4
+ * @module @skillsmith/mcp-server/tools/install.namespace-gate
5
+ *
6
+ * Encapsulates the three steps that bracket `service.install()` in the
7
+ * MCP install tool:
8
+ *
9
+ * 1. Ledger replay — rewrite the candidate skill's identifier when a
10
+ * previously-recorded user rename matches.
11
+ * 2. Pre-flight collision detection + suggestion-chain generation.
12
+ * 3. Mode gate (`preventative` blocks; `power_user`/`governance` warn).
13
+ *
14
+ * Extracted from `install.ts` per Step 6's "unconditional extraction"
15
+ * directive — keeps the hot-path file under the 500-LOC limit and keeps
16
+ * the new logic independently testable.
17
+ *
18
+ * Edits applied (plan-review 2026-05-02):
19
+ * - Edit 2: pre-flight scanner failure is ALWAYS non-blocking. The
20
+ * `runInstallPreflight` module already degrades on detector throws;
21
+ * this gate additionally swallows ledger-read errors (including
22
+ * `namespace.ledger.version_unsupported`) so a downgraded ledger
23
+ * never bricks installs.
24
+ * - Edit 6: typed `version_unsupported` error caught here, not bubbled.
25
+ * - Edit 7: pre-flight returns `auditId` explicitly; this gate threads
26
+ * it into the `pendingCollision` envelope without re-deriving.
27
+ */
28
+ import { type CandidateSkill, type RunInstallPreflightResult } from '../audit/install-preflight.js';
29
+ import type { AuditMode, Tier } from '@skillsmith/core/config/audit-mode';
30
+ import type { InstallResult } from './install.types.js';
31
+ export interface NamespaceGateInput {
32
+ /** Synthesized candidate for the skill being installed. */
33
+ candidate: CandidateSkill;
34
+ /** Resolved audit mode (caller resolves via `resolveAuditMode`). */
35
+ mode: AuditMode;
36
+ /** Subscription tier (passed through to detector for telemetry consistency). */
37
+ tier: Tier;
38
+ }
39
+ export interface NamespaceGateOutcome {
40
+ /**
41
+ * `'block'` only fires when `mode === 'preventative'` AND a candidate-
42
+ * involved collision was detected. Caller short-circuits the install
43
+ * with the `pendingCollision` envelope.
44
+ */
45
+ decision: 'block' | 'proceed';
46
+ /**
47
+ * The (possibly ledger-replayed) candidate. Caller MAY use this for
48
+ * post-install side effects, but Wave 2 PR #3 does not yet wire
49
+ * post-install rename — the ledger-replay rewrites the candidate in
50
+ * place at the pre-flight boundary so the surfaced suggestions match.
51
+ */
52
+ candidate: CandidateSkill;
53
+ /** Always present — populated by `runInstallPreflight`. */
54
+ preflight: RunInstallPreflightResult;
55
+ /**
56
+ * `InstallResult` payload to merge into the caller's return value.
57
+ * Populated for both `block` and `proceed` paths so the install hot
58
+ * path has a single shape to splat.
59
+ */
60
+ resultPatch: Pick<InstallResult, 'installComplete' | 'pendingCollision' | 'warnings'>;
61
+ }
62
+ /**
63
+ * Run the namespace pre-flight + apply the mode gate. Returns a decision
64
+ * the install hot path branches on. Never throws — all failure paths
65
+ * degrade to `decision: 'proceed'` with a logged warning (Edit 2).
66
+ */
67
+ export declare function runNamespaceGate(input: NamespaceGateInput): Promise<NamespaceGateOutcome>;
68
+ //# sourceMappingURL=install.namespace-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.namespace-gate.d.ts","sourceRoot":"","sources":["../../../src/tools/install.namespace-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,yBAAyB,EAC/B,MAAM,+BAA+B,CAAA;AAKtC,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAA;AAGzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEvD,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,SAAS,EAAE,cAAc,CAAA;IACzB,oEAAoE;IACpE,IAAI,EAAE,SAAS,CAAA;IACf,gFAAgF;IAChF,IAAI,EAAE,IAAI,CAAA;CACX;AAED,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAA;IAC7B;;;;;OAKG;IACH,SAAS,EAAE,cAAc,CAAA;IACzB,2DAA2D;IAC3D,SAAS,EAAE,yBAAyB,CAAA;IACpC;;;;OAIG;IACH,WAAW,EAAE,IAAI,CAAC,aAAa,EAAE,iBAAiB,GAAG,kBAAkB,GAAG,UAAU,CAAC,CAAA;CACtF;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA6E/F"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * @fileoverview Namespace pre-flight + mode gate for the install hot path
3
+ * (SMI-4588 Wave 2 Step 6, PR #3).
4
+ * @module @skillsmith/mcp-server/tools/install.namespace-gate
5
+ *
6
+ * Encapsulates the three steps that bracket `service.install()` in the
7
+ * MCP install tool:
8
+ *
9
+ * 1. Ledger replay — rewrite the candidate skill's identifier when a
10
+ * previously-recorded user rename matches.
11
+ * 2. Pre-flight collision detection + suggestion-chain generation.
12
+ * 3. Mode gate (`preventative` blocks; `power_user`/`governance` warn).
13
+ *
14
+ * Extracted from `install.ts` per Step 6's "unconditional extraction"
15
+ * directive — keeps the hot-path file under the 500-LOC limit and keeps
16
+ * the new logic independently testable.
17
+ *
18
+ * Edits applied (plan-review 2026-05-02):
19
+ * - Edit 2: pre-flight scanner failure is ALWAYS non-blocking. The
20
+ * `runInstallPreflight` module already degrades on detector throws;
21
+ * this gate additionally swallows ledger-read errors (including
22
+ * `namespace.ledger.version_unsupported`) so a downgraded ledger
23
+ * never bricks installs.
24
+ * - Edit 6: typed `version_unsupported` error caught here, not bubbled.
25
+ * - Edit 7: pre-flight returns `auditId` explicitly; this gate threads
26
+ * it into the `pendingCollision` envelope without re-deriving.
27
+ */
28
+ import { runInstallPreflight, } from '../audit/install-preflight.js';
29
+ import { newAuditId } from '../audit/audit-history.js';
30
+ import { readLedger } from '../audit/namespace-overrides.js';
31
+ import { applyLedgerReplay } from './install.ledger-replay.js';
32
+ import { scanLocalInventory } from '../utils/local-inventory.js';
33
+ /**
34
+ * Run the namespace pre-flight + apply the mode gate. Returns a decision
35
+ * the install hot path branches on. Never throws — all failure paths
36
+ * degrade to `decision: 'proceed'` with a logged warning (Edit 2).
37
+ */
38
+ export async function runNamespaceGate(input) {
39
+ const { mode, tier } = input;
40
+ // Step 1 — ledger replay. Read the ledger; on failure (including
41
+ // `version_unsupported`), degrade to "no replay, no preflight" because
42
+ // we cannot trust the candidate's effective identifier without it.
43
+ let candidate = input.candidate;
44
+ try {
45
+ const ledger = await readLedger();
46
+ const replay = applyLedgerReplay(input.candidate, ledger);
47
+ candidate = replay.candidate;
48
+ }
49
+ catch (err) {
50
+ // Edit 6: typed version_unsupported (or any other ledger error)
51
+ // surfaces here. Pre-flight is non-blocking; degrade.
52
+ console.warn(`[install.namespace-gate] ledger read failed (${err.message}); skipping pre-flight`);
53
+ return degradedProceed(candidate);
54
+ }
55
+ // Step 2 — scan local inventory + run pre-flight. The scanner runs
56
+ // synchronously per call (Wave 1 plumbing). Errors here also degrade.
57
+ let existingInventory;
58
+ try {
59
+ const scan = await scanLocalInventory();
60
+ existingInventory = scan.entries;
61
+ }
62
+ catch (err) {
63
+ console.warn(`[install.namespace-gate] scanLocalInventory failed (${err.message}); skipping pre-flight`);
64
+ return degradedProceed(candidate);
65
+ }
66
+ let preflight;
67
+ try {
68
+ preflight = await runInstallPreflight({
69
+ existingInventory,
70
+ candidate,
71
+ mode,
72
+ tier,
73
+ });
74
+ }
75
+ catch (err) {
76
+ // `runInstallPreflight` itself already catches detector throws and
77
+ // degrades, but a defensive outer catch keeps the install hot path
78
+ // bulletproof against any future regression.
79
+ console.warn(`[install.namespace-gate] runInstallPreflight threw (${err.message}); proceeding non-blocking`);
80
+ return degradedProceed(candidate);
81
+ }
82
+ // Step 3 — mode gate.
83
+ const hasCollision = preflight.pendingCollision !== null;
84
+ if (mode === 'preventative' && hasCollision) {
85
+ return {
86
+ decision: 'block',
87
+ candidate,
88
+ preflight,
89
+ resultPatch: {
90
+ installComplete: false,
91
+ pendingCollision: preflight.pendingCollision ?? undefined,
92
+ warnings: preflight.warnings.length > 0 ? preflight.warnings : undefined,
93
+ },
94
+ };
95
+ }
96
+ // power_user / governance / preventative-without-collision all proceed.
97
+ return {
98
+ decision: 'proceed',
99
+ candidate,
100
+ preflight,
101
+ resultPatch: {
102
+ installComplete: true,
103
+ warnings: preflight.warnings.length > 0 ? preflight.warnings : undefined,
104
+ },
105
+ };
106
+ }
107
+ /**
108
+ * Degraded-proceed shape used when ledger read, inventory scan, or
109
+ * pre-flight throws. Caller continues the install with no warnings.
110
+ *
111
+ * `auditId` is allocated via `newAuditId()` even on the degraded path so
112
+ * the `AuditId` brand invariant holds for any defensive consumer that
113
+ * reads `preflight.auditId` without checking `decision` first.
114
+ */
115
+ function degradedProceed(candidate) {
116
+ return {
117
+ decision: 'proceed',
118
+ candidate,
119
+ preflight: {
120
+ warnings: [],
121
+ pendingCollision: null,
122
+ auditId: newAuditId(),
123
+ },
124
+ resultPatch: {
125
+ installComplete: true,
126
+ },
127
+ };
128
+ }
129
+ //# sourceMappingURL=install.namespace-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.namespace-gate.js","sourceRoot":"","sources":["../../../src/tools/install.namespace-gate.ts"],"names":[],"mappings":"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"}