@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,326 @@
1
+ /**
2
+ * @fileoverview Edit-suggester core (SMI-4589 Wave 3 Steps 2-3).
3
+ * @module @skillsmith/mcp-server/audit/edit-suggester
4
+ *
5
+ * Takes the semantic-collision flags from Wave 1's `InventoryAuditResult`
6
+ * and produces `RecommendedEdit[]` — templated, deterministic prose-edit
7
+ * suggestions. No LLM calls. No fuzziness.
8
+ *
9
+ * Per-template gate (ratified 2026-05-01): v1 ships only
10
+ * `add_domain_qualifier` (4.10/5 from GPT-5.4 reviewer-#2 scoring). The
11
+ * other two templates (`narrow_scope` 1.70/5, `reword_trigger_verb`
12
+ * 2.35/5) FAILED the gate and are NOT shipped in any form — neither as
13
+ * auto-apply nor as `manual_review`. They route to SMI-4593 for
14
+ * reauthoring. Test cases 2-3 in `edit-suggester.test.ts` assert empty
15
+ * output for collisions that would have matched those failing templates,
16
+ * guarding against accidental re-registration before the gate clears.
17
+ *
18
+ * Dispatch pattern (plan §1):
19
+ * 1. Walk `result.semanticCollisions[]`, collect unique file paths
20
+ * across the surviving template's `applies()` checks.
21
+ * 2. `await Promise.all(uniqueFilePaths.map(fs.readFile))` — single
22
+ * parallel read phase. Latency budget is linear in unique-files,
23
+ * not templates × collisions.
24
+ * 3. Iterate flags; for each, walk templates pre-sorted by descending
25
+ * `priority`; first `applies()` true wins; `generate()` is
26
+ * synchronous over the cached `fileContent`.
27
+ * 4. Filter null results (template matched but generate() couldn't
28
+ * synthesize a valid edit — e.g. file content drifted).
29
+ *
30
+ * Plan: docs/internal/implementation/smi-4589-edit-suggester.md §1, §Steps 2-3.
31
+ */
32
+ import * as fs from 'node:fs/promises';
33
+ /**
34
+ * `add_domain_qualifier` template. Fires for `description_overlap` flags
35
+ * where one entry has a `meta.tags[0]` value the other lacks. Inserts
36
+ * `for <tag> tasks` after the trigger verb in the description, narrowing
37
+ * the trigger surface enough to differentiate from the partner.
38
+ *
39
+ * Per-template gate verdict 2026-05-01: 4.10/5 (GPT-5.4 reviewer-#2).
40
+ * PASS — registered in `APPLY_TEMPLATE_REGISTRY`.
41
+ */
42
+ const ADD_DOMAIN_QUALIFIER = {
43
+ category: 'description_overlap',
44
+ pattern: 'add_domain_qualifier',
45
+ priority: 100,
46
+ applies(flag) {
47
+ // Both entries must carry a description (the prose surface we mutate),
48
+ // and at least one entry must have a unique tag the other lacks (the
49
+ // qualifier text we insert). The tag-asymmetry check is the
50
+ // distinguishing feature of `add_domain_qualifier` versus a hypothetical
51
+ // `narrow_scope` template — same shape but different remediation.
52
+ const aTag = pickQualifierTag(flag.entryA, flag.entryB);
53
+ const bTag = pickQualifierTag(flag.entryB, flag.entryA);
54
+ if (aTag === null && bTag === null)
55
+ return false;
56
+ if (!flag.entryA.meta?.description && !flag.entryB.meta?.description) {
57
+ return false;
58
+ }
59
+ return true;
60
+ },
61
+ generate(flag, context) {
62
+ // Pick the entry on whose file we'll mutate. Prefer the one with a
63
+ // unique tag (the qualifier text comes from that tag). If both have
64
+ // unique tags, prefer entryA — deterministic by `applies()` ordering.
65
+ const aTag = pickQualifierTag(flag.entryA, flag.entryB);
66
+ const target = aTag !== null ? { entry: flag.entryA, tag: aTag, partner: flag.entryB } : null;
67
+ const fallback = target !== null
68
+ ? target
69
+ : (() => {
70
+ const bTag = pickQualifierTag(flag.entryB, flag.entryA);
71
+ return bTag !== null ? { entry: flag.entryB, tag: bTag, partner: flag.entryA } : null;
72
+ })();
73
+ if (!fallback)
74
+ return null;
75
+ const description = fallback.entry.meta?.description;
76
+ if (!description)
77
+ return null;
78
+ // Locate the description block in the file. Skill SKILL.md uses YAML
79
+ // frontmatter with a `description:` key; we match the description text
80
+ // verbatim and identify the line range it spans. Multi-line block-scalar
81
+ // descriptions are handled by line-range expansion (start = first line,
82
+ // end = last line whose trimmed text appears in the description).
83
+ const located = locateDescription(context.fileContent, description);
84
+ if (!located)
85
+ return null;
86
+ // Compose the after-snippet by injecting `for <tag> tasks` after the
87
+ // first trigger verb in the description. The trigger verb is the first
88
+ // word matching /^(use|trigger|run|when|whenever|invoke)/i; if none
89
+ // matches, we prepend `for <tag> tasks: ` to the description body
90
+ // instead. Either way the edit is deterministic.
91
+ const after = injectQualifier(located.snippet, fallback.tag);
92
+ if (after === null || after === located.snippet) {
93
+ // Snippet didn't change — would emit a no-op edit. Skip.
94
+ return null;
95
+ }
96
+ const cosine = flag.cosineScore.toFixed(2);
97
+ const rationale = `differentiates from \`${fallback.partner.identifier}\` (cosine ${cosine}) by inserting domain qualifier "for ${fallback.tag} tasks"`;
98
+ return {
99
+ collisionId: flag.collisionId,
100
+ category: 'description_overlap',
101
+ pattern: 'add_domain_qualifier',
102
+ filePath: fallback.entry.source_path,
103
+ lineRange: { start: located.startLine, end: located.endLine },
104
+ before: located.snippet,
105
+ after,
106
+ rationale,
107
+ applyAction: 'recommended_edit',
108
+ // Per-template gate cleared: ships at apply_with_confirmation.
109
+ applyMode: 'apply_with_confirmation',
110
+ otherEntry: {
111
+ identifier: fallback.partner.identifier,
112
+ sourcePath: fallback.partner.source_path,
113
+ },
114
+ };
115
+ },
116
+ };
117
+ /**
118
+ * Registry of templates that ship in v1. Pre-sorted by descending
119
+ * priority. The dispatcher walks this list per flag.
120
+ *
121
+ * Wave 3 ships a single template (`add_domain_qualifier`). SMI-4593
122
+ * reauthors `narrow_scope` and `reword_trigger_verb` and re-registers
123
+ * them upon clearing the per-template gate.
124
+ */
125
+ const V1_TEMPLATES = [ADD_DOMAIN_QUALIFIER];
126
+ /**
127
+ * Run the edit-suggester over an `InventoryAuditResult`'s semantic
128
+ * collisions. Returns `RecommendedEdit[]` — one per flag that matches a
129
+ * registered template AND whose template successfully synthesized a
130
+ * non-empty edit.
131
+ *
132
+ * Order of returned edits: same as `result.semanticCollisions[]` input
133
+ * order. Tests assert this stability so PR diffs in the audit-report
134
+ * markdown are deterministic.
135
+ *
136
+ * I/O: reads each unique referenced file ONCE, in parallel, before
137
+ * iterating templates. Templates see only `fileContent` strings, not
138
+ * paths — keeps templates pure and unit-testable without fixtures on
139
+ * disk.
140
+ *
141
+ * Failure model: any per-flag template error (fileRead failure, snippet
142
+ * locate failure, `generate()` returning null) skips that flag silently.
143
+ * The other flags still produce edits. An empty
144
+ * `result.semanticCollisions[]` short-circuits with no I/O.
145
+ */
146
+ export async function runEditSuggester(result, opts) {
147
+ if (result.semanticCollisions.length === 0)
148
+ return [];
149
+ const templates = sortByPriority(opts?.templateOverrides ?? V1_TEMPLATES);
150
+ if (templates.length === 0)
151
+ return [];
152
+ // Phase 1: collect unique file paths referenced by any flag whose
153
+ // partner-pair would feed into a template's `applies()`.
154
+ const uniquePaths = new Set();
155
+ for (const flag of result.semanticCollisions) {
156
+ uniquePaths.add(flag.entryA.source_path);
157
+ uniquePaths.add(flag.entryB.source_path);
158
+ }
159
+ // Phase 2: parallel reads. Failed reads degrade to `null` content; the
160
+ // template will return null when it can't locate the description.
161
+ const fileCache = new Map();
162
+ await Promise.all(Array.from(uniquePaths).map(async (filePath) => {
163
+ try {
164
+ const content = await fs.readFile(filePath, 'utf-8');
165
+ fileCache.set(filePath, content);
166
+ }
167
+ catch (err) {
168
+ // Soft-warn; per plan §Tests case 9 a missing file emits no edit.
169
+ console.warn(`[edit-suggester] read failed for ${filePath} (${err.message}); skipping flags that target it`);
170
+ fileCache.set(filePath, null);
171
+ }
172
+ }));
173
+ // Phase 3: iterate flags, dispatch to templates synchronously over
174
+ // cached content.
175
+ const edits = [];
176
+ for (const flag of result.semanticCollisions) {
177
+ const template = templates.find((t) => t.applies(flag));
178
+ if (!template)
179
+ continue;
180
+ // Templates target one of the two entries' files. We let `generate()`
181
+ // pick which (it has the asymmetry logic). For now, hand it whichever
182
+ // entry's file content is available — `generate()` will return null
183
+ // if it needed the other side. We pick entryA's content first since
184
+ // `add_domain_qualifier`'s `generate` prefers entryA when both have
185
+ // unique tags.
186
+ const aContent = fileCache.get(flag.entryA.source_path);
187
+ const bContent = fileCache.get(flag.entryB.source_path);
188
+ const candidates = [aContent ?? null, bContent ?? null];
189
+ let edit = null;
190
+ for (const content of candidates) {
191
+ if (!content)
192
+ continue;
193
+ const generated = template.generate(flag, { fileContent: content });
194
+ if (generated) {
195
+ edit = generated;
196
+ break;
197
+ }
198
+ }
199
+ if (edit)
200
+ edits.push(edit);
201
+ }
202
+ return edits;
203
+ }
204
+ // ---------------------------------------------------------------------------
205
+ // Template helpers (kept inline; ~150-LOC budget for this file)
206
+ // ---------------------------------------------------------------------------
207
+ /**
208
+ * Stable-sort templates by descending priority. Stable to preserve
209
+ * registration order on ties.
210
+ */
211
+ function sortByPriority(templates) {
212
+ return [...templates].sort((a, b) => b.priority - a.priority);
213
+ }
214
+ /**
215
+ * Pick the first tag from `entry` that does NOT appear in `partner.meta.tags`.
216
+ * Returns `null` if `entry` has no tags or all tags overlap.
217
+ */
218
+ function pickQualifierTag(entry, partner) {
219
+ const ours = entry.meta?.tags ?? [];
220
+ const theirs = new Set(partner.meta?.tags ?? []);
221
+ for (const tag of ours) {
222
+ if (typeof tag !== 'string')
223
+ continue;
224
+ const trimmed = tag.trim();
225
+ if (!trimmed)
226
+ continue;
227
+ if (!theirs.has(trimmed))
228
+ return trimmed;
229
+ }
230
+ return null;
231
+ }
232
+ /**
233
+ * Locate the `description` text block within `fileContent`. Returns the
234
+ * matched snippet plus 1-indexed inclusive line range, or `null` if the
235
+ * description cannot be located (file content drifted since scan time).
236
+ *
237
+ * Strategy: split the description into lines (trimmed), then scan
238
+ * fileContent line-by-line for the first line that matches the first
239
+ * description line. Once anchored, walk forward to confirm subsequent
240
+ * description lines match in order. Returns the byte-exact snippet from
241
+ * the original file (preserves leading whitespace, comments, etc.).
242
+ */
243
+ function locateDescription(fileContent, description) {
244
+ const fileLines = fileContent.split('\n');
245
+ const descLines = description
246
+ .split('\n')
247
+ .map((l) => l.trim())
248
+ .filter((l) => l.length > 0);
249
+ if (descLines.length === 0)
250
+ return null;
251
+ for (let i = 0; i < fileLines.length; i++) {
252
+ const fileLine = fileLines[i]?.trim() ?? '';
253
+ if (!fileLine.includes(descLines[0]))
254
+ continue;
255
+ // Try to match all description lines in order from this anchor.
256
+ let cursor = i;
257
+ let matched = true;
258
+ for (let j = 0; j < descLines.length; j++) {
259
+ // Walk forward; allow blank lines between description fragments.
260
+ while (cursor < fileLines.length) {
261
+ const candidate = fileLines[cursor]?.trim() ?? '';
262
+ if (candidate.includes(descLines[j]))
263
+ break;
264
+ if (candidate.length === 0 && j > 0) {
265
+ cursor++;
266
+ continue;
267
+ }
268
+ matched = false;
269
+ break;
270
+ }
271
+ if (!matched || cursor >= fileLines.length) {
272
+ matched = false;
273
+ break;
274
+ }
275
+ if (j < descLines.length - 1)
276
+ cursor++;
277
+ }
278
+ if (matched) {
279
+ const startLine = i + 1; // 1-indexed
280
+ const endLine = cursor + 1;
281
+ const snippet = fileLines.slice(i, cursor + 1).join('\n');
282
+ return { snippet, startLine, endLine };
283
+ }
284
+ }
285
+ return null;
286
+ }
287
+ /**
288
+ * Insert ` for <tag> tasks` after the first trigger verb match in
289
+ * `snippet`. If no trigger verb is found, prepend `for <tag> tasks: ` to
290
+ * the description body (after any leading frontmatter prefix like
291
+ * `description:`).
292
+ *
293
+ * Returns the modified snippet, or `null` if the qualifier text is
294
+ * already present (idempotent — no-op edits are filtered out by caller).
295
+ */
296
+ function injectQualifier(snippet, tag) {
297
+ const qualifierPhrase = `for ${tag} tasks`;
298
+ if (snippet.toLowerCase().includes(qualifierPhrase.toLowerCase())) {
299
+ // Already qualified.
300
+ return null;
301
+ }
302
+ // Trigger-verb pattern: case-insensitive match for verb at start of a
303
+ // word boundary, optionally preceded by `description:` prefix.
304
+ const triggerVerbPattern = /\b(use|trigger|run|when|whenever|invoke)\b(\s+\w+)?/i;
305
+ const match = triggerVerbPattern.exec(snippet);
306
+ if (match && match.index >= 0) {
307
+ const insertAt = match.index + match[0].length;
308
+ return `${snippet.slice(0, insertAt)} ${qualifierPhrase}${snippet.slice(insertAt)}`;
309
+ }
310
+ // No trigger verb: inject after the description-key prefix if present,
311
+ // else prepend to the snippet body.
312
+ const descKeyMatch = /^(\s*description\s*:\s*)(.*)$/im.exec(snippet);
313
+ if (descKeyMatch && descKeyMatch.index >= 0) {
314
+ const prefix = descKeyMatch[1];
315
+ const rest = descKeyMatch[2];
316
+ return snippet.replace(descKeyMatch[0], `${prefix}${qualifierPhrase}: ${rest}`);
317
+ }
318
+ return `${qualifierPhrase}: ${snippet}`;
319
+ }
320
+ /**
321
+ * Public registry-key accessor. Re-exports the pattern strings so the
322
+ * apply-path registry (`edit-applier.ts`) can import a single source of
323
+ * truth instead of stringly-typed literals.
324
+ */
325
+ export const V1_TEMPLATE_PATTERNS = V1_TEMPLATES.map((t) => t.pattern);
326
+ //# sourceMappingURL=edit-suggester.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-suggester.js","sourceRoot":"","sources":["../../../src/audit/edit-suggester.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * @fileoverview Type vocabulary for the edit-suggester (SMI-4589 Wave 3 Step 1).
3
+ * @module @skillsmith/mcp-server/audit/edit-suggester.types
4
+ *
5
+ * Defines `RecommendedEdit`, `EditCategory`, `EditTemplate` — the public
6
+ * surface consumed by Wave 3's audit-report writer extension, install
7
+ * pre-flight wiring, and Wave 4's MCP `apply_recommended_edit` tool surface.
8
+ *
9
+ * The shapes are deliberately additive: `RecommendedEdit` does not extend
10
+ * `RenameSuggestion` (Wave 2) because the `before`/`after` snippet pair has
11
+ * no analogue in the rename surface — coupling them would force the rename
12
+ * engine to carry prose-edit fields it never uses.
13
+ *
14
+ * Plan: docs/internal/implementation/smi-4589-edit-suggester.md §1.
15
+ */
16
+ import type { CollisionId, SemanticCollisionFlag } from './collision-detector.types.js';
17
+ /**
18
+ * Which class of prose collision a `RecommendedEdit` addresses.
19
+ *
20
+ * - `description_overlap` — two SKILL.md descriptions semantically overlap
21
+ * (cosine ≥0.75). Renaming doesn't help; the descriptions need to
22
+ * differentiate.
23
+ * - `claude_md_trigger_overlap` — two CLAUDE.md trigger phrases semantically
24
+ * overlap. Renaming the file doesn't help; the prose needs to change.
25
+ *
26
+ * v1 ships only `description_overlap` via the `add_domain_qualifier`
27
+ * template. `claude_md_trigger_overlap` (paired with the
28
+ * `reword_trigger_verb` template) FAILED the per-template gate at 2.35/5
29
+ * and is dropped from v1 — see plan §"Wave 3 ship gate". The category enum
30
+ * still ships so SMI-4593's reauthored template body has a stable value to
31
+ * register against without a follow-up type change.
32
+ */
33
+ export type EditCategory = 'description_overlap' | 'claude_md_trigger_overlap';
34
+ /**
35
+ * The narrow set of template patterns the edit-suggester knows about. v1
36
+ * ships `add_domain_qualifier` only (4.10/5 from GPT-5.4 reviewer-#2
37
+ * scoring). The other two templates failed the per-template gate at
38
+ * 2.35/5 and 1.70/5 respectively; SMI-4593 reauthors them.
39
+ *
40
+ * The string union is the canonical allowlist key for
41
+ * `APPLY_TEMPLATE_REGISTRY` in `edit-applier.ts`. Adding a new pattern
42
+ * here without registering it in that allowlist is a TS error (the apply
43
+ * path narrows on the registry literal); adding it to the allowlist
44
+ * without re-scoring against the per-template gate is caught at
45
+ * plan-review time per the Wave 3 plan §6.
46
+ */
47
+ export type EditTemplatePattern = 'add_domain_qualifier' | 'narrow_scope' | 'reword_trigger_verb';
48
+ /**
49
+ * One concrete prose-edit recommendation surfaced by `runEditSuggester`.
50
+ *
51
+ * Wave 3 emits these in two surfaces:
52
+ *
53
+ * 1. Audit-report writer's "Recommended Edits" section (rendered as a
54
+ * `diff` fenced markdown block per plan §2).
55
+ * 2. `NamespaceWarning.recommendedEdit` field for `description_overlap`
56
+ * collisions surfaced at install pre-flight time (plan §3).
57
+ *
58
+ * Wave 4's `apply_recommended_edit` MCP tool consumes this shape directly
59
+ * — `applyMode: 'apply_with_confirmation'` is the green-light for the
60
+ * tool to mutate the file, gated by `APPLY_TEMPLATE_REGISTRY`.
61
+ */
62
+ export interface RecommendedEdit {
63
+ /** Matches the source `SemanticCollisionFlag.collisionId` from Wave 1. */
64
+ collisionId: CollisionId;
65
+ /** Which prose-collision class this edit addresses. */
66
+ category: EditCategory;
67
+ /** Template pattern that generated the edit (registry allowlist key). */
68
+ pattern: EditTemplatePattern;
69
+ /** Absolute path to the file to mutate (SKILL.md or CLAUDE.md). */
70
+ filePath: string;
71
+ /** 1-indexed inclusive line range covering the `before` snippet. */
72
+ lineRange: {
73
+ start: number;
74
+ end: number;
75
+ };
76
+ /**
77
+ * Exact current snippet at `filePath:lineRange`. The applier validates
78
+ * this matches byte-for-byte before mutating; mismatch returns
79
+ * `error: 'edit.stale_before'` and the file is untouched.
80
+ */
81
+ before: string;
82
+ /**
83
+ * Templated proposed text. Deterministic — no LLM rewrite. v1 inserts
84
+ * `for <tag> tasks` after the trigger verb in the description.
85
+ */
86
+ after: string;
87
+ /**
88
+ * Human-readable rationale, e.g.
89
+ * `"differentiates from skillsmith/release-tools (cosine 0.82)"`.
90
+ * Surfaced verbatim in the audit-report markdown and in the install
91
+ * pre-flight warning message.
92
+ */
93
+ rationale: string;
94
+ /**
95
+ * Always `'recommended_edit'`. Distinguishes the prose-edit surface
96
+ * from Wave 2's rename surface (`'rename_command_file'` etc.) when
97
+ * agents introspect heterogeneous suggestion lists.
98
+ */
99
+ applyAction: 'recommended_edit';
100
+ /**
101
+ * `'manual_review'` — render in the audit report only; no mutation
102
+ * path. `'apply_with_confirmation'` — agent may auto-apply via
103
+ * `apply_recommended_edit` after user confirmation.
104
+ *
105
+ * v1: `add_domain_qualifier` (the only registered template) ships at
106
+ * `'apply_with_confirmation'`. `runEditSuggester` does NOT emit any
107
+ * edit at `'manual_review'` mode in v1 — the failing templates are
108
+ * absent from output entirely per plan R-4/R-8.
109
+ */
110
+ applyMode: 'manual_review' | 'apply_with_confirmation';
111
+ /**
112
+ * Cross-reference to the partner skill in the original collision flag.
113
+ * Lets the audit report say "differentiates from <other>" without
114
+ * forcing the writer to re-read inventory state.
115
+ */
116
+ otherEntry: {
117
+ identifier: string;
118
+ sourcePath: string;
119
+ };
120
+ }
121
+ /**
122
+ * One template implementation. `applies()` is a synchronous predicate over
123
+ * the flag; `generate()` is synchronous over `flag + fileContent` (the
124
+ * dispatcher pre-reads files in parallel before iterating templates per
125
+ * plan §1 async dispatch pattern).
126
+ *
127
+ * Templates return `null` from `generate()` when the flag matches but the
128
+ * synthesized edit can't be produced (e.g. line-range extraction fails
129
+ * because the file changed under us). The caller skips silently — the
130
+ * user still sees the warning + cosine score from Wave 1.
131
+ */
132
+ export interface EditTemplate {
133
+ category: EditCategory;
134
+ pattern: EditTemplatePattern;
135
+ /**
136
+ * Higher fires first within a flag. Tiebreak by registration order —
137
+ * the dispatcher is stable. v1 ships a single template per category so
138
+ * priority is informational only, but the field is load-bearing for
139
+ * the SMI-4593 reauthoring path that may register additional templates
140
+ * against the same category.
141
+ */
142
+ priority: number;
143
+ applies(flag: SemanticCollisionFlag): boolean;
144
+ generate(flag: SemanticCollisionFlag, context: {
145
+ fileContent: string;
146
+ }): RecommendedEdit | null;
147
+ }
148
+ //# sourceMappingURL=edit-suggester.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-suggester.types.d.ts","sourceRoot":"","sources":["../../../src/audit/edit-suggester.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AAEvF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,YAAY,GAAG,qBAAqB,GAAG,2BAA2B,CAAA;AAE9E;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,mBAAmB,GAAG,sBAAsB,GAAG,cAAc,GAAG,qBAAqB,CAAA;AAEjG;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAe;IAC9B,0EAA0E;IAC1E,WAAW,EAAE,WAAW,CAAA;IACxB,uDAAuD;IACvD,QAAQ,EAAE,YAAY,CAAA;IACtB,yEAAyE;IACzE,OAAO,EAAE,mBAAmB,CAAA;IAC5B,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAA;IAChB,oEAAoE;IACpE,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IACzC;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,WAAW,EAAE,kBAAkB,CAAA;IAC/B;;;;;;;;;OASG;IACH,SAAS,EAAE,eAAe,GAAG,yBAAyB,CAAA;IACtD;;;;OAIG;IACH,UAAU,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAA;CACvD;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,YAAY,CAAA;IACtB,OAAO,EAAE,mBAAmB,CAAA;IAC5B;;;;;;OAMG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAA;IAC7C,QAAQ,CAAC,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,eAAe,GAAG,IAAI,CAAA;CAChG"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @fileoverview Type vocabulary for the edit-suggester (SMI-4589 Wave 3 Step 1).
3
+ * @module @skillsmith/mcp-server/audit/edit-suggester.types
4
+ *
5
+ * Defines `RecommendedEdit`, `EditCategory`, `EditTemplate` — the public
6
+ * surface consumed by Wave 3's audit-report writer extension, install
7
+ * pre-flight wiring, and Wave 4's MCP `apply_recommended_edit` tool surface.
8
+ *
9
+ * The shapes are deliberately additive: `RecommendedEdit` does not extend
10
+ * `RenameSuggestion` (Wave 2) because the `before`/`after` snippet pair has
11
+ * no analogue in the rename surface — coupling them would force the rename
12
+ * engine to carry prose-edit fields it never uses.
13
+ *
14
+ * Plan: docs/internal/implementation/smi-4589-edit-suggester.md §1.
15
+ */
16
+ export {};
17
+ //# sourceMappingURL=edit-suggester.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-suggester.types.js","sourceRoot":"","sources":["../../../src/audit/edit-suggester.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @fileoverview `claudeCodeAdapter` — v1 implementation of `FrameworkAdapter`.
3
+ * Wraps Wave 1's `scanLocalInventory`, Wave 2's `applyRename`,
4
+ * and Wave 3's `applyRecommendedEdit` behind a uniform seam.
5
+ * @module @skillsmith/mcp-server/audit/framework-adapter
6
+ *
7
+ * Plan: docs/internal/implementation/smi-4590-cli-mcp-framework-adapter.md §5.
8
+ *
9
+ * v1 contract (Claude-Code only):
10
+ * - `scanPaths` delegates to `scanLocalInventory` and returns `entries[]`.
11
+ * - `applyAction({kind:'rename'})` is REFUSED — a thin {from, to} pair
12
+ * cannot reconstruct the `InventoryEntry` Wave 2's `applyRename`
13
+ * needs (kind discriminator, identifier, source_path), and a raw
14
+ * `fs.rename` would bypass the backup + namespace ledger and leave
15
+ * the user without a revert path. Callers must use the
16
+ * `applyRename(entry, newName, { auditId })` convenience wrapper.
17
+ * The bare `{kind:'rename'}` shape stays in the union as a forward-
18
+ * compat surface for v2 adapters that own their own audit-history.
19
+ * - `applyAction({kind:'inline-edit', searchMode:'literal'})` translates
20
+ * the action into a Wave 3 `RecommendedEdit` and dispatches to
21
+ * `applyRecommendedEdit`. Requires `action.auditId` + `action.pattern`;
22
+ * missing context throws `namespace.adapter.missing_context`.
23
+ * - `applyAction({kind:'inline-edit', searchMode:'regex'})` throws the
24
+ * typed error `namespace.adapter.unsupported_search_mode`. Reserved
25
+ * for v2 cursorAdapter.
26
+ * - Convenience wrappers `applyRename` + `applyEdit` build the right
27
+ * `AdapterAction` shape from inventory/edit context and call
28
+ * `applyAction`. They do NOT re-implement Wave 2/3 — the rename
29
+ * wrapper goes through Wave 2's full path (backup + ledger), and the
30
+ * edit wrapper goes through Wave 3's `applyRecommendedEdit`.
31
+ */
32
+ import { newAuditId } from './audit-history.js';
33
+ import type { FileRenameAction, FrameworkAdapter, InlineEditAction } from './framework-adapter.types.js';
34
+ /**
35
+ * Typed error class for adapter-layer failures. Callers `switch` on
36
+ * `kind` to branch on the failure mode without parsing strings.
37
+ */
38
+ export declare class FrameworkAdapterError extends Error {
39
+ readonly kind: 'namespace.adapter.unsupported_search_mode' | 'namespace.adapter.missing_context' | 'namespace.adapter.unsupported_action' | 'namespace.adapter.template_not_in_apply_registry' | 'namespace.adapter.search_not_found' | 'namespace.adapter.search_not_unique' | 'namespace.adapter.subcall_failed';
40
+ /**
41
+ * For `'subcall_failed'`, carries the inner typed-error `kind` from
42
+ * Wave 2 (`RenameError`) or Wave 3 (`EditApplyError`) so callers can
43
+ * `switch` on it without parsing strings.
44
+ */
45
+ readonly innerKind?: string;
46
+ constructor(kind: FrameworkAdapterError['kind'], message: string, innerKind?: string);
47
+ }
48
+ /**
49
+ * v1 implementation of `FrameworkAdapter` for Claude-Code.
50
+ */
51
+ export declare const claudeCodeAdapter: FrameworkAdapter;
52
+ export { newAuditId };
53
+ export type { FileRenameAction, InlineEditAction };
54
+ //# sourceMappingURL=framework-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework-adapter.d.ts","sourceRoot":"","sources":["../../../src/audit/framework-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAIH,OAAO,EAAE,UAAU,EAAqB,MAAM,oBAAoB,CAAA;AAQlE,OAAO,KAAK,EAEV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,8BAA8B,CAAA;AAErC;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,SAAgB,IAAI,EAChB,2CAA2C,GAC3C,mCAAmC,GACnC,sCAAsC,GACtC,kDAAkD,GAClD,oCAAoC,GACpC,qCAAqC,GACrC,kCAAkC,CAAA;IAEtC;;;;OAIG;IACH,SAAgB,SAAS,CAAC,EAAE,MAAM,CAAA;gBAEtB,IAAI,EAAE,qBAAqB,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM;CAMrF;AA0ID;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,gBAwG/B,CAAA;AAGD,OAAO,EAAE,UAAU,EAAE,CAAA;AACrB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAA"}