@opensip-cli/core 0.1.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 (604) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +8 -0
  3. package/README.md +31 -0
  4. package/dist/__tests__/config-resolution.test.d.ts +2 -0
  5. package/dist/__tests__/config-resolution.test.d.ts.map +1 -0
  6. package/dist/__tests__/config-resolution.test.js +94 -0
  7. package/dist/__tests__/config-resolution.test.js.map +1 -0
  8. package/dist/__tests__/public-api.test.d.ts +16 -0
  9. package/dist/__tests__/public-api.test.d.ts.map +1 -0
  10. package/dist/__tests__/public-api.test.js +209 -0
  11. package/dist/__tests__/public-api.test.js.map +1 -0
  12. package/dist/__tests__/signal-batch.test.d.ts +2 -0
  13. package/dist/__tests__/signal-batch.test.d.ts.map +1 -0
  14. package/dist/__tests__/signal-batch.test.js +39 -0
  15. package/dist/__tests__/signal-batch.test.js.map +1 -0
  16. package/dist/__tests__/signal-sink.test.d.ts +2 -0
  17. package/dist/__tests__/signal-sink.test.d.ts.map +1 -0
  18. package/dist/__tests__/signal-sink.test.js +25 -0
  19. package/dist/__tests__/signal-sink.test.js.map +1 -0
  20. package/dist/__tests__/strip-utils.test.d.ts +2 -0
  21. package/dist/__tests__/strip-utils.test.d.ts.map +1 -0
  22. package/dist/__tests__/strip-utils.test.js +397 -0
  23. package/dist/__tests__/strip-utils.test.js.map +1 -0
  24. package/dist/__tests__/text-tree.test.d.ts +2 -0
  25. package/dist/__tests__/text-tree.test.d.ts.map +1 -0
  26. package/dist/__tests__/text-tree.test.js +31 -0
  27. package/dist/__tests__/text-tree.test.js.map +1 -0
  28. package/dist/baseline/__tests__/fingerprint-strategy.test.d.ts +2 -0
  29. package/dist/baseline/__tests__/fingerprint-strategy.test.d.ts.map +1 -0
  30. package/dist/baseline/__tests__/fingerprint-strategy.test.js +69 -0
  31. package/dist/baseline/__tests__/fingerprint-strategy.test.js.map +1 -0
  32. package/dist/baseline/fingerprint-strategy.d.ts +70 -0
  33. package/dist/baseline/fingerprint-strategy.d.ts.map +1 -0
  34. package/dist/baseline/fingerprint-strategy.js +90 -0
  35. package/dist/baseline/fingerprint-strategy.js.map +1 -0
  36. package/dist/config-resolution.d.ts +27 -0
  37. package/dist/config-resolution.d.ts.map +1 -0
  38. package/dist/config-resolution.js +92 -0
  39. package/dist/config-resolution.js.map +1 -0
  40. package/dist/index.d.ts +81 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +165 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/languages/__tests__/content-filter-dispatch.test.d.ts +2 -0
  45. package/dist/languages/__tests__/content-filter-dispatch.test.d.ts.map +1 -0
  46. package/dist/languages/__tests__/content-filter-dispatch.test.js +87 -0
  47. package/dist/languages/__tests__/content-filter-dispatch.test.js.map +1 -0
  48. package/dist/languages/__tests__/non-code-formats.test.d.ts +2 -0
  49. package/dist/languages/__tests__/non-code-formats.test.d.ts.map +1 -0
  50. package/dist/languages/__tests__/non-code-formats.test.js +31 -0
  51. package/dist/languages/__tests__/non-code-formats.test.js.map +1 -0
  52. package/dist/languages/__tests__/parse-cache.test.d.ts +2 -0
  53. package/dist/languages/__tests__/parse-cache.test.d.ts.map +1 -0
  54. package/dist/languages/__tests__/parse-cache.test.js +228 -0
  55. package/dist/languages/__tests__/parse-cache.test.js.map +1 -0
  56. package/dist/languages/__tests__/registry.test.d.ts +2 -0
  57. package/dist/languages/__tests__/registry.test.d.ts.map +1 -0
  58. package/dist/languages/__tests__/registry.test.js +193 -0
  59. package/dist/languages/__tests__/registry.test.js.map +1 -0
  60. package/dist/languages/__tests__/workspace-unit-contract.test.d.ts +2 -0
  61. package/dist/languages/__tests__/workspace-unit-contract.test.d.ts.map +1 -0
  62. package/dist/languages/__tests__/workspace-unit-contract.test.js +66 -0
  63. package/dist/languages/__tests__/workspace-unit-contract.test.js.map +1 -0
  64. package/dist/languages/adapter.d.ts +66 -0
  65. package/dist/languages/adapter.d.ts.map +1 -0
  66. package/dist/languages/adapter.js +2 -0
  67. package/dist/languages/adapter.js.map +1 -0
  68. package/dist/languages/content-filter-dispatch.d.ts +36 -0
  69. package/dist/languages/content-filter-dispatch.d.ts.map +1 -0
  70. package/dist/languages/content-filter-dispatch.js +75 -0
  71. package/dist/languages/content-filter-dispatch.js.map +1 -0
  72. package/dist/languages/generic-types.d.ts +22 -0
  73. package/dist/languages/generic-types.d.ts.map +1 -0
  74. package/dist/languages/generic-types.js +3 -0
  75. package/dist/languages/generic-types.js.map +1 -0
  76. package/dist/languages/index.d.ts +12 -0
  77. package/dist/languages/index.d.ts.map +1 -0
  78. package/dist/languages/index.js +7 -0
  79. package/dist/languages/index.js.map +1 -0
  80. package/dist/languages/non-code-formats.d.ts +37 -0
  81. package/dist/languages/non-code-formats.d.ts.map +1 -0
  82. package/dist/languages/non-code-formats.js +45 -0
  83. package/dist/languages/non-code-formats.js.map +1 -0
  84. package/dist/languages/parse-cache-class.d.ts +69 -0
  85. package/dist/languages/parse-cache-class.d.ts.map +1 -0
  86. package/dist/languages/parse-cache-class.js +135 -0
  87. package/dist/languages/parse-cache-class.js.map +1 -0
  88. package/dist/languages/parse-cache.d.ts +54 -0
  89. package/dist/languages/parse-cache.d.ts.map +1 -0
  90. package/dist/languages/parse-cache.js +88 -0
  91. package/dist/languages/parse-cache.js.map +1 -0
  92. package/dist/languages/registry.d.ts +35 -0
  93. package/dist/languages/registry.d.ts.map +1 -0
  94. package/dist/languages/registry.js +123 -0
  95. package/dist/languages/registry.js.map +1 -0
  96. package/dist/languages/strip-scanners.d.ts +170 -0
  97. package/dist/languages/strip-scanners.d.ts.map +1 -0
  98. package/dist/languages/strip-scanners.js +233 -0
  99. package/dist/languages/strip-scanners.js.map +1 -0
  100. package/dist/languages/strip-utils.d.ts +66 -0
  101. package/dist/languages/strip-utils.d.ts.map +1 -0
  102. package/dist/languages/strip-utils.js +88 -0
  103. package/dist/languages/strip-utils.js.map +1 -0
  104. package/dist/languages/text-tree.d.ts +44 -0
  105. package/dist/languages/text-tree.d.ts.map +1 -0
  106. package/dist/languages/text-tree.js +34 -0
  107. package/dist/languages/text-tree.js.map +1 -0
  108. package/dist/languages/workspace-unit.d.ts +18 -0
  109. package/dist/languages/workspace-unit.d.ts.map +1 -0
  110. package/dist/languages/workspace-unit.js +2 -0
  111. package/dist/languages/workspace-unit.js.map +1 -0
  112. package/dist/lib/__tests__/config-version.test.d.ts +12 -0
  113. package/dist/lib/__tests__/config-version.test.d.ts.map +1 -0
  114. package/dist/lib/__tests__/config-version.test.js +92 -0
  115. package/dist/lib/__tests__/config-version.test.js.map +1 -0
  116. package/dist/lib/__tests__/diagnostics-bus.test.d.ts +7 -0
  117. package/dist/lib/__tests__/diagnostics-bus.test.d.ts.map +1 -0
  118. package/dist/lib/__tests__/diagnostics-bus.test.js +44 -0
  119. package/dist/lib/__tests__/diagnostics-bus.test.js.map +1 -0
  120. package/dist/lib/__tests__/env-registry.test.d.ts +7 -0
  121. package/dist/lib/__tests__/env-registry.test.d.ts.map +1 -0
  122. package/dist/lib/__tests__/env-registry.test.js +82 -0
  123. package/dist/lib/__tests__/env-registry.test.js.map +1 -0
  124. package/dist/lib/__tests__/errors.test.d.ts +2 -0
  125. package/dist/lib/__tests__/errors.test.d.ts.map +1 -0
  126. package/dist/lib/__tests__/errors.test.js +218 -0
  127. package/dist/lib/__tests__/errors.test.js.map +1 -0
  128. package/dist/lib/__tests__/format.test.d.ts +2 -0
  129. package/dist/lib/__tests__/format.test.d.ts.map +1 -0
  130. package/dist/lib/__tests__/format.test.js +23 -0
  131. package/dist/lib/__tests__/format.test.js.map +1 -0
  132. package/dist/lib/__tests__/ids.test.d.ts +2 -0
  133. package/dist/lib/__tests__/ids.test.d.ts.map +1 -0
  134. package/dist/lib/__tests__/ids.test.js +80 -0
  135. package/dist/lib/__tests__/ids.test.js.map +1 -0
  136. package/dist/lib/__tests__/logger.test.d.ts +2 -0
  137. package/dist/lib/__tests__/logger.test.d.ts.map +1 -0
  138. package/dist/lib/__tests__/logger.test.js +284 -0
  139. package/dist/lib/__tests__/logger.test.js.map +1 -0
  140. package/dist/lib/__tests__/package-version.test.d.ts +2 -0
  141. package/dist/lib/__tests__/package-version.test.d.ts.map +1 -0
  142. package/dist/lib/__tests__/package-version.test.js +47 -0
  143. package/dist/lib/__tests__/package-version.test.js.map +1 -0
  144. package/dist/lib/__tests__/paths.test.d.ts +5 -0
  145. package/dist/lib/__tests__/paths.test.d.ts.map +1 -0
  146. package/dist/lib/__tests__/paths.test.js +59 -0
  147. package/dist/lib/__tests__/paths.test.js.map +1 -0
  148. package/dist/lib/__tests__/payload-version.test.d.ts +2 -0
  149. package/dist/lib/__tests__/payload-version.test.d.ts.map +1 -0
  150. package/dist/lib/__tests__/payload-version.test.js +35 -0
  151. package/dist/lib/__tests__/payload-version.test.js.map +1 -0
  152. package/dist/lib/__tests__/phantom-detect.test.d.ts +10 -0
  153. package/dist/lib/__tests__/phantom-detect.test.d.ts.map +1 -0
  154. package/dist/lib/__tests__/phantom-detect.test.js +84 -0
  155. package/dist/lib/__tests__/phantom-detect.test.js.map +1 -0
  156. package/dist/lib/__tests__/project-context.test.d.ts +10 -0
  157. package/dist/lib/__tests__/project-context.test.d.ts.map +1 -0
  158. package/dist/lib/__tests__/project-context.test.js +240 -0
  159. package/dist/lib/__tests__/project-context.test.js.map +1 -0
  160. package/dist/lib/__tests__/registry.test.d.ts +2 -0
  161. package/dist/lib/__tests__/registry.test.d.ts.map +1 -0
  162. package/dist/lib/__tests__/registry.test.js +333 -0
  163. package/dist/lib/__tests__/registry.test.js.map +1 -0
  164. package/dist/lib/__tests__/retry.test.d.ts +2 -0
  165. package/dist/lib/__tests__/retry.test.d.ts.map +1 -0
  166. package/dist/lib/__tests__/retry.test.js +71 -0
  167. package/dist/lib/__tests__/retry.test.js.map +1 -0
  168. package/dist/lib/__tests__/run-diagnostics.test.d.ts +9 -0
  169. package/dist/lib/__tests__/run-diagnostics.test.d.ts.map +1 -0
  170. package/dist/lib/__tests__/run-diagnostics.test.js +61 -0
  171. package/dist/lib/__tests__/run-diagnostics.test.js.map +1 -0
  172. package/dist/lib/__tests__/run-scope.test.d.ts +2 -0
  173. package/dist/lib/__tests__/run-scope.test.d.ts.map +1 -0
  174. package/dist/lib/__tests__/run-scope.test.js +202 -0
  175. package/dist/lib/__tests__/run-scope.test.js.map +1 -0
  176. package/dist/lib/__tests__/run-timer.test.d.ts +2 -0
  177. package/dist/lib/__tests__/run-timer.test.d.ts.map +1 -0
  178. package/dist/lib/__tests__/run-timer.test.js +152 -0
  179. package/dist/lib/__tests__/run-timer.test.js.map +1 -0
  180. package/dist/lib/__tests__/severity-policy.test.d.ts +6 -0
  181. package/dist/lib/__tests__/severity-policy.test.d.ts.map +1 -0
  182. package/dist/lib/__tests__/severity-policy.test.js +47 -0
  183. package/dist/lib/__tests__/severity-policy.test.js.map +1 -0
  184. package/dist/lib/__tests__/telemetry.test.d.ts +2 -0
  185. package/dist/lib/__tests__/telemetry.test.d.ts.map +1 -0
  186. package/dist/lib/__tests__/telemetry.test.js +212 -0
  187. package/dist/lib/__tests__/telemetry.test.js.map +1 -0
  188. package/dist/lib/__tests__/verdict-policy.test.d.ts +7 -0
  189. package/dist/lib/__tests__/verdict-policy.test.d.ts.map +1 -0
  190. package/dist/lib/__tests__/verdict-policy.test.js +91 -0
  191. package/dist/lib/__tests__/verdict-policy.test.js.map +1 -0
  192. package/dist/lib/__tests__/yaml.test.d.ts +6 -0
  193. package/dist/lib/__tests__/yaml.test.d.ts.map +1 -0
  194. package/dist/lib/__tests__/yaml.test.js +79 -0
  195. package/dist/lib/__tests__/yaml.test.js.map +1 -0
  196. package/dist/lib/config-version.d.ts +49 -0
  197. package/dist/lib/config-version.d.ts.map +1 -0
  198. package/dist/lib/config-version.js +56 -0
  199. package/dist/lib/config-version.js.map +1 -0
  200. package/dist/lib/diagnostics-bus.d.ts +48 -0
  201. package/dist/lib/diagnostics-bus.d.ts.map +1 -0
  202. package/dist/lib/diagnostics-bus.js +74 -0
  203. package/dist/lib/diagnostics-bus.js.map +1 -0
  204. package/dist/lib/env-registry.d.ts +108 -0
  205. package/dist/lib/env-registry.d.ts.map +1 -0
  206. package/dist/lib/env-registry.js +92 -0
  207. package/dist/lib/env-registry.js.map +1 -0
  208. package/dist/lib/errors.d.ts +132 -0
  209. package/dist/lib/errors.d.ts.map +1 -0
  210. package/dist/lib/errors.js +160 -0
  211. package/dist/lib/errors.js.map +1 -0
  212. package/dist/lib/execution/__tests__/execution.test.d.ts +7 -0
  213. package/dist/lib/execution/__tests__/execution.test.d.ts.map +1 -0
  214. package/dist/lib/execution/__tests__/execution.test.js +254 -0
  215. package/dist/lib/execution/__tests__/execution.test.js.map +1 -0
  216. package/dist/lib/execution/index.d.ts +15 -0
  217. package/dist/lib/execution/index.d.ts.map +1 -0
  218. package/dist/lib/execution/index.js +10 -0
  219. package/dist/lib/execution/index.js.map +1 -0
  220. package/dist/lib/execution/options.d.ts +32 -0
  221. package/dist/lib/execution/options.d.ts.map +1 -0
  222. package/dist/lib/execution/options.js +15 -0
  223. package/dist/lib/execution/options.js.map +1 -0
  224. package/dist/lib/execution/pipeline.d.ts +36 -0
  225. package/dist/lib/execution/pipeline.d.ts.map +1 -0
  226. package/dist/lib/execution/pipeline.js +38 -0
  227. package/dist/lib/execution/pipeline.js.map +1 -0
  228. package/dist/lib/execution/retry.d.ts +38 -0
  229. package/dist/lib/execution/retry.d.ts.map +1 -0
  230. package/dist/lib/execution/retry.js +56 -0
  231. package/dist/lib/execution/retry.js.map +1 -0
  232. package/dist/lib/execution/run-with-timeout.d.ts +46 -0
  233. package/dist/lib/execution/run-with-timeout.d.ts.map +1 -0
  234. package/dist/lib/execution/run-with-timeout.js +86 -0
  235. package/dist/lib/execution/run-with-timeout.js.map +1 -0
  236. package/dist/lib/execution/schedule.d.ts +62 -0
  237. package/dist/lib/execution/schedule.d.ts.map +1 -0
  238. package/dist/lib/execution/schedule.js +130 -0
  239. package/dist/lib/execution/schedule.js.map +1 -0
  240. package/dist/lib/format.d.ts +17 -0
  241. package/dist/lib/format.d.ts.map +1 -0
  242. package/dist/lib/format.js +26 -0
  243. package/dist/lib/format.js.map +1 -0
  244. package/dist/lib/ids.d.ts +13 -0
  245. package/dist/lib/ids.d.ts.map +1 -0
  246. package/dist/lib/ids.js +48 -0
  247. package/dist/lib/ids.js.map +1 -0
  248. package/dist/lib/logger.d.ts +166 -0
  249. package/dist/lib/logger.d.ts.map +1 -0
  250. package/dist/lib/logger.js +283 -0
  251. package/dist/lib/logger.js.map +1 -0
  252. package/dist/lib/package-version.d.ts +17 -0
  253. package/dist/lib/package-version.d.ts.map +1 -0
  254. package/dist/lib/package-version.js +52 -0
  255. package/dist/lib/package-version.js.map +1 -0
  256. package/dist/lib/paths.d.ts +139 -0
  257. package/dist/lib/paths.d.ts.map +1 -0
  258. package/dist/lib/paths.js +105 -0
  259. package/dist/lib/paths.js.map +1 -0
  260. package/dist/lib/payload-version.d.ts +15 -0
  261. package/dist/lib/payload-version.d.ts.map +1 -0
  262. package/dist/lib/payload-version.js +24 -0
  263. package/dist/lib/payload-version.js.map +1 -0
  264. package/dist/lib/phantom-detect.d.ts +21 -0
  265. package/dist/lib/phantom-detect.d.ts.map +1 -0
  266. package/dist/lib/phantom-detect.js +76 -0
  267. package/dist/lib/phantom-detect.js.map +1 -0
  268. package/dist/lib/project-context.d.ts +66 -0
  269. package/dist/lib/project-context.d.ts.map +1 -0
  270. package/dist/lib/project-context.js +112 -0
  271. package/dist/lib/project-context.js.map +1 -0
  272. package/dist/lib/recipe-id.d.ts +13 -0
  273. package/dist/lib/recipe-id.d.ts.map +1 -0
  274. package/dist/lib/recipe-id.js +15 -0
  275. package/dist/lib/recipe-id.js.map +1 -0
  276. package/dist/lib/registry.d.ts +98 -0
  277. package/dist/lib/registry.d.ts.map +1 -0
  278. package/dist/lib/registry.js +152 -0
  279. package/dist/lib/registry.js.map +1 -0
  280. package/dist/lib/retry.d.ts +26 -0
  281. package/dist/lib/retry.d.ts.map +1 -0
  282. package/dist/lib/retry.js +48 -0
  283. package/dist/lib/retry.js.map +1 -0
  284. package/dist/lib/run-diagnostics.d.ts +64 -0
  285. package/dist/lib/run-diagnostics.d.ts.map +1 -0
  286. package/dist/lib/run-diagnostics.js +25 -0
  287. package/dist/lib/run-diagnostics.js.map +1 -0
  288. package/dist/lib/run-scope.d.ts +167 -0
  289. package/dist/lib/run-scope.d.ts.map +1 -0
  290. package/dist/lib/run-scope.js +176 -0
  291. package/dist/lib/run-scope.js.map +1 -0
  292. package/dist/lib/run-timer.d.ts +82 -0
  293. package/dist/lib/run-timer.d.ts.map +1 -0
  294. package/dist/lib/run-timer.js +79 -0
  295. package/dist/lib/run-timer.js.map +1 -0
  296. package/dist/lib/scope-types.d.ts +172 -0
  297. package/dist/lib/scope-types.d.ts.map +1 -0
  298. package/dist/lib/scope-types.js +27 -0
  299. package/dist/lib/scope-types.js.map +1 -0
  300. package/dist/lib/severity-policy.d.ts +38 -0
  301. package/dist/lib/severity-policy.d.ts.map +1 -0
  302. package/dist/lib/severity-policy.js +44 -0
  303. package/dist/lib/severity-policy.js.map +1 -0
  304. package/dist/lib/telemetry.d.ts +93 -0
  305. package/dist/lib/telemetry.d.ts.map +1 -0
  306. package/dist/lib/telemetry.js +144 -0
  307. package/dist/lib/telemetry.js.map +1 -0
  308. package/dist/lib/ui-context.d.ts +34 -0
  309. package/dist/lib/ui-context.d.ts.map +1 -0
  310. package/dist/lib/ui-context.js +16 -0
  311. package/dist/lib/ui-context.js.map +1 -0
  312. package/dist/lib/verdict-policy.d.ts +71 -0
  313. package/dist/lib/verdict-policy.d.ts.map +1 -0
  314. package/dist/lib/verdict-policy.js +82 -0
  315. package/dist/lib/verdict-policy.js.map +1 -0
  316. package/dist/lib/yaml.d.ts +74 -0
  317. package/dist/lib/yaml.d.ts.map +1 -0
  318. package/dist/lib/yaml.js +118 -0
  319. package/dist/lib/yaml.js.map +1 -0
  320. package/dist/plugins/__tests__/as-if-external.test.d.ts +18 -0
  321. package/dist/plugins/__tests__/as-if-external.test.d.ts.map +1 -0
  322. package/dist/plugins/__tests__/as-if-external.test.js +159 -0
  323. package/dist/plugins/__tests__/as-if-external.test.js.map +1 -0
  324. package/dist/plugins/__tests__/authored-tool-discovery.test.d.ts +8 -0
  325. package/dist/plugins/__tests__/authored-tool-discovery.test.d.ts.map +1 -0
  326. package/dist/plugins/__tests__/authored-tool-discovery.test.js +97 -0
  327. package/dist/plugins/__tests__/authored-tool-discovery.test.js.map +1 -0
  328. package/dist/plugins/__tests__/capability-discovery.test.d.ts +2 -0
  329. package/dist/plugins/__tests__/capability-discovery.test.d.ts.map +1 -0
  330. package/dist/plugins/__tests__/capability-discovery.test.js +349 -0
  331. package/dist/plugins/__tests__/capability-discovery.test.js.map +1 -0
  332. package/dist/plugins/__tests__/capability-from-manifest.test.d.ts +2 -0
  333. package/dist/plugins/__tests__/capability-from-manifest.test.d.ts.map +1 -0
  334. package/dist/plugins/__tests__/capability-from-manifest.test.js +172 -0
  335. package/dist/plugins/__tests__/capability-from-manifest.test.js.map +1 -0
  336. package/dist/plugins/__tests__/capability-loader.test.d.ts +2 -0
  337. package/dist/plugins/__tests__/capability-loader.test.d.ts.map +1 -0
  338. package/dist/plugins/__tests__/capability-loader.test.js +122 -0
  339. package/dist/plugins/__tests__/capability-loader.test.js.map +1 -0
  340. package/dist/plugins/__tests__/capability-registry.test.d.ts +2 -0
  341. package/dist/plugins/__tests__/capability-registry.test.d.ts.map +1 -0
  342. package/dist/plugins/__tests__/capability-registry.test.js +185 -0
  343. package/dist/plugins/__tests__/capability-registry.test.js.map +1 -0
  344. package/dist/plugins/__tests__/discover.test.d.ts +2 -0
  345. package/dist/plugins/__tests__/discover.test.d.ts.map +1 -0
  346. package/dist/plugins/__tests__/discover.test.js +311 -0
  347. package/dist/plugins/__tests__/discover.test.js.map +1 -0
  348. package/dist/plugins/__tests__/loader.test.d.ts +2 -0
  349. package/dist/plugins/__tests__/loader.test.d.ts.map +1 -0
  350. package/dist/plugins/__tests__/loader.test.js +191 -0
  351. package/dist/plugins/__tests__/loader.test.js.map +1 -0
  352. package/dist/plugins/__tests__/manifest-discovery.test.d.ts +2 -0
  353. package/dist/plugins/__tests__/manifest-discovery.test.d.ts.map +1 -0
  354. package/dist/plugins/__tests__/manifest-discovery.test.js +132 -0
  355. package/dist/plugins/__tests__/manifest-discovery.test.js.map +1 -0
  356. package/dist/plugins/__tests__/manifest-loader.test.d.ts +2 -0
  357. package/dist/plugins/__tests__/manifest-loader.test.d.ts.map +1 -0
  358. package/dist/plugins/__tests__/manifest-loader.test.js +434 -0
  359. package/dist/plugins/__tests__/manifest-loader.test.js.map +1 -0
  360. package/dist/plugins/__tests__/marker-discovery.test.d.ts +2 -0
  361. package/dist/plugins/__tests__/marker-discovery.test.d.ts.map +1 -0
  362. package/dist/plugins/__tests__/marker-discovery.test.js +164 -0
  363. package/dist/plugins/__tests__/marker-discovery.test.js.map +1 -0
  364. package/dist/plugins/__tests__/node-modules-walk.test.d.ts +2 -0
  365. package/dist/plugins/__tests__/node-modules-walk.test.d.ts.map +1 -0
  366. package/dist/plugins/__tests__/node-modules-walk.test.js +76 -0
  367. package/dist/plugins/__tests__/node-modules-walk.test.js.map +1 -0
  368. package/dist/plugins/__tests__/package-entry.test.d.ts +9 -0
  369. package/dist/plugins/__tests__/package-entry.test.d.ts.map +1 -0
  370. package/dist/plugins/__tests__/package-entry.test.js +117 -0
  371. package/dist/plugins/__tests__/package-entry.test.js.map +1 -0
  372. package/dist/plugins/__tests__/recipe-loader.test.d.ts +2 -0
  373. package/dist/plugins/__tests__/recipe-loader.test.d.ts.map +1 -0
  374. package/dist/plugins/__tests__/recipe-loader.test.js +130 -0
  375. package/dist/plugins/__tests__/recipe-loader.test.js.map +1 -0
  376. package/dist/plugins/__tests__/scope-validation.test.d.ts +2 -0
  377. package/dist/plugins/__tests__/scope-validation.test.d.ts.map +1 -0
  378. package/dist/plugins/__tests__/scope-validation.test.js +68 -0
  379. package/dist/plugins/__tests__/scope-validation.test.js.map +1 -0
  380. package/dist/plugins/__tests__/single-core-guard.test.d.ts +10 -0
  381. package/dist/plugins/__tests__/single-core-guard.test.d.ts.map +1 -0
  382. package/dist/plugins/__tests__/single-core-guard.test.js +89 -0
  383. package/dist/plugins/__tests__/single-core-guard.test.js.map +1 -0
  384. package/dist/plugins/__tests__/tool-package-discovery.test.d.ts +2 -0
  385. package/dist/plugins/__tests__/tool-package-discovery.test.d.ts.map +1 -0
  386. package/dist/plugins/__tests__/tool-package-discovery.test.js +215 -0
  387. package/dist/plugins/__tests__/tool-package-discovery.test.js.map +1 -0
  388. package/dist/plugins/authored-tool-discovery.d.ts +45 -0
  389. package/dist/plugins/authored-tool-discovery.d.ts.map +1 -0
  390. package/dist/plugins/authored-tool-discovery.js +61 -0
  391. package/dist/plugins/authored-tool-discovery.js.map +1 -0
  392. package/dist/plugins/capability-discovery.d.ts +80 -0
  393. package/dist/plugins/capability-discovery.d.ts.map +1 -0
  394. package/dist/plugins/capability-discovery.js +278 -0
  395. package/dist/plugins/capability-discovery.js.map +1 -0
  396. package/dist/plugins/capability-loader.d.ts +50 -0
  397. package/dist/plugins/capability-loader.d.ts.map +1 -0
  398. package/dist/plugins/capability-loader.js +85 -0
  399. package/dist/plugins/capability-loader.js.map +1 -0
  400. package/dist/plugins/capability-registry.d.ts +169 -0
  401. package/dist/plugins/capability-registry.d.ts.map +1 -0
  402. package/dist/plugins/capability-registry.js +319 -0
  403. package/dist/plugins/capability-registry.js.map +1 -0
  404. package/dist/plugins/discover.d.ts +64 -0
  405. package/dist/plugins/discover.d.ts.map +1 -0
  406. package/dist/plugins/discover.js +303 -0
  407. package/dist/plugins/discover.js.map +1 -0
  408. package/dist/plugins/index.d.ts +37 -0
  409. package/dist/plugins/index.d.ts.map +1 -0
  410. package/dist/plugins/index.js +40 -0
  411. package/dist/plugins/index.js.map +1 -0
  412. package/dist/plugins/json-guards.d.ts +11 -0
  413. package/dist/plugins/json-guards.d.ts.map +1 -0
  414. package/dist/plugins/json-guards.js +15 -0
  415. package/dist/plugins/json-guards.js.map +1 -0
  416. package/dist/plugins/loader.d.ts +67 -0
  417. package/dist/plugins/loader.d.ts.map +1 -0
  418. package/dist/plugins/loader.js +137 -0
  419. package/dist/plugins/loader.js.map +1 -0
  420. package/dist/plugins/manifest-discovery.d.ts +28 -0
  421. package/dist/plugins/manifest-discovery.d.ts.map +1 -0
  422. package/dist/plugins/manifest-discovery.js +103 -0
  423. package/dist/plugins/manifest-discovery.js.map +1 -0
  424. package/dist/plugins/manifest-loader.d.ts +120 -0
  425. package/dist/plugins/manifest-loader.d.ts.map +1 -0
  426. package/dist/plugins/manifest-loader.js +410 -0
  427. package/dist/plugins/manifest-loader.js.map +1 -0
  428. package/dist/plugins/marker-discovery.d.ts +115 -0
  429. package/dist/plugins/marker-discovery.d.ts.map +1 -0
  430. package/dist/plugins/marker-discovery.js +172 -0
  431. package/dist/plugins/marker-discovery.js.map +1 -0
  432. package/dist/plugins/node-modules-walk.d.ts +61 -0
  433. package/dist/plugins/node-modules-walk.d.ts.map +1 -0
  434. package/dist/plugins/node-modules-walk.js +99 -0
  435. package/dist/plugins/node-modules-walk.js.map +1 -0
  436. package/dist/plugins/package-entry.d.ts +38 -0
  437. package/dist/plugins/package-entry.d.ts.map +1 -0
  438. package/dist/plugins/package-entry.js +86 -0
  439. package/dist/plugins/package-entry.js.map +1 -0
  440. package/dist/plugins/recipe-loader.d.ts +63 -0
  441. package/dist/plugins/recipe-loader.d.ts.map +1 -0
  442. package/dist/plugins/recipe-loader.js +67 -0
  443. package/dist/plugins/recipe-loader.js.map +1 -0
  444. package/dist/plugins/scope-validation.d.ts +35 -0
  445. package/dist/plugins/scope-validation.d.ts.map +1 -0
  446. package/dist/plugins/scope-validation.js +55 -0
  447. package/dist/plugins/scope-validation.js.map +1 -0
  448. package/dist/plugins/single-core-guard.d.ts +28 -0
  449. package/dist/plugins/single-core-guard.d.ts.map +1 -0
  450. package/dist/plugins/single-core-guard.js +69 -0
  451. package/dist/plugins/single-core-guard.js.map +1 -0
  452. package/dist/plugins/tool-package-discovery.d.ts +93 -0
  453. package/dist/plugins/tool-package-discovery.d.ts.map +1 -0
  454. package/dist/plugins/tool-package-discovery.js +118 -0
  455. package/dist/plugins/tool-package-discovery.js.map +1 -0
  456. package/dist/plugins/types.d.ts +78 -0
  457. package/dist/plugins/types.d.ts.map +1 -0
  458. package/dist/plugins/types.js +15 -0
  459. package/dist/plugins/types.js.map +1 -0
  460. package/dist/recipes/__tests__/registry.test.d.ts +2 -0
  461. package/dist/recipes/__tests__/registry.test.d.ts.map +1 -0
  462. package/dist/recipes/__tests__/registry.test.js +170 -0
  463. package/dist/recipes/__tests__/registry.test.js.map +1 -0
  464. package/dist/recipes/__tests__/selector.test.d.ts +20 -0
  465. package/dist/recipes/__tests__/selector.test.d.ts.map +1 -0
  466. package/dist/recipes/__tests__/selector.test.js +173 -0
  467. package/dist/recipes/__tests__/selector.test.js.map +1 -0
  468. package/dist/recipes/__tests__/unit-config.test.d.ts +7 -0
  469. package/dist/recipes/__tests__/unit-config.test.d.ts.map +1 -0
  470. package/dist/recipes/__tests__/unit-config.test.js +52 -0
  471. package/dist/recipes/__tests__/unit-config.test.js.map +1 -0
  472. package/dist/recipes/registry.d.ts +105 -0
  473. package/dist/recipes/registry.d.ts.map +1 -0
  474. package/dist/recipes/registry.js +141 -0
  475. package/dist/recipes/registry.js.map +1 -0
  476. package/dist/recipes/selector.d.ts +112 -0
  477. package/dist/recipes/selector.d.ts.map +1 -0
  478. package/dist/recipes/selector.js +134 -0
  479. package/dist/recipes/selector.js.map +1 -0
  480. package/dist/recipes/unit-config.d.ts +63 -0
  481. package/dist/recipes/unit-config.d.ts.map +1 -0
  482. package/dist/recipes/unit-config.js +68 -0
  483. package/dist/recipes/unit-config.js.map +1 -0
  484. package/dist/runtime/__tests__/in-process-transport.test.d.ts +6 -0
  485. package/dist/runtime/__tests__/in-process-transport.test.d.ts.map +1 -0
  486. package/dist/runtime/__tests__/in-process-transport.test.js +73 -0
  487. package/dist/runtime/__tests__/in-process-transport.test.js.map +1 -0
  488. package/dist/runtime/__tests__/subprocess-transport.test.d.ts +11 -0
  489. package/dist/runtime/__tests__/subprocess-transport.test.d.ts.map +1 -0
  490. package/dist/runtime/__tests__/subprocess-transport.test.js +118 -0
  491. package/dist/runtime/__tests__/subprocess-transport.test.js.map +1 -0
  492. package/dist/runtime/in-process-transport.d.ts +20 -0
  493. package/dist/runtime/in-process-transport.d.ts.map +1 -0
  494. package/dist/runtime/in-process-transport.js +49 -0
  495. package/dist/runtime/in-process-transport.js.map +1 -0
  496. package/dist/runtime/progress-transport.d.ts +73 -0
  497. package/dist/runtime/progress-transport.d.ts.map +1 -0
  498. package/dist/runtime/progress-transport.js +17 -0
  499. package/dist/runtime/progress-transport.js.map +1 -0
  500. package/dist/runtime/subprocess-transport.d.ts +43 -0
  501. package/dist/runtime/subprocess-transport.d.ts.map +1 -0
  502. package/dist/runtime/subprocess-transport.js +134 -0
  503. package/dist/runtime/subprocess-transport.js.map +1 -0
  504. package/dist/signals/comment-openers.d.ts +29 -0
  505. package/dist/signals/comment-openers.d.ts.map +1 -0
  506. package/dist/signals/comment-openers.js +41 -0
  507. package/dist/signals/comment-openers.js.map +1 -0
  508. package/dist/signals/comment-openers.test.d.ts +7 -0
  509. package/dist/signals/comment-openers.test.d.ts.map +1 -0
  510. package/dist/signals/comment-openers.test.js +41 -0
  511. package/dist/signals/comment-openers.test.js.map +1 -0
  512. package/dist/signals/create-signal-from-violation.d.ts +29 -0
  513. package/dist/signals/create-signal-from-violation.d.ts.map +1 -0
  514. package/dist/signals/create-signal-from-violation.js +29 -0
  515. package/dist/signals/create-signal-from-violation.js.map +1 -0
  516. package/dist/signals/signal-sink.d.ts +49 -0
  517. package/dist/signals/signal-sink.d.ts.map +1 -0
  518. package/dist/signals/signal-sink.js +6 -0
  519. package/dist/signals/signal-sink.js.map +1 -0
  520. package/dist/signals/suppress.d.ts +102 -0
  521. package/dist/signals/suppress.d.ts.map +1 -0
  522. package/dist/signals/suppress.js +325 -0
  523. package/dist/signals/suppress.js.map +1 -0
  524. package/dist/signals/suppress.test.d.ts +2 -0
  525. package/dist/signals/suppress.test.d.ts.map +1 -0
  526. package/dist/signals/suppress.test.js +213 -0
  527. package/dist/signals/suppress.test.js.map +1 -0
  528. package/dist/tools/__tests__/command-spec.test.d.ts +2 -0
  529. package/dist/tools/__tests__/command-spec.test.d.ts.map +1 -0
  530. package/dist/tools/__tests__/command-spec.test.js +191 -0
  531. package/dist/tools/__tests__/command-spec.test.js.map +1 -0
  532. package/dist/tools/__tests__/compatibility.test.d.ts +5 -0
  533. package/dist/tools/__tests__/compatibility.test.d.ts.map +1 -0
  534. package/dist/tools/__tests__/compatibility.test.js +41 -0
  535. package/dist/tools/__tests__/compatibility.test.js.map +1 -0
  536. package/dist/tools/__tests__/ids.test.d.ts +5 -0
  537. package/dist/tools/__tests__/ids.test.d.ts.map +1 -0
  538. package/dist/tools/__tests__/ids.test.js +56 -0
  539. package/dist/tools/__tests__/ids.test.js.map +1 -0
  540. package/dist/tools/__tests__/manifest-assert.test.d.ts +5 -0
  541. package/dist/tools/__tests__/manifest-assert.test.d.ts.map +1 -0
  542. package/dist/tools/__tests__/manifest-assert.test.js +66 -0
  543. package/dist/tools/__tests__/manifest-assert.test.js.map +1 -0
  544. package/dist/tools/__tests__/registry.test.d.ts +2 -0
  545. package/dist/tools/__tests__/registry.test.d.ts.map +1 -0
  546. package/dist/tools/__tests__/registry.test.js +93 -0
  547. package/dist/tools/__tests__/registry.test.js.map +1 -0
  548. package/dist/tools/__tests__/types.test.d.ts +2 -0
  549. package/dist/tools/__tests__/types.test.d.ts.map +1 -0
  550. package/dist/tools/__tests__/types.test.js +51 -0
  551. package/dist/tools/__tests__/types.test.js.map +1 -0
  552. package/dist/tools/capability.d.ts +257 -0
  553. package/dist/tools/capability.d.ts.map +1 -0
  554. package/dist/tools/capability.js +46 -0
  555. package/dist/tools/capability.js.map +1 -0
  556. package/dist/tools/command-spec.d.ts +211 -0
  557. package/dist/tools/command-spec.d.ts.map +1 -0
  558. package/dist/tools/command-spec.js +110 -0
  559. package/dist/tools/command-spec.js.map +1 -0
  560. package/dist/tools/compatibility.d.ts +45 -0
  561. package/dist/tools/compatibility.d.ts.map +1 -0
  562. package/dist/tools/compatibility.js +49 -0
  563. package/dist/tools/compatibility.js.map +1 -0
  564. package/dist/tools/ids.d.ts +61 -0
  565. package/dist/tools/ids.d.ts.map +1 -0
  566. package/dist/tools/ids.js +61 -0
  567. package/dist/tools/ids.js.map +1 -0
  568. package/dist/tools/index.d.ts +22 -0
  569. package/dist/tools/index.d.ts.map +1 -0
  570. package/dist/tools/index.js +28 -0
  571. package/dist/tools/index.js.map +1 -0
  572. package/dist/tools/manifest-assert.d.ts +35 -0
  573. package/dist/tools/manifest-assert.d.ts.map +1 -0
  574. package/dist/tools/manifest-assert.js +67 -0
  575. package/dist/tools/manifest-assert.js.map +1 -0
  576. package/dist/tools/manifest.d.ts +178 -0
  577. package/dist/tools/manifest.d.ts.map +1 -0
  578. package/dist/tools/manifest.js +35 -0
  579. package/dist/tools/manifest.js.map +1 -0
  580. package/dist/tools/registry.d.ts +37 -0
  581. package/dist/tools/registry.d.ts.map +1 -0
  582. package/dist/tools/registry.js +49 -0
  583. package/dist/tools/registry.js.map +1 -0
  584. package/dist/tools/types.d.ts +1021 -0
  585. package/dist/tools/types.d.ts.map +1 -0
  586. package/dist/tools/types.js +77 -0
  587. package/dist/tools/types.js.map +1 -0
  588. package/dist/types/__tests__/signal.test.d.ts +2 -0
  589. package/dist/types/__tests__/signal.test.d.ts.map +1 -0
  590. package/dist/types/__tests__/signal.test.js +111 -0
  591. package/dist/types/__tests__/signal.test.js.map +1 -0
  592. package/dist/types/index.d.ts +5 -0
  593. package/dist/types/index.d.ts.map +1 -0
  594. package/dist/types/index.js +3 -0
  595. package/dist/types/index.js.map +1 -0
  596. package/dist/types/signal-batch.d.ts +56 -0
  597. package/dist/types/signal-batch.d.ts.map +1 -0
  598. package/dist/types/signal-batch.js +54 -0
  599. package/dist/types/signal-batch.js.map +1 -0
  600. package/dist/types/signal.d.ts +77 -0
  601. package/dist/types/signal.d.ts.map +1 -0
  602. package/dist/types/signal.js +42 -0
  603. package/dist/types/signal.js.map +1 -0
  604. package/package.json +57 -0
