@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,279 @@
1
+ /**
2
+ * @fileoverview Helpers for the local-inventory scanner (SMI-4587 Wave 1 Step 2).
3
+ * @module @skillsmith/mcp-server/utils/local-inventory.helpers
4
+ *
5
+ * Pure functions extracted to keep `local-inventory.ts` thin. CLAUDE.md
6
+ * regex extraction lives here so the regex behavior can be tested in
7
+ * isolation. Frontmatter helpers wrap the existing `parseYamlFrontmatter`.
8
+ */
9
+ import * as crypto from 'node:crypto';
10
+ import * as fs from 'node:fs';
11
+ import * as path from 'node:path';
12
+ import { parseYamlFrontmatter } from '../tools/validate.helpers.js';
13
+ /**
14
+ * Stable warning code catalog. Keep this in sync with the writer; the audit
15
+ * report renders messages keyed off `code`.
16
+ */
17
+ export const WARNING_CODES = {
18
+ TRIGGER_SURFACE_TRUNCATED: 'namespace.inventory.trigger_surface_truncated',
19
+ BOOTSTRAP_FAILED: 'namespace.inventory.bootstrap_failed',
20
+ CLAUDE_MD_RECALL_LOW: 'namespace.inventory.claude_md_recall_low',
21
+ REGEX_EXTRACTION_SKIPPED: 'namespace.inventory.regex_extraction_skipped',
22
+ UNMANAGED_SKILL_BOOTSTRAPPED: 'namespace.inventory.unmanaged_skill_bootstrapped',
23
+ PARSE_FAILED: 'namespace.inventory.parse_failed',
24
+ };
25
+ /** Maximum trigger phrases retained per entry — matches `OverlapDetector.MAX_TRIGGER_PHRASES_PER_SKILL`. */
26
+ export const MAX_TRIGGER_PHRASES_PER_SKILL = 50;
27
+ /**
28
+ * Cap an array of trigger phrases at MAX_TRIGGER_PHRASES_PER_SKILL. When
29
+ * truncation occurs, append a warning of code `trigger_surface_truncated`
30
+ * with the dropped count so the user sees it in the audit report.
31
+ */
32
+ export function capTriggerSurface(identifier, phrases, warnings) {
33
+ if (phrases.length <= MAX_TRIGGER_PHRASES_PER_SKILL) {
34
+ return phrases;
35
+ }
36
+ warnings.push({
37
+ code: WARNING_CODES.TRIGGER_SURFACE_TRUNCATED,
38
+ message: `triggerSurface for "${identifier}" was capped at ${MAX_TRIGGER_PHRASES_PER_SKILL} phrases (${phrases.length - MAX_TRIGGER_PHRASES_PER_SKILL} dropped)`,
39
+ context: {
40
+ entry_identifier: identifier,
41
+ dropped_count: phrases.length - MAX_TRIGGER_PHRASES_PER_SKILL,
42
+ },
43
+ });
44
+ return phrases.slice(0, MAX_TRIGGER_PHRASES_PER_SKILL);
45
+ }
46
+ /**
47
+ * Split a description into sentence-level trigger phrases. Empty or
48
+ * whitespace-only segments are filtered.
49
+ */
50
+ export function splitDescriptionToPhrases(description) {
51
+ if (!description)
52
+ return [];
53
+ // Split on sentence terminators; tolerate runs of whitespace and trailing
54
+ // punctuation. Not a strict NLP tokenizer — close-enough for trigger surface.
55
+ return description
56
+ .split(/[.!?\n]+/)
57
+ .map((s) => s.trim())
58
+ .filter((s) => s.length > 0);
59
+ }
60
+ /**
61
+ * Read the YAML frontmatter from a `.md` file. Returns `{}` if no
62
+ * frontmatter or the file cannot be parsed.
63
+ */
64
+ export function readFrontmatter(filePath) {
65
+ try {
66
+ const content = fs.readFileSync(filePath, 'utf-8');
67
+ return parseYamlFrontmatter(content) ?? {};
68
+ }
69
+ catch {
70
+ return {};
71
+ }
72
+ }
73
+ /**
74
+ * Extract the body of a `.md` file (everything after the closing
75
+ * frontmatter delimiter, or the full content if no frontmatter).
76
+ */
77
+ export function readBody(filePath) {
78
+ try {
79
+ const content = fs.readFileSync(filePath, 'utf-8');
80
+ if (!content.startsWith('---'))
81
+ return content;
82
+ const end = content.indexOf('---', 3);
83
+ if (end === -1)
84
+ return content;
85
+ return content.slice(end + 3).trimStart();
86
+ }
87
+ catch {
88
+ return '';
89
+ }
90
+ }
91
+ /**
92
+ * Pull the first non-empty line from a body string. Used as the fallback
93
+ * trigger surface for frontmatter-less command files.
94
+ */
95
+ export function firstNonEmptyLine(body) {
96
+ for (const line of body.split('\n')) {
97
+ const trimmed = line.trim();
98
+ if (trimmed)
99
+ return trimmed;
100
+ }
101
+ return '';
102
+ }
103
+ /**
104
+ * Stable identifier for a CLAUDE.md trigger line. The identifier doubles as
105
+ * dedup key — two scans of the same line produce the same id. Hashed
106
+ * because the line itself can be long; first 12 hex chars are sufficient.
107
+ */
108
+ export function hashClaudeMdLine(claudeMdPath, line) {
109
+ const norm = line.trim().toLowerCase();
110
+ const hash = crypto
111
+ .createHash('sha256')
112
+ .update(`${claudeMdPath}:${norm}`)
113
+ .digest('hex')
114
+ .slice(0, 12);
115
+ return `claude_md:${hash}`;
116
+ }
117
+ /**
118
+ * Best-effort regex extractor for CLAUDE.md trigger phrases.
119
+ *
120
+ * Two patterns are recognized (per Wave 0 spike goal #3):
121
+ *
122
+ * 1. Bullet items under headings matching
123
+ * `/^#{1,3}\s*(Trigger phrases|Use when|Skills)\b/i`. Recall is
124
+ * best-effort — false negatives expected for non-standard heading text.
125
+ * 2. Any line containing the high-confidence marker
126
+ * `<!-- skillsmith:trigger -->`. The full line is captured as a phrase.
127
+ *
128
+ * Returns one `InventoryEntry` per extracted line. Failures (file missing,
129
+ * unparseable) emit a `warnings[]` entry — never throw.
130
+ */
131
+ export function extractClaudeMdTriggers(claudeMdPath, warnings) {
132
+ let content;
133
+ try {
134
+ content = fs.readFileSync(claudeMdPath, 'utf-8');
135
+ }
136
+ catch {
137
+ // Missing file is silent (no CLAUDE.md is a normal state).
138
+ return [];
139
+ }
140
+ const entries = [];
141
+ let stat;
142
+ try {
143
+ stat = fs.statSync(claudeMdPath);
144
+ }
145
+ catch {
146
+ stat = undefined;
147
+ }
148
+ let captureMode = 'idle';
149
+ let lines;
150
+ try {
151
+ lines = content.split('\n');
152
+ }
153
+ catch {
154
+ warnings.push({
155
+ code: WARNING_CODES.REGEX_EXTRACTION_SKIPPED,
156
+ message: `CLAUDE.md at ${claudeMdPath} unparseable; trigger-phrase scan skipped`,
157
+ context: { path: claudeMdPath },
158
+ });
159
+ return [];
160
+ }
161
+ // Headings considered as trigger sections. Case-insensitive, allow up to
162
+ // three leading hashes (per spec line 104).
163
+ const headingRe = /^#{1,3}\s*(Trigger phrases|Use when|Skills)\b/i;
164
+ const otherHeadingRe = /^#{1,6}\s+/;
165
+ const bulletRe = /^[-*]\s+(.+)$/;
166
+ const markerRe = /<!--\s*skillsmith:trigger\s*-->/;
167
+ for (const rawLine of lines) {
168
+ const line = rawLine.trim();
169
+ if (markerRe.test(line)) {
170
+ // High-confidence marker line — capture the whole line minus the marker.
171
+ const phrase = line.replace(markerRe, '').trim();
172
+ if (phrase) {
173
+ entries.push(makeClaudeMdEntry(claudeMdPath, phrase, stat?.mtimeMs));
174
+ }
175
+ continue;
176
+ }
177
+ if (headingRe.test(line)) {
178
+ captureMode = 'heading';
179
+ continue;
180
+ }
181
+ // Reset capture mode on any other heading.
182
+ if (otherHeadingRe.test(line)) {
183
+ captureMode = 'idle';
184
+ continue;
185
+ }
186
+ if (captureMode === 'heading') {
187
+ const m = bulletRe.exec(line);
188
+ if (m && m[1]) {
189
+ const phrase = m[1].trim();
190
+ if (phrase) {
191
+ entries.push(makeClaudeMdEntry(claudeMdPath, phrase, stat?.mtimeMs));
192
+ }
193
+ }
194
+ }
195
+ }
196
+ return entries;
197
+ }
198
+ function makeClaudeMdEntry(claudeMdPath, phrase, mtime) {
199
+ return {
200
+ kind: 'claude_md_rule',
201
+ source_path: claudeMdPath,
202
+ identifier: hashClaudeMdLine(claudeMdPath, phrase),
203
+ triggerSurface: [phrase],
204
+ mtime,
205
+ meta: { description: phrase },
206
+ };
207
+ }
208
+ /**
209
+ * Resolve `~/.skillsmith/manifest.json` and return the parsed object, or
210
+ * `null` if absent / unreadable. Scanner uses this to populate
211
+ * `entry.meta.author` for installed skills.
212
+ */
213
+ export function loadManifest(manifestPath) {
214
+ try {
215
+ if (!fs.existsSync(manifestPath))
216
+ return null;
217
+ const raw = fs.readFileSync(manifestPath, 'utf-8');
218
+ return JSON.parse(raw);
219
+ }
220
+ catch {
221
+ return null;
222
+ }
223
+ }
224
+ /**
225
+ * Look up an `author` (and `tags`) for a given skill identifier in the
226
+ * manifest. Manifest shape varies — be tolerant: walk the top-level keys
227
+ * and any obvious `skills` array/object.
228
+ */
229
+ export function lookupAuthor(manifest, identifier) {
230
+ if (!manifest)
231
+ return {};
232
+ // Many manifest shapes possible; check common ones.
233
+ const skills = (manifest.skills ?? manifest.installed);
234
+ if (Array.isArray(skills)) {
235
+ for (const s of skills) {
236
+ if (s &&
237
+ typeof s === 'object' &&
238
+ (s.id === identifier ||
239
+ s.name === identifier)) {
240
+ const rec = s;
241
+ return {
242
+ author: typeof rec.author === 'string' ? rec.author : undefined,
243
+ tags: Array.isArray(rec.tags) ? rec.tags : undefined,
244
+ };
245
+ }
246
+ }
247
+ }
248
+ if (skills && typeof skills === 'object') {
249
+ const rec = skills[identifier];
250
+ if (rec && typeof rec === 'object') {
251
+ const r = rec;
252
+ return {
253
+ author: typeof r.author === 'string' ? r.author : undefined,
254
+ tags: Array.isArray(r.tags) ? r.tags : undefined,
255
+ };
256
+ }
257
+ }
258
+ return {};
259
+ }
260
+ /**
261
+ * Cross-platform mtime read. Returns `undefined` on stat failure rather
262
+ * than throwing — mtime is informational for ordering, not load-bearing.
263
+ */
264
+ export function readMtime(filePath) {
265
+ try {
266
+ return fs.statSync(filePath).mtimeMs;
267
+ }
268
+ catch {
269
+ return undefined;
270
+ }
271
+ }
272
+ /**
273
+ * Resolve absolute path joining `dir + filename`. Centralized so future
274
+ * portability work (E-ANTI-1 v2) can swap in a relative-to-home derivation.
275
+ */
276
+ export function joinPath(dir, filename) {
277
+ return path.join(dir, filename);
278
+ }
279
+ //# sourceMappingURL=local-inventory.helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-inventory.helpers.js","sourceRoot":"","sources":["../../../src/utils/local-inventory.helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAEjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AAGnE;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,yBAAyB,EAAE,+CAA+C;IAC1E,gBAAgB,EAAE,sCAAsC;IACxD,oBAAoB,EAAE,0CAA0C;IAChE,wBAAwB,EAAE,8CAA8C;IACxE,4BAA4B,EAAE,kDAAkD;IAChF,YAAY,EAAE,kCAAkC;CACxC,CAAA;AAEV,4GAA4G;AAC5G,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,CAAA;AAE/C;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,UAAkB,EAClB,OAAiB,EACjB,QAAuB;IAEvB,IAAI,OAAO,CAAC,MAAM,IAAI,6BAA6B,EAAE,CAAC;QACpD,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,QAAQ,CAAC,IAAI,CAAC;QACZ,IAAI,EAAE,aAAa,CAAC,yBAAyB;QAC7C,OAAO,EAAE,uBAAuB,UAAU,mBAAmB,6BAA6B,aAAa,OAAO,CAAC,MAAM,GAAG,6BAA6B,WAAW;QAChK,OAAO,EAAE;YACP,gBAAgB,EAAE,UAAU;YAC5B,aAAa,EAAE,OAAO,CAAC,MAAM,GAAG,6BAA6B;SAC9D;KACF,CAAC,CAAA;IAEF,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,6BAA6B,CAAC,CAAA;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,WAA+B;IACvE,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,CAAA;IAC3B,0EAA0E;IAC1E,8EAA8E;IAC9E,OAAO,WAAW;SACf,KAAK,CAAC,UAAU,CAAC;SACjB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAClD,OAAO,oBAAoB,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,QAAgB;IACvC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAClD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC;YAAE,OAAO,OAAO,CAAA;QAC9C,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;QACrC,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,OAAO,OAAO,CAAA;QAC9B,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAA;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAC3B,IAAI,OAAO;YAAE,OAAO,OAAO,CAAA;IAC7B,CAAC;IACD,OAAO,EAAE,CAAA;AACX,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,YAAoB,EAAE,IAAY;IACjE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IACtC,MAAM,IAAI,GAAG,MAAM;SAChB,UAAU,CAAC,QAAQ,CAAC;SACpB,MAAM,CAAC,GAAG,YAAY,IAAI,IAAI,EAAE,CAAC;SACjC,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IACf,OAAO,aAAa,IAAI,EAAE,CAAA;AAC5B,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,uBAAuB,CACrC,YAAoB,EACpB,QAAuB;IAEvB,IAAI,OAAe,CAAA;IACnB,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,2DAA2D;QAC3D,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,OAAO,GAAqB,EAAE,CAAA;IACpC,IAAI,IAA0B,CAAA;IAC9B,IAAI,CAAC;QACH,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,GAAG,SAAS,CAAA;IAClB,CAAC;IAED,IAAI,WAAW,GAAkC,MAAM,CAAA;IACvD,IAAI,KAAe,CAAA;IACnB,IAAI,CAAC;QACH,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,aAAa,CAAC,wBAAwB;YAC5C,OAAO,EAAE,gBAAgB,YAAY,2CAA2C;YAChF,OAAO,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE;SAChC,CAAC,CAAA;QACF,OAAO,EAAE,CAAA;IACX,CAAC;IAED,yEAAyE;IACzE,4CAA4C;IAC5C,MAAM,SAAS,GAAG,gDAAgD,CAAA;IAClE,MAAM,cAAc,GAAG,YAAY,CAAA;IACnC,MAAM,QAAQ,GAAG,eAAe,CAAA;IAChC,MAAM,QAAQ,GAAG,iCAAiC,CAAA;IAElD,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAA;QAE3B,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,yEAAyE;YACzE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;YAChD,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAA;YACtE,CAAC;YACD,SAAQ;QACV,CAAC;QAED,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,WAAW,GAAG,SAAS,CAAA;YACvB,SAAQ;QACV,CAAC;QAED,2CAA2C;QAC3C,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,WAAW,GAAG,MAAM,CAAA;YACpB,SAAQ;QACV,CAAC;QAED,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAC7B,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACd,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;gBAC1B,IAAI,MAAM,EAAE,CAAC;oBACX,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAA;gBACtE,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,SAAS,iBAAiB,CACxB,YAAoB,EACpB,MAAc,EACd,KAAyB;IAEzB,OAAO;QACL,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,YAAY;QACzB,UAAU,EAAE,gBAAgB,CAAC,YAAY,EAAE,MAAM,CAAC;QAClD,cAAc,EAAE,CAAC,MAAM,CAAC;QACxB,KAAK;QACL,IAAI,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE;KAC9B,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,YAAoB;IAC/C,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC;YAAE,OAAO,IAAI,CAAA;QAC7C,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;QAClD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAA;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAwC,EACxC,UAAkB;IAElB,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAA;IAExB,oDAAoD;IACpD,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAY,CAAA;IACjE,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,IACE,CAAC;gBACD,OAAO,CAAC,KAAK,QAAQ;gBACrB,CAAE,CAA6B,CAAC,EAAE,KAAK,UAAU;oBAC9C,CAA6B,CAAC,IAAI,KAAK,UAAU,CAAC,EACrD,CAAC;gBACD,MAAM,GAAG,GAAG,CAA4B,CAAA;gBACxC,OAAO;oBACL,MAAM,EAAE,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;oBAC/D,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,IAAiB,CAAC,CAAC,CAAC,SAAS;iBACnE,CAAA;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QACzC,MAAM,GAAG,GAAI,MAAkC,CAAC,UAAU,CAAC,CAAA;QAC3D,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACnC,MAAM,CAAC,GAAG,GAA8B,CAAA;YACxC,OAAO;gBACL,MAAM,EAAE,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;gBAC3D,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,IAAiB,CAAC,CAAC,CAAC,SAAS;aAC/D,CAAA;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAA;AACX,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAA;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,QAAgB;IACpD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;AACjC,CAAC"}
@@ -0,0 +1,202 @@
1
+ /**
2
+ * @fileoverview Local-inventory scanner for the consumer namespace audit.
3
+ * @module @skillsmith/mcp-server/utils/local-inventory
4
+ * @see SMI-4587 Wave 1 Step 2 — scan ~/.claude/{skills,commands,agents} +
5
+ * CLAUDE.md trigger phrases into a unified InventoryEntry[].
6
+ *
7
+ * Each source is independent — failure in one does not fail the others.
8
+ * The scanner is read-only; bootstrapping unmanaged skills via `index_local`
9
+ * is wired in a subsequent PR (Step 6a).
10
+ */
11
+ import * as fs from 'node:fs';
12
+ import * as os from 'node:os';
13
+ import * as path from 'node:path';
14
+ import { WARNING_CODES, capTriggerSurface, extractClaudeMdTriggers, firstNonEmptyLine, loadManifest, lookupAuthor, readBody, readFrontmatter, readMtime, splitDescriptionToPhrases, } from './local-inventory.helpers.js';
15
+ const DEFAULT_HOME_CLAUDE_DIR = path.join(os.homedir(), '.claude');
16
+ const DEFAULT_MANIFEST_PATH = path.join(os.homedir(), '.skillsmith', 'manifest.json');
17
+ /**
18
+ * Scan `~/.claude/{skills,commands,agents}` and CLAUDE.md trigger phrases.
19
+ *
20
+ * Returns `entries[]` sorted by `kind` then `identifier`, plus any soft
21
+ * `warnings[]` raised during scanning. `durationMs` measures wall-clock
22
+ * time for the whole scan (excluding the optional bootstrap step that
23
+ * lands in a subsequent PR).
24
+ */
25
+ export async function scanLocalInventory(opts = {}) {
26
+ const startedAt = process.hrtime.bigint();
27
+ const homeDir = opts.homeDir ?? os.homedir();
28
+ const claudeDir = opts.homeDir ? path.join(opts.homeDir, '.claude') : DEFAULT_HOME_CLAUDE_DIR;
29
+ const manifestPath = opts.manifestPath ?? DEFAULT_MANIFEST_PATH;
30
+ const warnings = [];
31
+ const entries = [];
32
+ const manifest = loadManifest(manifestPath);
33
+ // Source 1: ~/.claude/skills/*/SKILL.md
34
+ entries.push(...scanSkills(path.join(claudeDir, 'skills'), manifest, warnings));
35
+ // Source 2: ~/.claude/commands/*.md
36
+ entries.push(...scanCommands(path.join(claudeDir, 'commands'), warnings));
37
+ // Source 3: ~/.claude/agents/*.md
38
+ entries.push(...scanAgents(path.join(claudeDir, 'agents'), warnings));
39
+ // Source 4: ~/.claude/CLAUDE.md and (optional) project CLAUDE.md
40
+ const userClaudeMd = path.join(claudeDir, 'CLAUDE.md');
41
+ if (fs.existsSync(userClaudeMd)) {
42
+ entries.push(...extractClaudeMdTriggers(userClaudeMd, warnings));
43
+ }
44
+ if (opts.projectDir) {
45
+ const projectClaudeMd = path.join(opts.projectDir, 'CLAUDE.md');
46
+ if (fs.existsSync(projectClaudeMd)) {
47
+ entries.push(...extractClaudeMdTriggers(projectClaudeMd, warnings));
48
+ }
49
+ }
50
+ // Stable ordering for downstream consumers.
51
+ entries.sort((a, b) => {
52
+ if (a.kind !== b.kind)
53
+ return a.kind.localeCompare(b.kind);
54
+ return a.identifier.localeCompare(b.identifier);
55
+ });
56
+ const elapsedNs = process.hrtime.bigint() - startedAt;
57
+ const durationMs = Number(elapsedNs) / 1_000_000;
58
+ // Suppress unused-variable warning while keeping the homeDir resolution
59
+ // visible in opts handling above. Reserved for future per-OS path logic.
60
+ void homeDir;
61
+ return { entries, warnings, durationMs };
62
+ }
63
+ /**
64
+ * Scan `~/.claude/skills/*` for SKILL.md frontmatter. Returns one entry
65
+ * per directory; entries without SKILL.md are still recorded (with
66
+ * directory-name fallback) so the collision detector still sees them.
67
+ */
68
+ function scanSkills(skillsDir, manifest, warnings) {
69
+ if (!fs.existsSync(skillsDir))
70
+ return [];
71
+ const out = [];
72
+ let dirEntries;
73
+ try {
74
+ dirEntries = fs.readdirSync(skillsDir, { withFileTypes: true });
75
+ }
76
+ catch {
77
+ return [];
78
+ }
79
+ for (const dirent of dirEntries) {
80
+ if (!dirent.isDirectory() || dirent.name.startsWith('.'))
81
+ continue;
82
+ const skillDir = path.join(skillsDir, dirent.name);
83
+ const skillMd = path.join(skillDir, 'SKILL.md');
84
+ let identifier = dirent.name;
85
+ let description;
86
+ let mtime;
87
+ if (fs.existsSync(skillMd)) {
88
+ const fm = readFrontmatter(skillMd);
89
+ const fmName = typeof fm.name === 'string' ? fm.name : undefined;
90
+ if (fmName && fmName.trim())
91
+ identifier = fmName.trim();
92
+ const fmDesc = coerceDescription(fm.description);
93
+ if (fmDesc)
94
+ description = fmDesc;
95
+ mtime = readMtime(skillMd);
96
+ }
97
+ else {
98
+ // Skill directory without SKILL.md is unusual; record a soft warning
99
+ // so the audit report can flag it but do not block the scan.
100
+ warnings.push({
101
+ code: WARNING_CODES.PARSE_FAILED,
102
+ message: `skill directory ${skillDir} has no SKILL.md; using directory name as identifier`,
103
+ context: { path: skillDir },
104
+ });
105
+ }
106
+ const phrases = capTriggerSurface(identifier, [identifier, ...splitDescriptionToPhrases(description)], warnings);
107
+ const author = lookupAuthor(manifest, identifier);
108
+ out.push({
109
+ kind: 'skill',
110
+ source_path: skillMd,
111
+ identifier,
112
+ triggerSurface: phrases,
113
+ mtime,
114
+ meta: {
115
+ description,
116
+ author: author.author,
117
+ tags: author.tags,
118
+ },
119
+ });
120
+ }
121
+ return out;
122
+ }
123
+ /**
124
+ * Scan `~/.claude/commands/*.md`. Frontmatter `description:` wins as
125
+ * trigger surface; otherwise the first non-empty line of the body.
126
+ * Tolerates frontmatter-less files (most slash commands have none).
127
+ */
128
+ function scanCommands(commandsDir, warnings) {
129
+ if (!fs.existsSync(commandsDir))
130
+ return [];
131
+ return scanMdDir(commandsDir, 'command', warnings);
132
+ }
133
+ /**
134
+ * Scan `~/.claude/agents/*.md`. Subagent files always carry frontmatter
135
+ * `description:` per Claude Code convention; surface that. Falls back to
136
+ * filename + body first-line if frontmatter is absent.
137
+ */
138
+ function scanAgents(agentsDir, warnings) {
139
+ if (!fs.existsSync(agentsDir))
140
+ return [];
141
+ return scanMdDir(agentsDir, 'agent', warnings);
142
+ }
143
+ /**
144
+ * Shared scan logic for commands + agents — both follow the
145
+ * "filename = identifier; description from frontmatter or body" shape.
146
+ */
147
+ function scanMdDir(dir, kind, warnings) {
148
+ const out = [];
149
+ let dirEntries;
150
+ try {
151
+ dirEntries = fs.readdirSync(dir, { withFileTypes: true });
152
+ }
153
+ catch {
154
+ return [];
155
+ }
156
+ for (const dirent of dirEntries) {
157
+ if (!dirent.isFile())
158
+ continue;
159
+ if (!dirent.name.endsWith('.md'))
160
+ continue;
161
+ if (dirent.name.startsWith('.'))
162
+ continue;
163
+ const filePath = path.join(dir, dirent.name);
164
+ const identifier = dirent.name.slice(0, -3); // strip .md
165
+ const fm = readFrontmatter(filePath);
166
+ const description = coerceDescription(fm.description);
167
+ let triggerLine = description ?? '';
168
+ if (!triggerLine) {
169
+ triggerLine = firstNonEmptyLine(readBody(filePath));
170
+ }
171
+ const phrases = capTriggerSurface(identifier, [identifier, ...(triggerLine ? splitDescriptionToPhrases(triggerLine) : [])], warnings);
172
+ out.push({
173
+ kind,
174
+ source_path: filePath,
175
+ identifier,
176
+ triggerSurface: phrases,
177
+ mtime: readMtime(filePath),
178
+ meta: {
179
+ description: triggerLine || undefined,
180
+ },
181
+ });
182
+ }
183
+ return out;
184
+ }
185
+ /**
186
+ * `parseYamlFrontmatter` returns `string | string[] | undefined` for
187
+ * description (depending on block-scalar syntax). Normalize to a single
188
+ * string for downstream consumers.
189
+ */
190
+ function coerceDescription(value) {
191
+ if (typeof value === 'string')
192
+ return value.trim() || undefined;
193
+ if (Array.isArray(value)) {
194
+ const joined = value
195
+ .map((v) => (typeof v === 'string' ? v.trim() : ''))
196
+ .filter((v) => v.length > 0)
197
+ .join(' ');
198
+ return joined.length > 0 ? joined : undefined;
199
+ }
200
+ return undefined;
201
+ }
202
+ //# sourceMappingURL=local-inventory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-inventory.js","sourceRoot":"","sources":["../../../src/utils/local-inventory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * @fileoverview Type vocabulary for the local-inventory scanner (SMI-4587 Wave 1 Step 1).
3
+ * @module @skillsmith/mcp-server/utils/local-inventory.types
4
+ *
5
+ * Public surface consumed by the collision-detector + audit-history modules.
6
+ * Wave 2/3/4 import these types — keep stable and additive.
7
+ */
8
+ /**
9
+ * The four sources scanned by `scanLocalInventory`. Each kind carries different
10
+ * `triggerSurface` semantics; the collision detector handles them uniformly.
11
+ */
12
+ export type InventoryKind = 'skill' | 'command' | 'agent' | 'claude_md_rule';
13
+ /**
14
+ * One entry in the user's local inventory. Keyed by `kind` + `identifier`,
15
+ * sourced at `source_path`, with the trigger text used by the collision detector
16
+ * surfaced in `triggerSurface`.
17
+ */
18
+ export interface InventoryEntry {
19
+ kind: InventoryKind;
20
+ /** Absolute path to the source file. */
21
+ source_path: string;
22
+ /**
23
+ * Skills: name from frontmatter or directory fallback.
24
+ * Commands / agents: filename without `.md`.
25
+ * `claude_md_rule`: hashed line excerpt — see helpers.ts for the derivation.
26
+ */
27
+ identifier: string;
28
+ /** Phrases the collision detector matches against. */
29
+ triggerSurface: string[];
30
+ /**
31
+ * Last-modified timestamp (Unix epoch ms) from `fs.stat`. Populated by the
32
+ * scanner; consumed by the audit-report writer's mtime-based collision-cluster
33
+ * sort (most-recent first within each severity group).
34
+ */
35
+ mtime?: number;
36
+ meta?: {
37
+ /** From `~/.skillsmith/manifest.json` if registered; else undefined. */
38
+ author?: string;
39
+ tags?: string[];
40
+ /** Raw description for audit-report rendering. */
41
+ description?: string;
42
+ };
43
+ }
44
+ /**
45
+ * Soft-failure signal emitted by the scanner. `code` is a stable identifier
46
+ * (catalog in local-inventory.helpers.ts); `context` carries structured detail.
47
+ */
48
+ export interface ScanWarning {
49
+ /** Stable warning code; see WARNING_CODES in helpers. */
50
+ code: string;
51
+ /** Human-readable text for the audit report. */
52
+ message: string;
53
+ context?: Record<string, unknown>;
54
+ }
55
+ /**
56
+ * Output of `scanLocalInventory`. `warnings` are typed-coded objects (not
57
+ * strings) so report writers + telemetry can branch on `code` without parsing
58
+ * prose.
59
+ */
60
+ export interface ScanResult {
61
+ entries: InventoryEntry[];
62
+ warnings: ScanWarning[];
63
+ durationMs: number;
64
+ }
65
+ /** Brand type for ULID-shaped audit identifiers. */
66
+ export type AuditId = string & {
67
+ readonly __brand: 'AuditId';
68
+ };
69
+ /**
70
+ * Brand type for collision identifiers.
71
+ *
72
+ * Machine-local constraint (E-ANTI-1): derived from absolute filesystem paths
73
+ * via sha256(auditId + ':' + sortedEntryPaths.join(',')). Portability across
74
+ * home-directory renames is NOT supported in v1; if the user renames their
75
+ * home directory or moves skills, prior `namespace-overrides.json` ledger
76
+ * entries become unreachable. Acceptable for v1 (local-only tool); a v2
77
+ * follow-up will switch to a path-relative derivation.
78
+ */
79
+ export type CollisionId = string & {
80
+ readonly __brand: 'CollisionId';
81
+ };
82
+ /**
83
+ * Exact-name collision: two or more entries share the same normalized
84
+ * `identifier`. Severity is always `error` — exact collisions are unambiguous.
85
+ *
86
+ * Design note (E-CONF-2): no `suggestion` field. Wave 2's rename engine
87
+ * generates suggestions from `ExactCollisionFlag` entries; coupling a
88
+ * suggestion field here would force Wave 4's display logic into the detector
89
+ * module, breaking detection-only separation.
90
+ */
91
+ export interface ExactCollisionFlag {
92
+ kind: 'exact';
93
+ collisionId: CollisionId;
94
+ identifier: string;
95
+ /** Two or more entries colliding on the same identifier. */
96
+ entries: InventoryEntry[];
97
+ severity: 'error';
98
+ reason: string;
99
+ }
100
+ //# sourceMappingURL=local-inventory.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-inventory.types.d.ts","sourceRoot":"","sources":["../../../src/utils/local-inventory.types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,gBAAgB,CAAA;AAE5E;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,aAAa,CAAA;IACnB,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAA;IAClB,sDAAsD;IACtD,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE;QACL,wEAAwE;QACxE,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;QACf,kDAAkD;QAClD,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;CACF;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAA;IACZ,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAClC;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,cAAc,EAAE,CAAA;IACzB,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,oDAAoD;AACpD,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAA;CAAE,CAAA;AAE9D;;;;;;;;;GASG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAA;CAAE,CAAA;AAEtE;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAA;IACb,WAAW,EAAE,WAAW,CAAA;IACxB,UAAU,EAAE,MAAM,CAAA;IAClB,4DAA4D;IAC5D,OAAO,EAAE,cAAc,EAAE,CAAA;IACzB,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;CACf"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @fileoverview Type vocabulary for the local-inventory scanner (SMI-4587 Wave 1 Step 1).
3
+ * @module @skillsmith/mcp-server/utils/local-inventory.types
4
+ *
5
+ * Public surface consumed by the collision-detector + audit-history modules.
6
+ * Wave 2/3/4 import these types — keep stable and additive.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=local-inventory.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-inventory.types.js","sourceRoot":"","sources":["../../../src/utils/local-inventory.types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -61,6 +61,18 @@ export declare function startStripeWebhookServer(webhookServer: StripeWebhookSer
61
61
  port?: number;
62
62
  host?: string;
63
63
  }): Promise<void>;