@@ -0,0 +1,170 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { ValidationError } from '../../lib/errors.js';
3
+ import { logger } from '../../lib/logger.js';
4
+ import { RecipeRegistry } from '../registry.js';
5
+ const stub = (id, name, opts = {}) => ({
6
+ id,
7
+ name,
8
+ displayName: opts.displayName ?? name,
9
+ description: opts.description ?? `${name} stub`,
10
+ tags: opts.tags,
11
+ extra: opts.extra,
12
+ });
13
+ describe('RecipeRegistry', () => {
14
+ let reg;
15
+ let warnSpy;
16
+ beforeEach(() => {
17
+ reg = new RecipeRegistry({ module: 'test:recipes' });
18
+ warnSpy = vi.spyOn(logger, 'warn').mockImplementation(() => undefined);
19
+ });
20
+ afterEach(() => {
21
+ vi.restoreAllMocks();
22
+ });
23
+ it('registers and looks up by id and name', () => {
24
+ const r = stub('A', 'alpha');
25
+ reg.register(r);
26
+ expect(reg.getById('A')).toBe(r);
27
+ expect(reg.getByName('alpha')).toBe(r);
28
+ expect(reg.has('A')).toBe(true);
29
+ expect(reg.has('alpha')).toBe(true);
30
+ });
31
+ it('loadRecipe falls back from name to id', () => {
32
+ const r = stub('A', 'alpha');
33
+ reg.register(r);
34
+ expect(reg.loadRecipe('alpha')).toBe(r);
35
+ expect(reg.loadRecipe('A')).toBe(r);
36
+ expect(reg.loadRecipe('nope')).toBeUndefined();
37
+ });
38
+ it('getAllRecipes returns the registered set in registration order', () => {
39
+ reg.register(stub('A', 'alpha'));
40
+ reg.register(stub('B', 'beta'));
41
+ expect(reg.getAllRecipes().map((r) => r.id)).toEqual(['A', 'B']);
42
+ });
43
+ it('getNames returns all registered names', () => {
44
+ reg.register(stub('A', 'alpha'));
45
+ reg.register(stub('B', 'beta'));
46
+ expect(reg.getNames()).toEqual(['alpha', 'beta']);
47
+ });
48
+ it('getByTag filters by recipe tags', () => {
49
+ reg.register(stub('A', 'alpha', { tags: ['fast'] }));
50
+ reg.register(stub('B', 'beta', { tags: ['slow'] }));
51
+ reg.register(stub('C', 'gamma'));
52
+ expect(reg.getByTag('fast').map((r) => r.id)).toEqual(['A']);
53
+ });
54
+ it('size reflects the registered count', () => {
55
+ expect(reg.size).toBe(0);
56
+ reg.register(stub('A', 'alpha'));
57
+ expect(reg.size).toBe(1);
58
+ reg.register(stub('B', 'beta'));
59
+ expect(reg.size).toBe(2);
60
+ });
61
+ it('remove(id) drops both the byId and byName entries', () => {
62
+ reg.register(stub('A', 'alpha'));
63
+ expect(reg.remove('A')).toBe(true);
64
+ expect(reg.getById('A')).toBeUndefined();
65
+ expect(reg.getByName('alpha')).toBeUndefined();
66
+ expect(reg.remove('A')).toBe(false);
67
+ });
68
+ it('clear() drops every entry', () => {
69
+ reg.register(stub('A', 'alpha'));
70
+ reg.register(stub('B', 'beta'));
71
+ reg.clear();
72
+ expect(reg.size).toBe(0);
73
+ expect(reg.getAllRecipes()).toEqual([]);
74
+ });
75
+ it('registerAll registers a batch with shared options', () => {
76
+ reg.registerAll([stub('A', 'alpha'), stub('B', 'beta')]);
77
+ expect(reg.size).toBe(2);
78
+ });
79
+ describe('duplicate-id policy', () => {
80
+ it('default: keeps the first entry, emits a warning', () => {
81
+ const first = stub('A', 'alpha', { extra: 'first' });
82
+ const second = stub('A', 'alpha', { extra: 'second' });
83
+ reg.register(first);
84
+ reg.register(second);
85
+ expect(reg.getById('A')).toBe(first);
86
+ expect(warnSpy).toHaveBeenCalledWith(expect.objectContaining({
87
+ evt: 'recipe.registry.duplicate',
88
+ module: 'test:recipes',
89
+ id: 'A',
90
+ name: 'alpha',
91
+ }));
92
+ });
93
+ it('also rejects on duplicate name (different id)', () => {
94
+ reg.register(stub('A', 'alpha'));
95
+ reg.register(stub('B', 'alpha'));
96
+ expect(reg.size).toBe(1);
97
+ expect(reg.getById('B')).toBeUndefined();
98
+ });
99
+ it('{ allowOverwrite: true } replaces the entry and keeps mappings consistent', () => {
100
+ reg.register(stub('A', 'alpha', { extra: 'first' }));
101
+ const replacement = stub('A', 'alpha', { extra: 'second' });
102
+ reg.register(replacement, { allowOverwrite: true });
103
+ expect(reg.getById('A')).toBe(replacement);
104
+ expect(reg.getByName('alpha')).toBe(replacement);
105
+ expect(reg.size).toBe(1);
106
+ });
107
+ it('{ allowOverwrite: true } with a different id but same name cleans up the stale id', () => {
108
+ reg.register(stub('A', 'alpha'));
109
+ const replacement = stub('B', 'alpha');
110
+ reg.register(replacement, { allowOverwrite: true });
111
+ expect(reg.getById('A')).toBeUndefined();
112
+ expect(reg.getById('B')).toBe(replacement);
113
+ expect(reg.getByName('alpha')).toBe(replacement);
114
+ expect(reg.size).toBe(1);
115
+ });
116
+ it('{ throwOnDuplicate: true } throws ValidationError', () => {
117
+ reg.register(stub('A', 'alpha'));
118
+ expect(() => reg.register(stub('A', 'alpha'), { throwOnDuplicate: true })).toThrow(ValidationError);
119
+ });
120
+ it('{ throwOnDuplicate: true } honours the per-call validationCode override', () => {
121
+ reg.register(stub('A', 'alpha'));
122
+ try {
123
+ reg.register(stub('A', 'alpha'), {
124
+ throwOnDuplicate: true,
125
+ validationCode: 'VALIDATION.TEST.CUSTOM',
126
+ });
127
+ expect.fail('should have thrown');
128
+ }
129
+ catch (error) {
130
+ expect(error).toBeInstanceOf(ValidationError);
131
+ expect(error.code).toBe('VALIDATION.TEST.CUSTOM');
132
+ }
133
+ });
134
+ it('{ throwOnDuplicate: true } registers normally when there is no duplicate', () => {
135
+ reg.register(stub('A', 'alpha'));
136
+ const fresh = stub('B', 'beta');
137
+ reg.register(fresh, { throwOnDuplicate: true });
138
+ expect(reg.getById('B')).toBe(fresh);
139
+ expect(reg.size).toBe(2);
140
+ });
141
+ it('{ internal: true } bypasses the duplicate guard and overwrites silently', () => {
142
+ const first = stub('A', 'alpha', { extra: 'first' });
143
+ const second = stub('A', 'alpha', { extra: 'second' });
144
+ reg.register(first, { internal: true });
145
+ reg.register(second, { internal: true });
146
+ expect(reg.getById('A')).toBe(second);
147
+ expect(warnSpy).not.toHaveBeenCalled();
148
+ });
149
+ it('{ allowOverwrite: true } with a same id but different name removes the stale name mapping', () => {
150
+ reg.register(stub('A', 'alpha'));
151
+ const replacement = stub('A', 'beta');
152
+ reg.register(replacement, { allowOverwrite: true });
153
+ expect(reg.getById('A')).toBe(replacement);
154
+ expect(reg.getByName('beta')).toBe(replacement);
155
+ // The stale 'alpha' name mapping is gone.
156
+ expect(reg.getByName('alpha')).toBeUndefined();
157
+ expect(reg.size).toBe(1);
158
+ });
159
+ it('rejects { allowOverwrite: true, throwOnDuplicate: true } as mutually exclusive', () => {
160
+ // The two flags advertise contradictory semantics; passing both
161
+ // is a programmer error and should throw rather than silently
162
+ // pick one (audit 2026-05-23 / N3).
163
+ expect(() => reg.register(stub('A', 'alpha'), {
164
+ allowOverwrite: true,
165
+ throwOnDuplicate: true,
166
+ })).toThrow(ValidationError);
167
+ });
168
+ });
169
+ });
170
+ //# sourceMappingURL=registry.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.test.js","sourceRoot":"","sources":["../../../src/recipes/__tests__/registry.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @fileoverview Characterization + unit tests for the generic recipe
3
+ * resolver (`resolveSelector`).
4
+ *
5
+ * The resolver is the selection algorithm fitness (`resolveChecks`) and
6
+ * simulation (in-service resolver) now delegate to. These tests lock its
7
+ * output for each arm, the predicate-override path, and the two
8
+ * programmer-error guards — independent of any tool (core cannot import
9
+ * fitness/sim). The real no-behavior-change proof for the tools lives in
10
+ * their own suites, which pass unedited; this pins the substrate itself.
11
+ *
12
+ * Expected outputs are asserted with explicit `toEqual` (not auto-filled
13
+ * snapshots) so the locked values are hand-reviewed in the diff.
14
+ *
15
+ * `minimatch` is not a core dependency, so the `pattern`/`all` glob matcher
16
+ * is a tiny test-only `*`-glob — sufficient for these fixtures; fitness
17
+ * injects the real `minimatch` in production.
18
+ */
19
+ export {};
20
+ //# sourceMappingURL=selector.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selector.test.d.ts","sourceRoot":"","sources":["../../../src/recipes/__tests__/selector.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * @fileoverview Characterization + unit tests for the generic recipe
3
+ * resolver (`resolveSelector`).
4
+ *
5
+ * The resolver is the selection algorithm fitness (`resolveChecks`) and
6
+ * simulation (in-service resolver) now delegate to. These tests lock its
7
+ * output for each arm, the predicate-override path, and the two
8
+ * programmer-error guards — independent of any tool (core cannot import
9
+ * fitness/sim). The real no-behavior-change proof for the tools lives in
10
+ * their own suites, which pass unedited; this pins the substrate itself.
11
+ *
12
+ * Expected outputs are asserted with explicit `toEqual` (not auto-filled
13
+ * snapshots) so the locked values are hand-reviewed in the diff.
14
+ *
15
+ * `minimatch` is not a core dependency, so the `pattern`/`all` glob matcher
16
+ * is a tiny test-only `*`-glob — sufficient for these fixtures; fitness
17
+ * injects the real `minimatch` in production.
18
+ */
19
+ import { describe, expect, it } from 'vitest';
20
+ import { SystemError } from '../../lib/errors.js';
21
+ import { resolveSelector } from '../selector.js';
22
+ /** Test-only `*`-glob matcher (exact match when the pattern has no `*`). */
23
+ function glob(target, pattern) {
24
+ if (!pattern.includes('*'))
25
+ return target === pattern;
26
+ const escaped = pattern
27
+ .split('*')
28
+ .map((part) => part.replaceAll(/[.+?^${}()|[\]\\]/g, String.raw `\$&`));
29
+ return new RegExp(`^${escaped.join('.*')}$`).test(target);
30
+ }
31
+ const items = [
32
+ { id: 'security:no-eval', name: 'security:no-eval', tags: ['security', 'architecture'] },
33
+ { id: 'security:no-exec', name: 'security:no-exec', tags: ['security'] },
34
+ { id: 'backend:no-sync-fs', name: 'backend:no-sync-fs', tags: ['backend'] },
35
+ { id: 'frontend:no-inline-style', name: 'frontend:no-inline-style', tags: ['frontend'] },
36
+ { id: 'architecture:layering', name: 'architecture:layering', tags: ['architecture'] },
37
+ { id: 'no-todo', name: 'no-todo', tags: [] },
38
+ { id: 'backend:max-params', name: 'backend:max-params', tags: ['backend', 'architecture'] },
39
+ { id: 'load-test', name: 'load-test', tags: ['load'], kind: 'load' },
40
+ ];
41
+ /** Fitness-style match targets: key + bare slug + `tag/bareSlug`. */
42
+ function buildMatchTargets(slug, tags = []) {
43
+ const targets = [slug];
44
+ const bare = slug.includes(':') ? slug.split(':').pop() : slug;
45
+ if (bare !== slug)
46
+ targets.push(bare);
47
+ for (const tag of tags)
48
+ targets.push(`${tag}/${bare}`);
49
+ return targets;
50
+ }
51
+ /** Fitness-shaped options: glob match + bare-slug → namespaced-key reverse lookup. */
52
+ const fitnessOpts = {
53
+ keysOf: (item) => buildMatchTargets(item.id, item.tags),
54
+ tagsOf: (item) => item.tags ?? [],
55
+ match: glob,
56
+ resolveExplicit: (id) => {
57
+ if (id.includes(':'))
58
+ return undefined;
59
+ const found = items.find((item) => item.id.endsWith(`:${id}`));
60
+ return found?.id;
61
+ },
62
+ };
63
+ const ids = (result) => result.map((item) => item.id);
64
+ describe('resolveSelector — built-in arms', () => {
65
+ it('explicit: exact key, bare-slug reverse lookup, request order, no de-dup', () => {
66
+ const result = resolveSelector({ type: 'explicit', ids: ['security:no-eval', 'no-todo', 'no-exec'] }, items, fitnessOpts);
67
+ expect(ids(result)).toEqual(['security:no-eval', 'no-todo', 'security:no-exec']);
68
+ });
69
+ it('all: no exclude returns every item in registration order', () => {
70
+ const result = resolveSelector({ type: 'all' }, items, fitnessOpts);
71
+ expect(ids(result)).toEqual([
72
+ 'security:no-eval',
73
+ 'security:no-exec',
74
+ 'backend:no-sync-fs',
75
+ 'frontend:no-inline-style',
76
+ 'architecture:layering',
77
+ 'no-todo',
78
+ 'backend:max-params',
79
+ 'load-test',
80
+ ]);
81
+ });
82
+ it('all: glob exclude drops matched keys', () => {
83
+ const result = resolveSelector({ type: 'all', exclude: ['security:*'] }, items, fitnessOpts);
84
+ expect(ids(result)).toEqual([
85
+ 'backend:no-sync-fs',
86
+ 'frontend:no-inline-style',
87
+ 'architecture:layering',
88
+ 'no-todo',
89
+ 'backend:max-params',
90
+ 'load-test',
91
+ ]);
92
+ });
93
+ it('tags: include intersection (exclude is over tags)', () => {
94
+ const result = resolveSelector({ type: 'tags', include: ['architecture'] }, items, fitnessOpts);
95
+ expect(ids(result)).toEqual([
96
+ 'security:no-eval',
97
+ 'architecture:layering',
98
+ 'backend:max-params',
99
+ ]);
100
+ });
101
+ it('tags: tag-based exclude removes matched items', () => {
102
+ const result = resolveSelector({ type: 'tags', include: ['architecture'], exclude: ['security'] }, items, fitnessOpts);
103
+ // security:no-eval carries the 'security' tag → excluded.
104
+ expect(ids(result)).toEqual(['architecture:layering', 'backend:max-params']);
105
+ });
106
+ it('pattern: include globs over match targets, minus exclude globs', () => {
107
+ const result = resolveSelector({ type: 'pattern', include: ['backend:*'] }, items, fitnessOpts);
108
+ expect(ids(result)).toEqual(['backend:no-sync-fs', 'backend:max-params']);
109
+ });
110
+ });
111
+ describe('resolveSelector — guards', () => {
112
+ it('throws SELECTOR_NO_MATCHER when an exclude arm has no injected matcher', () => {
113
+ const noMatch = {
114
+ keysOf: (item) => [item.id],
115
+ };
116
+ try {
117
+ resolveSelector({ type: 'all', exclude: ['x'] }, items, noMatch);
118
+ expect.unreachable('should have thrown');
119
+ }
120
+ catch (error) {
121
+ expect(error).toBeInstanceOf(SystemError);
122
+ expect(error.code).toBe('SYSTEM.CORE.SELECTOR_NO_MATCHER');
123
+ }
124
+ });
125
+ it('throws UNKNOWN_SELECTOR for a tool-only arm with no predicate', () => {
126
+ try {
127
+ resolveSelector({ type: 'kind', kinds: ['load'] }, items, fitnessOpts);
128
+ expect.unreachable('should have thrown');
129
+ }
130
+ catch (error) {
131
+ expect(error).toBeInstanceOf(SystemError);
132
+ expect(error.code).toBe('SYSTEM.CORE.UNKNOWN_SELECTOR');
133
+ }
134
+ });
135
+ });
136
+ describe('resolveSelector — predicate override (simulation-style)', () => {
137
+ const simOpts = {
138
+ keysOf: (item) => [item.id, item.name],
139
+ tagsOf: (item) => item.tags ?? [],
140
+ predicates: {
141
+ kind: (item, sel) => {
142
+ if (sel.type !== 'kind')
143
+ return false;
144
+ const kinds = new Set(sel.kinds);
145
+ const exclude = new Set(sel.exclude);
146
+ return (item.kind !== undefined &&
147
+ kinds.has(item.kind) &&
148
+ !exclude.has(item.id) &&
149
+ !exclude.has(item.name));
150
+ },
151
+ // sim's `tags` excludes on id/name (not tags) — overrides the built-in arm.
152
+ tags: (item, sel) => {
153
+ if (sel.type !== 'tags')
154
+ return false;
155
+ const include = new Set(sel.include);
156
+ const exclude = new Set(sel.exclude);
157
+ return ((item.tags ?? []).some((t) => include.has(t)) &&
158
+ !exclude.has(item.id) &&
159
+ !exclude.has(item.name));
160
+ },
161
+ },
162
+ };
163
+ it('kind predicate filters by item.kind', () => {
164
+ const result = resolveSelector({ type: 'kind', kinds: ['load'] }, items, simOpts);
165
+ expect(ids(result)).toEqual(['load-test']);
166
+ });
167
+ it('tags predicate excludes on id/name, not tags', () => {
168
+ const result = resolveSelector({ type: 'tags', include: ['architecture'], exclude: ['security:no-eval'] }, items, simOpts);
169
+ // 'security:no-eval' is excluded by id even though it carries 'architecture'.
170
+ expect(ids(result)).toEqual(['architecture:layering', 'backend:max-params']);
171
+ });
172
+ });
173
+ //# sourceMappingURL=selector.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selector.test.js","sourceRoot":"","sources":["../../../src/recipes/__tests__/selector.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * unit-config — scope-bound per-unit recipe config accessors. The lookup is
3
+ * bound to `currentScope()`, so reads outside any scope return `{}` and reads
4
+ * inside a scope return the slice stored by `setCurrentRecipeUnitConfig`.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=unit-config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unit-config.test.d.ts","sourceRoot":"","sources":["../../../src/recipes/__tests__/unit-config.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * unit-config — scope-bound per-unit recipe config accessors. The lookup is
3
+ * bound to `currentScope()`, so reads outside any scope return `{}` and reads
4
+ * inside a scope return the slice stored by `setCurrentRecipeUnitConfig`.
5
+ */
6
+ import { describe, it, expect } from 'vitest';
7
+ import { LanguageRegistry } from '../../languages/registry.js';
8
+ import { RunScope, runWithScopeSync } from '../../lib/run-scope.js';
9
+ import { ToolRegistry } from '../../tools/registry.js';
10
+ import { getUnitConfig, setCurrentRecipeUnitConfig, clearCurrentRecipeUnitConfig, } from '../unit-config.js';
11
+ /** Core-internal stand-ins for the retired `test-utils/with-scope` sugar
12
+ * (ADR-0040 — see verdict-policy.test.ts for the cycle rationale). */
13
+ const makeTestScope = () => new RunScope({ languages: new LanguageRegistry(), tools: new ToolRegistry() });
14
+ const withScopeSync = runWithScopeSync;
15
+ describe('getUnitConfig', () => {
16
+ it('returns an empty object when called outside any scope', () => {
17
+ expect(getUnitConfig('any-slug')).toEqual({});
18
+ });
19
+ it('returns an empty object for a scope with no config set', () => {
20
+ const scope = makeTestScope();
21
+ const result = withScopeSync(scope, () => getUnitConfig('missing'));
22
+ expect(result).toEqual({});
23
+ });
24
+ it('returns the stored slice for a matching slug', () => {
25
+ const scope = makeTestScope();
26
+ setCurrentRecipeUnitConfig(scope, { 'my-unit': { threshold: 42 } });
27
+ const result = withScopeSync(scope, () => getUnitConfig('my-unit'));
28
+ expect(result.threshold).toBe(42);
29
+ });
30
+ it('returns an empty object for a slug absent from a populated config', () => {
31
+ const scope = makeTestScope();
32
+ setCurrentRecipeUnitConfig(scope, { 'other-unit': { threshold: 1 } });
33
+ const result = withScopeSync(scope, () => getUnitConfig('my-unit'));
34
+ expect(result).toEqual({});
35
+ });
36
+ });
37
+ describe('setCurrentRecipeUnitConfig / clearCurrentRecipeUnitConfig', () => {
38
+ it('treats an undefined config as an empty map', () => {
39
+ const scope = makeTestScope();
40
+ setCurrentRecipeUnitConfig(scope, undefined);
41
+ const result = withScopeSync(scope, () => getUnitConfig('my-unit'));
42
+ expect(result).toEqual({});
43
+ });
44
+ it('clear() removes a previously-set slice', () => {
45
+ const scope = makeTestScope();
46
+ setCurrentRecipeUnitConfig(scope, { 'my-unit': { threshold: 7 } });
47
+ expect(withScopeSync(scope, () => getUnitConfig('my-unit')).threshold).toBe(7);
48
+ clearCurrentRecipeUnitConfig(scope);
49
+ expect(withScopeSync(scope, () => getUnitConfig('my-unit'))).toEqual({});
50
+ });
51
+ });
52
+ //# sourceMappingURL=unit-config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unit-config.test.js","sourceRoot":"","sources":["../../../src/recipes/__tests__/unit-config.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * @fileoverview Generic recipe registry — shared plumbing for fitness
3
+ * and simulation recipe registries.
4
+ *
5
+ * Both fitness and simulation expose a "recipe" concept (a named bundle
6
+ * of selectors + execution options). The registry data structure they
7
+ * need is identical: a Map by id, a Map by name, register/lookup
8
+ * helpers, and a guarded duplicate-id policy. Only the recipe service —
9
+ * how a recipe's selector is resolved against the corresponding tool's
10
+ * registry of checks/scenarios — legitimately differs between the two
11
+ * tools, so the service stays per-package.
12
+ *
13
+ * Implemented on top of the kernel's unified `Registry<T>` base.
14
+ * `RecipeRegistry<T>` exposes the historical `allowOverwrite +
15
+ * throwOnDuplicate` flag-pair surface and routes per-call to the
16
+ * appropriate `inner.register(...)` invocation.
17
+ *
18
+ * The temp `protected byId`/`byName` shim that Phase 2 introduced is
19
+ * gone — both subclasses (`FitnessRecipeRegistry`,
20
+ * `SimulationRecipeRegistry`) now seed built-ins via
21
+ * `registerAll(builtIns, { internal: true })` (LSP-clean).
22
+ */
23
+ import { Registry, type Registerable } from '../lib/registry.js';
24
+ import type { Logger } from '../lib/logger.js';
25
+ /** Minimum shape any recipe must satisfy to live in a `RecipeRegistry`. */
26
+ export interface RecipeBase extends Registerable {
27
+ readonly id: string;
28
+ readonly name: string;
29
+ readonly displayName: string;
30
+ readonly description: string;
31
+ readonly tags?: readonly string[];
32
+ }
33
+ /** Options for a single `register` call. */
34
+ export interface RecipeRegisterOptions {
35
+ /** Allow replacing an existing entry with the same id or name. */
36
+ readonly allowOverwrite?: boolean;
37
+ /**
38
+ * Throw a `ValidationError` on duplicate id/name instead of the
39
+ * default "warn-and-skip" behaviour. Use this for registries where
40
+ * historical callers relied on a thrown error (e.g. user recipe
41
+ * loaders that signal config errors via exceptions).
42
+ */
43
+ readonly throwOnDuplicate?: boolean;
44
+ /**
45
+ * Validation-error code surfaced when `throwOnDuplicate` fires.
46
+ * Falls back to the registry's `validationCode` constructor option.
47
+ */
48
+ readonly validationCode?: string;
49
+ /**
50
+ * Bypass the duplicate guard for this call. Used by built-in
51
+ * seeding paths in `FitnessRecipeRegistry` / `SimulationRecipeRegistry`;
52
+ * not part of the public surface for user code.
53
+ */
54
+ readonly internal?: boolean;
55
+ }
56
+ /** Constructor options for a `RecipeRegistry<T>`. */
57
+ export interface RecipeRegistryOptions {
58
+ /** Human label used in log/throw messages — e.g. `'fitness'`, `'simulation'`. */
59
+ readonly module?: string;
60
+ /** Default validation error code on duplicate when `throwOnDuplicate` is set. */
61
+ readonly validationCode?: string;
62
+ readonly logger?: Logger;
63
+ }
64
+ /**
65
+ * Process-wide policy: duplicate id/name with `allowOverwrite: false`
66
+ * keeps the first entry and emits a warning. Use `register(.., {
67
+ * throwOnDuplicate: true })` to opt into the historical fitness/sim
68
+ * "throw on duplicate" contract.
69
+ */
70
+ export declare class RecipeRegistry<T extends RecipeBase> {
71
+ protected readonly inner: Registry<T>;
72
+ private readonly module;
73
+ private readonly validationCode;
74
+ constructor(options?: RecipeRegistryOptions);
75
+ /**
76
+ * Register a recipe.
77
+ *
78
+ * - Default: refuses on duplicate id/name; logs a `recipe.registry.duplicate` warning.
79
+ * - `{ allowOverwrite: true }`: replaces the existing entry.
80
+ * - `{ throwOnDuplicate: true }`: throws a `ValidationError` instead of warning.
81
+ * Mutually exclusive with `allowOverwrite`.
82
+ * - `{ internal: true }`: bypasses the duplicate guard. Used for
83
+ * built-in seeding in subclasses.
84
+ */
85
+ register(recipe: T, options?: RecipeRegisterOptions): void;
86
+ /** Register many recipes with shared options. */
87
+ registerAll(recipes: readonly T[], options?: RecipeRegisterOptions): void;
88
+ /** Look up a recipe by name first, falling back to id. */
89
+ loadRecipe(nameOrId: string): T | undefined;
90
+ getByName(name: string): T | undefined;
91
+ getById(id: string): T | undefined;
92
+ has(nameOrId: string): boolean;
93
+ /** All registered recipes, in registration order. */
94
+ getAllRecipes(): readonly T[];
95
+ /** All registered recipe names, in registration order. */
96
+ getNames(): readonly string[];
97
+ /** Recipes with a given tag. */
98
+ getByTag(tag: string): readonly T[];
99
+ get size(): number;
100
+ /** Remove a recipe by id. Returns true if it existed. */
101
+ remove(id: string): boolean;
102
+ /** Drop every entry. */
103
+ clear(): void;
104
+ }
105
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/recipes/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE/C,2EAA2E;AAC3E,MAAM,WAAW,UAAW,SAAQ,YAAY;IAC9C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,4CAA4C;AAC5C,MAAM,WAAW,qBAAqB;IACpC,kEAAkE;IAClE,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,qDAAqD;AACrD,MAAM,WAAW,qBAAqB;IACpC,iFAAiF;IACjF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,iFAAiF;IACjF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,qBAAa,cAAc,CAAC,CAAC,SAAS,UAAU;IAC9C,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;gBAE5B,OAAO,GAAE,qBAA0B;IAY/C;;;;;;;;;OASG;IACH,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,OAAO,GAAE,qBAA0B,GAAG,IAAI;IA+C9D,iDAAiD;IACjD,WAAW,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,EAAE,OAAO,GAAE,qBAA0B,GAAG,IAAI;IAM7E,0DAA0D;IAC1D,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAI3C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAItC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAIlC,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAI9B,qDAAqD;IACrD,aAAa,IAAI,SAAS,CAAC,EAAE;IAI7B,0DAA0D;IAC1D,QAAQ,IAAI,SAAS,MAAM,EAAE;IAI7B,gCAAgC;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC,EAAE;IAInC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,yDAAyD;IACzD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI3B,wBAAwB;IACxB,KAAK,IAAI,IAAI;CAGd"}