64
+ /**
65
+ * Attach SIGTERM/SIGINT shutdown handlers idempotently to the standalone
66
+ * Stripe webhook server. Returns a `detach()` function that removes both
67
+ * handlers, intended for the listener-count audit test.
68
+ *
69
+ * SMI-4694: mirrors `webhook-endpoint.ts#attachShutdownHandlers`. Same
70
+ * risk profile (standalone daemon, supervisor re-entry possible).
71
+ *
72
+ * @internal Exported for the SMI-4694 listener-count audit test only; not
73
+ * part of the public webhook surface.
74
+ */
75
+ export declare function attachShutdownHandlers(webhookServer: StripeWebhookServer): () => void;
64
76
  /**
65
77
  * Standalone entry point for Stripe webhook server
66
78
  */
@@ -1 +1 @@
1
- {"version":3,"file":"stripe-webhook-endpoint.d.ts","sourceRoot":"","sources":["../../../src/webhooks/stripe-webhook-endpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAiD,MAAM,EAAE,MAAM,MAAM,CAAA;AAO5E,OAAO,KAAK,EAAE,gBAAgB,EAAuB,MAAM,uBAAuB,CAAA;AAClF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AAMpE,MAAM,WAAW,yBAAyB;IACxC;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;IAErB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IAEpB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IAEzB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,0BAA2B,SAAQ,yBAAyB;IAC3E;;OAEG;IACH,cAAc,EAAE,oBAAoB,CAAA;IAEpC;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CACpF;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,gBAAgB,CAAA;IAC7B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1B;AAMD;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,0BAA0B,GAClC,mBAAmB,CAiJrB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,mBAAmB,EAClC,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7C,OAAO,CAAC,IAAI,CAAC,CAUf;AAED;;GAEG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAqD1C"}
1
+ {"version":3,"file":"stripe-webhook-endpoint.d.ts","sourceRoot":"","sources":["../../../src/webhooks/stripe-webhook-endpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAiD,MAAM,EAAE,MAAM,MAAM,CAAA;AAO5E,OAAO,KAAK,EAAE,gBAAgB,EAAuB,MAAM,uBAAuB,CAAA;AAClF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AAMpE,MAAM,WAAW,yBAAyB;IACxC;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;IAErB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IAEpB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IAEzB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,0BAA2B,SAAQ,yBAAyB;IAC3E;;OAEG;IACH,cAAc,EAAE,oBAAoB,CAAA;IAEpC;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CACpF;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,gBAAgB,CAAA;IAC7B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1B;AAMD;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,0BAA0B,GAClC,mBAAmB,CAiJrB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,mBAAmB,EAClC,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7C,OAAO,CAAC,IAAI,CAAC,CAUf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,mBAAmB,GAAG,MAAM,IAAI,CAkBrF;AAED;;GAEG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CA6C1C"}