modestbench 0.1.0 → 0.3.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 (484) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +162 -57
  3. package/dist/bootstrap.cjs +10 -10
  4. package/dist/bootstrap.cjs.map +1 -1
  5. package/dist/bootstrap.d.cts.map +1 -1
  6. package/dist/bootstrap.d.ts.map +1 -1
  7. package/dist/bootstrap.js +5 -5
  8. package/dist/bootstrap.js.map +1 -1
  9. package/dist/cli/commands/analyze.cjs +60 -0
  10. package/dist/cli/commands/analyze.cjs.map +1 -0
  11. package/dist/cli/commands/analyze.d.cts +35 -0
  12. package/dist/cli/commands/analyze.d.cts.map +1 -0
  13. package/dist/cli/commands/analyze.d.ts +35 -0
  14. package/dist/cli/commands/analyze.d.ts.map +1 -0
  15. package/dist/cli/commands/analyze.js +56 -0
  16. package/dist/cli/commands/analyze.js.map +1 -0
  17. package/dist/cli/commands/baseline.cjs +404 -0
  18. package/dist/cli/commands/baseline.cjs.map +1 -0
  19. package/dist/cli/commands/baseline.d.cts +72 -0
  20. package/dist/cli/commands/baseline.d.cts.map +1 -0
  21. package/dist/cli/commands/baseline.d.ts +72 -0
  22. package/dist/cli/commands/baseline.d.ts.map +1 -0
  23. package/dist/cli/commands/baseline.js +396 -0
  24. package/dist/cli/commands/baseline.js.map +1 -0
  25. package/dist/cli/commands/history.cjs +108 -266
  26. package/dist/cli/commands/history.cjs.map +1 -1
  27. package/dist/cli/commands/history.d.cts +75 -12
  28. package/dist/cli/commands/history.d.cts.map +1 -1
  29. package/dist/cli/commands/history.d.ts +75 -12
  30. package/dist/cli/commands/history.d.ts.map +1 -1
  31. package/dist/cli/commands/history.js +105 -268
  32. package/dist/cli/commands/history.js.map +1 -1
  33. package/dist/cli/commands/init.cjs +88 -155
  34. package/dist/cli/commands/init.cjs.map +1 -1
  35. package/dist/cli/commands/init.d.cts +4 -4
  36. package/dist/cli/commands/init.d.cts.map +1 -1
  37. package/dist/cli/commands/init.d.ts +4 -4
  38. package/dist/cli/commands/init.d.ts.map +1 -1
  39. package/dist/cli/commands/init.js +88 -155
  40. package/dist/cli/commands/init.js.map +1 -1
  41. package/dist/cli/commands/run.cjs +143 -112
  42. package/dist/cli/commands/run.cjs.map +1 -1
  43. package/dist/cli/commands/run.d.cts +17 -3
  44. package/dist/cli/commands/run.d.cts.map +1 -1
  45. package/dist/cli/commands/run.d.ts +17 -3
  46. package/dist/cli/commands/run.d.ts.map +1 -1
  47. package/dist/cli/commands/run.js +142 -78
  48. package/dist/cli/commands/run.js.map +1 -1
  49. package/dist/cli/index.cjs +671 -266
  50. package/dist/cli/index.cjs.map +1 -1
  51. package/dist/cli/index.d.cts +4 -16
  52. package/dist/cli/index.d.cts.map +1 -1
  53. package/dist/cli/index.d.ts +4 -16
  54. package/dist/cli/index.d.ts.map +1 -1
  55. package/dist/cli/index.js +664 -259
  56. package/dist/cli/index.js.map +1 -1
  57. package/dist/config/budget-schema.cjs +172 -0
  58. package/dist/config/budget-schema.cjs.map +1 -0
  59. package/dist/config/budget-schema.d.cts +59 -0
  60. package/dist/config/budget-schema.d.cts.map +1 -0
  61. package/dist/config/budget-schema.d.ts +59 -0
  62. package/dist/config/budget-schema.d.ts.map +1 -0
  63. package/dist/config/budget-schema.js +166 -0
  64. package/dist/config/budget-schema.js.map +1 -0
  65. package/dist/config/schema.cjs +182 -2
  66. package/dist/config/schema.cjs.map +1 -1
  67. package/dist/config/schema.d.cts +122 -3
  68. package/dist/config/schema.d.cts.map +1 -1
  69. package/dist/config/schema.d.ts +122 -3
  70. package/dist/config/schema.d.ts.map +1 -1
  71. package/dist/config/schema.js +180 -1
  72. package/dist/config/schema.js.map +1 -1
  73. package/dist/constants.cjs +45 -2
  74. package/dist/constants.cjs.map +1 -1
  75. package/dist/constants.d.cts +41 -0
  76. package/dist/constants.d.cts.map +1 -1
  77. package/dist/constants.d.ts +41 -0
  78. package/dist/constants.d.ts.map +1 -1
  79. package/dist/constants.js +44 -1
  80. package/dist/constants.js.map +1 -1
  81. package/dist/core/engine.cjs +104 -15
  82. package/dist/core/engine.cjs.map +1 -1
  83. package/dist/core/engine.d.cts +7 -4
  84. package/dist/core/engine.d.cts.map +1 -1
  85. package/dist/core/engine.d.ts +7 -4
  86. package/dist/core/engine.d.ts.map +1 -1
  87. package/dist/core/engine.js +105 -16
  88. package/dist/core/engine.js.map +1 -1
  89. package/dist/core/output-path-resolver.cjs +41 -0
  90. package/dist/core/output-path-resolver.cjs.map +1 -0
  91. package/dist/core/output-path-resolver.d.cts +10 -0
  92. package/dist/core/output-path-resolver.d.cts.map +1 -0
  93. package/dist/core/output-path-resolver.d.ts +10 -0
  94. package/dist/core/output-path-resolver.d.ts.map +1 -0
  95. package/dist/core/output-path-resolver.js +37 -0
  96. package/dist/core/output-path-resolver.js.map +1 -0
  97. package/dist/errors/base.cjs +12 -3
  98. package/dist/errors/base.cjs.map +1 -1
  99. package/dist/errors/base.d.cts +7 -0
  100. package/dist/errors/base.d.cts.map +1 -1
  101. package/dist/errors/base.d.ts +7 -0
  102. package/dist/errors/base.d.ts.map +1 -1
  103. package/dist/errors/base.js +10 -2
  104. package/dist/errors/base.js.map +1 -1
  105. package/dist/errors/budget.cjs +37 -0
  106. package/dist/errors/budget.cjs.map +1 -0
  107. package/dist/errors/budget.d.cts +31 -0
  108. package/dist/errors/budget.d.cts.map +1 -0
  109. package/dist/errors/budget.d.ts +31 -0
  110. package/dist/errors/budget.d.ts.map +1 -0
  111. package/dist/errors/budget.js +33 -0
  112. package/dist/errors/budget.js.map +1 -0
  113. package/dist/errors/index.cjs +4 -1
  114. package/dist/errors/index.cjs.map +1 -1
  115. package/dist/errors/index.d.cts +1 -0
  116. package/dist/errors/index.d.cts.map +1 -1
  117. package/dist/errors/index.d.ts +1 -0
  118. package/dist/errors/index.d.ts.map +1 -1
  119. package/dist/errors/index.js +2 -0
  120. package/dist/errors/index.js.map +1 -1
  121. package/dist/formatters/history/base.cjs +9 -0
  122. package/dist/formatters/history/base.cjs.map +1 -0
  123. package/dist/formatters/history/base.d.cts +26 -0
  124. package/dist/formatters/history/base.d.cts.map +1 -0
  125. package/dist/formatters/history/base.d.ts +26 -0
  126. package/dist/formatters/history/base.d.ts.map +1 -0
  127. package/dist/formatters/history/base.js +8 -0
  128. package/dist/formatters/history/base.js.map +1 -0
  129. package/dist/formatters/history/compare.cjs +127 -0
  130. package/dist/formatters/history/compare.cjs.map +1 -0
  131. package/dist/formatters/history/compare.d.cts +21 -0
  132. package/dist/formatters/history/compare.d.cts.map +1 -0
  133. package/dist/formatters/history/compare.d.ts +21 -0
  134. package/dist/formatters/history/compare.d.ts.map +1 -0
  135. package/dist/formatters/history/compare.js +123 -0
  136. package/dist/formatters/history/compare.js.map +1 -0
  137. package/dist/formatters/history/list.cjs +74 -0
  138. package/dist/formatters/history/list.cjs.map +1 -0
  139. package/dist/formatters/history/list.d.cts +25 -0
  140. package/dist/formatters/history/list.d.cts.map +1 -0
  141. package/dist/formatters/history/list.d.ts +25 -0
  142. package/dist/formatters/history/list.d.ts.map +1 -0
  143. package/dist/formatters/history/list.js +70 -0
  144. package/dist/formatters/history/list.js.map +1 -0
  145. package/dist/formatters/history/show.cjs +98 -0
  146. package/dist/formatters/history/show.cjs.map +1 -0
  147. package/dist/formatters/history/show.d.cts +21 -0
  148. package/dist/formatters/history/show.d.cts.map +1 -0
  149. package/dist/formatters/history/show.d.ts +21 -0
  150. package/dist/formatters/history/show.d.ts.map +1 -0
  151. package/dist/formatters/history/show.js +94 -0
  152. package/dist/formatters/history/show.js.map +1 -0
  153. package/dist/formatters/history/trends.cjs +194 -0
  154. package/dist/formatters/history/trends.cjs.map +1 -0
  155. package/dist/formatters/history/trends.d.cts +22 -0
  156. package/dist/formatters/history/trends.d.cts.map +1 -0
  157. package/dist/formatters/history/trends.d.ts +22 -0
  158. package/dist/formatters/history/trends.d.ts.map +1 -0
  159. package/dist/formatters/history/trends.js +190 -0
  160. package/dist/formatters/history/trends.js.map +1 -0
  161. package/dist/formatters/history/visualization.cjs +79 -0
  162. package/dist/formatters/history/visualization.cjs.map +1 -0
  163. package/dist/formatters/history/visualization.d.cts +24 -0
  164. package/dist/formatters/history/visualization.d.cts.map +1 -0
  165. package/dist/formatters/history/visualization.d.ts +24 -0
  166. package/dist/formatters/history/visualization.d.ts.map +1 -0
  167. package/dist/formatters/history/visualization.js +74 -0
  168. package/dist/formatters/history/visualization.js.map +1 -0
  169. package/dist/index.cjs +27 -17
  170. package/dist/index.cjs.map +1 -1
  171. package/dist/index.d.cts +10 -5
  172. package/dist/index.d.cts.map +1 -1
  173. package/dist/index.d.ts +10 -5
  174. package/dist/index.d.ts.map +1 -1
  175. package/dist/index.js +14 -9
  176. package/dist/index.js.map +1 -1
  177. package/dist/reporters/csv.cjs +39 -19
  178. package/dist/reporters/csv.cjs.map +1 -1
  179. package/dist/reporters/csv.d.cts +4 -7
  180. package/dist/reporters/csv.d.cts.map +1 -1
  181. package/dist/reporters/csv.d.ts +4 -7
  182. package/dist/reporters/csv.d.ts.map +1 -1
  183. package/dist/reporters/csv.js +38 -18
  184. package/dist/reporters/csv.js.map +1 -1
  185. package/dist/reporters/human.cjs +87 -99
  186. package/dist/reporters/human.cjs.map +1 -1
  187. package/dist/reporters/human.d.cts +15 -14
  188. package/dist/reporters/human.d.cts.map +1 -1
  189. package/dist/reporters/human.d.ts +15 -14
  190. package/dist/reporters/human.d.ts.map +1 -1
  191. package/dist/reporters/human.js +68 -80
  192. package/dist/reporters/human.js.map +1 -1
  193. package/dist/reporters/json.cjs +25 -50
  194. package/dist/reporters/json.cjs.map +1 -1
  195. package/dist/reporters/json.d.cts +3 -29
  196. package/dist/reporters/json.d.cts.map +1 -1
  197. package/dist/reporters/json.d.ts +3 -29
  198. package/dist/reporters/json.d.ts.map +1 -1
  199. package/dist/reporters/json.js +26 -51
  200. package/dist/reporters/json.js.map +1 -1
  201. package/dist/reporters/profile-human.cjs +149 -0
  202. package/dist/reporters/profile-human.cjs.map +1 -0
  203. package/dist/reporters/profile-human.d.cts +44 -0
  204. package/dist/reporters/profile-human.d.cts.map +1 -0
  205. package/dist/reporters/profile-human.d.ts +44 -0
  206. package/dist/reporters/profile-human.d.ts.map +1 -0
  207. package/dist/reporters/profile-human.js +142 -0
  208. package/dist/reporters/profile-human.js.map +1 -0
  209. package/dist/reporters/simple.cjs +66 -46
  210. package/dist/reporters/simple.cjs.map +1 -1
  211. package/dist/reporters/simple.d.cts +15 -15
  212. package/dist/reporters/simple.d.cts.map +1 -1
  213. package/dist/reporters/simple.d.ts +15 -15
  214. package/dist/reporters/simple.d.ts.map +1 -1
  215. package/dist/reporters/simple.js +65 -45
  216. package/dist/reporters/simple.js.map +1 -1
  217. package/dist/schema/modestbench-config.schema.json +153 -0
  218. package/dist/services/baseline-storage.cjs +151 -0
  219. package/dist/services/baseline-storage.cjs.map +1 -0
  220. package/dist/services/baseline-storage.d.cts +55 -0
  221. package/dist/services/baseline-storage.d.cts.map +1 -0
  222. package/dist/services/baseline-storage.d.ts +55 -0
  223. package/dist/services/baseline-storage.d.ts.map +1 -0
  224. package/dist/services/baseline-storage.js +147 -0
  225. package/dist/services/baseline-storage.js.map +1 -0
  226. package/dist/services/budget-evaluator.cjs +146 -0
  227. package/dist/services/budget-evaluator.cjs.map +1 -0
  228. package/dist/services/budget-evaluator.d.cts +29 -0
  229. package/dist/services/budget-evaluator.d.cts.map +1 -0
  230. package/dist/services/budget-evaluator.d.ts +29 -0
  231. package/dist/services/budget-evaluator.d.ts.map +1 -0
  232. package/dist/services/budget-evaluator.js +142 -0
  233. package/dist/services/budget-evaluator.js.map +1 -0
  234. package/dist/{config/manager.cjs → services/config-manager.cjs} +25 -11
  235. package/dist/services/config-manager.cjs.map +1 -0
  236. package/dist/{config/manager.d.cts → services/config-manager.d.cts} +7 -2
  237. package/dist/services/config-manager.d.cts.map +1 -0
  238. package/dist/{config/manager.d.ts → services/config-manager.d.ts} +7 -2
  239. package/dist/services/config-manager.d.ts.map +1 -0
  240. package/dist/{config/manager.js → services/config-manager.js} +25 -11
  241. package/dist/services/config-manager.js.map +1 -0
  242. package/dist/{core/loader.cjs → services/file-loader.cjs} +5 -8
  243. package/dist/services/file-loader.cjs.map +1 -0
  244. package/dist/{core/loader.d.cts → services/file-loader.d.cts} +1 -1
  245. package/dist/services/file-loader.d.cts.map +1 -0
  246. package/dist/{core/loader.d.ts → services/file-loader.d.ts} +1 -1
  247. package/dist/services/file-loader.d.ts.map +1 -0
  248. package/dist/{core/loader.js → services/file-loader.js} +5 -8
  249. package/dist/services/file-loader.js.map +1 -0
  250. package/dist/services/history/comparison.cjs +124 -0
  251. package/dist/services/history/comparison.cjs.map +1 -0
  252. package/dist/services/history/comparison.d.cts +18 -0
  253. package/dist/services/history/comparison.d.cts.map +1 -0
  254. package/dist/services/history/comparison.d.ts +18 -0
  255. package/dist/services/history/comparison.d.ts.map +1 -0
  256. package/dist/services/history/comparison.js +120 -0
  257. package/dist/services/history/comparison.js.map +1 -0
  258. package/dist/services/history/models.cjs +9 -0
  259. package/dist/services/history/models.cjs.map +1 -0
  260. package/dist/services/history/models.d.cts +139 -0
  261. package/dist/services/history/models.d.cts.map +1 -0
  262. package/dist/services/history/models.d.ts +139 -0
  263. package/dist/services/history/models.d.ts.map +1 -0
  264. package/dist/services/history/models.js +8 -0
  265. package/dist/services/history/models.js.map +1 -0
  266. package/dist/services/history/query.cjs +97 -0
  267. package/dist/services/history/query.cjs.map +1 -0
  268. package/dist/services/history/query.d.cts +38 -0
  269. package/dist/services/history/query.d.cts.map +1 -0
  270. package/dist/services/history/query.d.ts +38 -0
  271. package/dist/services/history/query.d.ts.map +1 -0
  272. package/dist/services/history/query.js +92 -0
  273. package/dist/services/history/query.js.map +1 -0
  274. package/dist/services/history/trend-analysis.cjs +187 -0
  275. package/dist/services/history/trend-analysis.cjs.map +1 -0
  276. package/dist/services/history/trend-analysis.d.cts +34 -0
  277. package/dist/services/history/trend-analysis.d.cts.map +1 -0
  278. package/dist/services/history/trend-analysis.d.ts +34 -0
  279. package/dist/services/history/trend-analysis.d.ts.map +1 -0
  280. package/dist/services/history/trend-analysis.js +179 -0
  281. package/dist/services/history/trend-analysis.js.map +1 -0
  282. package/dist/{storage/history.cjs → services/history-storage.cjs} +1 -1
  283. package/dist/services/history-storage.cjs.map +1 -0
  284. package/dist/{storage/history.d.cts → services/history-storage.d.cts} +1 -1
  285. package/dist/services/history-storage.d.cts.map +1 -0
  286. package/dist/{storage/history.d.ts → services/history-storage.d.ts} +1 -1
  287. package/dist/services/history-storage.d.ts.map +1 -0
  288. package/dist/{storage/history.js → services/history-storage.js} +1 -1
  289. package/dist/services/history-storage.js.map +1 -0
  290. package/dist/services/profiler/profile-filter.cjs +113 -0
  291. package/dist/services/profiler/profile-filter.cjs.map +1 -0
  292. package/dist/services/profiler/profile-filter.d.cts +20 -0
  293. package/dist/services/profiler/profile-filter.d.cts.map +1 -0
  294. package/dist/services/profiler/profile-filter.d.ts +20 -0
  295. package/dist/services/profiler/profile-filter.d.ts.map +1 -0
  296. package/dist/services/profiler/profile-filter.js +109 -0
  297. package/dist/services/profiler/profile-filter.js.map +1 -0
  298. package/dist/services/profiler/profile-parser.cjs +139 -0
  299. package/dist/services/profiler/profile-parser.cjs.map +1 -0
  300. package/dist/services/profiler/profile-parser.d.cts +18 -0
  301. package/dist/services/profiler/profile-parser.d.cts.map +1 -0
  302. package/dist/services/profiler/profile-parser.d.ts +18 -0
  303. package/dist/services/profiler/profile-parser.d.ts.map +1 -0
  304. package/dist/services/profiler/profile-parser.js +132 -0
  305. package/dist/services/profiler/profile-parser.js.map +1 -0
  306. package/dist/services/profiler/profile-runner.cjs +90 -0
  307. package/dist/services/profiler/profile-runner.cjs.map +1 -0
  308. package/dist/services/profiler/profile-runner.d.cts +29 -0
  309. package/dist/services/profiler/profile-runner.d.cts.map +1 -0
  310. package/dist/services/profiler/profile-runner.d.ts +29 -0
  311. package/dist/services/profiler/profile-runner.d.ts.map +1 -0
  312. package/dist/services/profiler/profile-runner.js +86 -0
  313. package/dist/services/profiler/profile-runner.js.map +1 -0
  314. package/dist/{progress/manager.cjs → services/progress-manager.cjs} +1 -1
  315. package/dist/services/progress-manager.cjs.map +1 -0
  316. package/dist/{progress/manager.d.cts → services/progress-manager.d.cts} +1 -1
  317. package/dist/services/progress-manager.d.cts.map +1 -0
  318. package/dist/{progress/manager.d.ts → services/progress-manager.d.ts} +1 -1
  319. package/dist/services/progress-manager.d.ts.map +1 -0
  320. package/dist/{progress/manager.js → services/progress-manager.js} +1 -1
  321. package/dist/services/progress-manager.js.map +1 -0
  322. package/dist/{reporters/registry.cjs → services/reporter-registry.cjs} +19 -25
  323. package/dist/services/reporter-registry.cjs.map +1 -0
  324. package/dist/{reporters/registry.d.cts → services/reporter-registry.d.cts} +19 -41
  325. package/dist/services/reporter-registry.d.cts.map +1 -0
  326. package/dist/{reporters/registry.d.ts → services/reporter-registry.d.ts} +19 -41
  327. package/dist/services/reporter-registry.d.ts.map +1 -0
  328. package/dist/{reporters/registry.js → services/reporter-registry.js} +19 -25
  329. package/dist/services/reporter-registry.js.map +1 -0
  330. package/dist/types/budgets.cjs +8 -0
  331. package/dist/types/budgets.cjs.map +1 -0
  332. package/dist/types/budgets.d.cts +149 -0
  333. package/dist/types/budgets.d.cts.map +1 -0
  334. package/dist/types/budgets.d.ts +149 -0
  335. package/dist/types/budgets.d.ts.map +1 -0
  336. package/dist/types/budgets.js +7 -0
  337. package/dist/types/budgets.js.map +1 -0
  338. package/dist/types/cli.cjs +2 -11
  339. package/dist/types/cli.cjs.map +1 -1
  340. package/dist/types/cli.d.cts +3 -224
  341. package/dist/types/cli.d.cts.map +1 -1
  342. package/dist/types/cli.d.ts +3 -224
  343. package/dist/types/cli.d.ts.map +1 -1
  344. package/dist/types/cli.js +2 -11
  345. package/dist/types/cli.js.map +1 -1
  346. package/dist/types/core.cjs +6 -1
  347. package/dist/types/core.cjs.map +1 -1
  348. package/dist/types/core.d.cts +13 -2
  349. package/dist/types/core.d.cts.map +1 -1
  350. package/dist/types/core.d.ts +13 -2
  351. package/dist/types/core.d.ts.map +1 -1
  352. package/dist/types/core.js +2 -1
  353. package/dist/types/core.js.map +1 -1
  354. package/dist/types/index.cjs +5 -0
  355. package/dist/types/index.cjs.map +1 -1
  356. package/dist/types/index.d.cts +2 -0
  357. package/dist/types/index.d.cts.map +1 -1
  358. package/dist/types/index.d.ts +2 -0
  359. package/dist/types/index.d.ts.map +1 -1
  360. package/dist/types/index.js +2 -0
  361. package/dist/types/index.js.map +1 -1
  362. package/dist/types/interfaces.d.cts +15 -8
  363. package/dist/types/interfaces.d.cts.map +1 -1
  364. package/dist/types/interfaces.d.ts +15 -8
  365. package/dist/types/interfaces.d.ts.map +1 -1
  366. package/dist/types/profiler.cjs +11 -0
  367. package/dist/types/profiler.cjs.map +1 -0
  368. package/dist/types/profiler.d.cts +100 -0
  369. package/dist/types/profiler.d.cts.map +1 -0
  370. package/dist/types/profiler.d.ts +100 -0
  371. package/dist/types/profiler.d.ts.map +1 -0
  372. package/dist/types/profiler.js +10 -0
  373. package/dist/types/profiler.js.map +1 -0
  374. package/dist/types/utility.cjs.map +1 -1
  375. package/dist/types/utility.d.cts +0 -8
  376. package/dist/types/utility.d.cts.map +1 -1
  377. package/dist/types/utility.d.ts +0 -8
  378. package/dist/types/utility.d.ts.map +1 -1
  379. package/dist/types/utility.js.map +1 -1
  380. package/dist/utils/ansi.cjs +61 -0
  381. package/dist/utils/ansi.cjs.map +1 -0
  382. package/dist/utils/ansi.d.cts +53 -0
  383. package/dist/utils/ansi.d.cts.map +1 -0
  384. package/dist/utils/ansi.d.ts +53 -0
  385. package/dist/utils/ansi.d.ts.map +1 -0
  386. package/dist/utils/ansi.js +57 -0
  387. package/dist/utils/ansi.js.map +1 -0
  388. package/dist/utils/identifiers.cjs +32 -0
  389. package/dist/utils/identifiers.cjs.map +1 -0
  390. package/dist/utils/identifiers.d.cts +32 -0
  391. package/dist/utils/identifiers.d.cts.map +1 -0
  392. package/dist/utils/identifiers.d.ts +32 -0
  393. package/dist/utils/identifiers.d.ts.map +1 -0
  394. package/dist/utils/identifiers.js +27 -0
  395. package/dist/utils/identifiers.js.map +1 -0
  396. package/dist/utils/package.cjs +40 -0
  397. package/dist/utils/package.cjs.map +1 -0
  398. package/dist/utils/package.d.cts +15 -0
  399. package/dist/utils/package.d.cts.map +1 -0
  400. package/dist/utils/package.d.ts +15 -0
  401. package/dist/utils/package.d.ts.map +1 -0
  402. package/dist/utils/package.js +33 -0
  403. package/dist/utils/package.js.map +1 -0
  404. package/dist/utils/type-guards.cjs +48 -0
  405. package/dist/utils/type-guards.cjs.map +1 -0
  406. package/dist/utils/type-guards.d.cts +22 -0
  407. package/dist/utils/type-guards.d.cts.map +1 -0
  408. package/dist/utils/type-guards.d.ts +22 -0
  409. package/dist/utils/type-guards.d.ts.map +1 -0
  410. package/dist/utils/type-guards.js +43 -0
  411. package/dist/utils/type-guards.js.map +1 -0
  412. package/package.json +14 -13
  413. package/src/bootstrap.ts +5 -5
  414. package/src/cli/commands/analyze.ts +101 -0
  415. package/src/cli/commands/baseline.ts +577 -0
  416. package/src/cli/commands/history.ts +194 -342
  417. package/src/cli/commands/init.ts +105 -183
  418. package/src/cli/commands/run.ts +186 -88
  419. package/src/cli/index.ts +731 -234
  420. package/src/config/budget-schema.ts +189 -0
  421. package/src/config/schema.ts +260 -1
  422. package/src/constants.ts +53 -1
  423. package/src/core/engine.ts +153 -14
  424. package/src/core/output-path-resolver.ts +46 -0
  425. package/src/errors/base.ts +11 -2
  426. package/src/errors/budget.ts +38 -0
  427. package/src/errors/index.ts +3 -0
  428. package/src/formatters/history/base.ts +28 -0
  429. package/src/formatters/history/compare.ts +186 -0
  430. package/src/formatters/history/list.ts +101 -0
  431. package/src/formatters/history/show.ts +155 -0
  432. package/src/formatters/history/trends.ts +281 -0
  433. package/src/formatters/history/visualization.ts +93 -0
  434. package/src/index.ts +17 -12
  435. package/src/reporters/csv.ts +55 -26
  436. package/src/reporters/human.ts +90 -89
  437. package/src/reporters/json.ts +27 -72
  438. package/src/reporters/profile-human.ts +204 -0
  439. package/src/reporters/simple.ts +85 -54
  440. package/src/services/baseline-storage.ts +199 -0
  441. package/src/services/budget-evaluator.ts +182 -0
  442. package/src/{config/manager.ts → services/config-manager.ts} +24 -9
  443. package/src/{core/loader.ts → services/file-loader.ts} +4 -7
  444. package/src/services/history/comparison.ts +130 -0
  445. package/src/services/history/models.ts +148 -0
  446. package/src/services/history/query.ts +116 -0
  447. package/src/services/history/trend-analysis.ts +238 -0
  448. package/src/services/profiler/profile-filter.ts +143 -0
  449. package/src/services/profiler/profile-parser.ts +194 -0
  450. package/src/services/profiler/profile-runner.ts +121 -0
  451. package/src/{reporters/registry.ts → services/reporter-registry.ts} +46 -81
  452. package/src/types/budgets.ts +180 -0
  453. package/src/types/cli.ts +5 -235
  454. package/src/types/core.ts +50 -10
  455. package/src/types/index.ts +5 -0
  456. package/src/types/interfaces.ts +16 -6
  457. package/src/types/profiler.ts +132 -0
  458. package/src/types/utility.ts +0 -10
  459. package/src/utils/ansi.ts +59 -0
  460. package/src/utils/identifiers.ts +58 -0
  461. package/src/utils/package.ts +35 -0
  462. package/src/utils/type-guards.ts +51 -0
  463. package/dist/config/manager.cjs.map +0 -1
  464. package/dist/config/manager.d.cts.map +0 -1
  465. package/dist/config/manager.d.ts.map +0 -1
  466. package/dist/config/manager.js.map +0 -1
  467. package/dist/core/loader.cjs.map +0 -1
  468. package/dist/core/loader.d.cts.map +0 -1
  469. package/dist/core/loader.d.ts.map +0 -1
  470. package/dist/core/loader.js.map +0 -1
  471. package/dist/progress/manager.cjs.map +0 -1
  472. package/dist/progress/manager.d.cts.map +0 -1
  473. package/dist/progress/manager.d.ts.map +0 -1
  474. package/dist/progress/manager.js.map +0 -1
  475. package/dist/reporters/registry.cjs.map +0 -1
  476. package/dist/reporters/registry.d.cts.map +0 -1
  477. package/dist/reporters/registry.d.ts.map +0 -1
  478. package/dist/reporters/registry.js.map +0 -1
  479. package/dist/storage/history.cjs.map +0 -1
  480. package/dist/storage/history.d.cts.map +0 -1
  481. package/dist/storage/history.d.ts.map +0 -1
  482. package/dist/storage/history.js.map +0 -1
  483. /package/src/{storage/history.ts → services/history-storage.ts} +0 -0
  484. /package/src/{progress/manager.ts → services/progress-manager.ts} +0 -0
@@ -7,16 +7,36 @@
7
7
 
8
8
  import { resolve } from 'node:path';
9
9
 
10
- import type { BenchmarkRun } from '../../types/index.js';
10
+ import type { BenchmarkRun, ModestBenchConfig } from '../../types/index.js';
11
11
  import type { CliContext } from '../index.js';
12
12
 
13
13
  import { ErrorCodes } from '../../constants.js';
14
+ import { resolveOutputPath } from '../../core/output-path-resolver.js';
14
15
  import {
16
+ type BudgetExceededError,
15
17
  InvalidArgumentError,
16
- type ModestBenchError,
17
18
  UnknownReporterError,
18
19
  } from '../../errors/index.js';
20
+ import { CsvReporter } from '../../reporters/csv.js';
21
+ import { HumanReporter } from '../../reporters/human.js';
22
+ import { JsonReporter } from '../../reporters/json.js';
23
+ import { SimpleReporter } from '../../reporters/simple.js';
19
24
  import { ExitCodes } from '../../types/cli.js';
25
+ import { hasErrorCode, isError } from '../../utils/type-guards.js';
26
+
27
+ /**
28
+ * Default values for the run command
29
+ *
30
+ * These are the command-level defaults used when neither config file nor CLI
31
+ * arguments provide values. They represent sensible defaults for running
32
+ * benchmarks.
33
+ */
34
+ export const RUN_COMMAND_DEFAULTS = {
35
+ bail: false,
36
+ quiet: false,
37
+ reporters: ['human'],
38
+ verbose: false,
39
+ } as const satisfies Partial<ModestBenchConfig>;
20
40
 
21
41
  /**
22
42
  * Run command options interface
@@ -24,7 +44,7 @@ import { ExitCodes } from '../../types/cli.js';
24
44
  interface RunOptions {
25
45
  bail?: boolean | undefined;
26
46
  config?: string | undefined;
27
- cwd: string;
47
+ cwd?: string;
28
48
  engine?: 'accurate' | 'tinybench' | undefined;
29
49
  exclude?: string[] | undefined;
30
50
  excludeTags?: string[] | undefined;
@@ -32,10 +52,11 @@ interface RunOptions {
32
52
  json?: boolean | undefined;
33
53
  noColor?: boolean | undefined;
34
54
  outputDir?: string | undefined;
35
- pattern: string[];
55
+ outputFile?: string | undefined;
56
+ pattern?: string[] | undefined;
36
57
  progress?: boolean | undefined;
37
58
  quiet?: boolean | undefined;
38
- reporters: string[];
59
+ reporters?: string[] | undefined;
39
60
  tags?: string[] | undefined;
40
61
  time?: number | undefined;
41
62
  timeout?: number | undefined;
@@ -61,6 +82,18 @@ export const handleRunCommand = async (
61
82
  const showCliMessages = verbose && !options.quiet;
62
83
 
63
84
  try {
85
+ // Validate --output-file usage
86
+ if (
87
+ options.outputFile &&
88
+ options.reporters &&
89
+ options.reporters.length > 1
90
+ ) {
91
+ throw new InvalidArgumentError(
92
+ '--output-file can only be used with a single reporter. ' +
93
+ 'Use --output <dir> for multiple reporters.',
94
+ );
95
+ }
96
+
64
97
  // Step 1: Load and merge configuration
65
98
  if (showCliMessages) {
66
99
  console.error('Loading configuration...');
@@ -71,14 +104,14 @@ export const handleRunCommand = async (
71
104
  if (showCliMessages) {
72
105
  console.error('Setting up reporters...');
73
106
  }
74
- const reporters = await setupReporters(
107
+ const reporters = setupReporters(
75
108
  context,
76
109
  config,
77
- shouldBeQuiet,
78
110
  verbose,
79
111
  showCliMessages,
80
112
  options.quiet ?? false,
81
113
  options.outputDir,
114
+ options.outputFile,
82
115
  options.progress,
83
116
  );
84
117
 
@@ -129,7 +162,7 @@ export const handleRunCommand = async (
129
162
  console.error(` ${error.code}: ${error.message}`);
130
163
  }
131
164
  }
132
- return ExitCodes.ValidationError;
165
+ return ExitCodes.VALIDATION_ERROR;
133
166
  }
134
167
 
135
168
  // Step 5: Execution phase
@@ -161,36 +194,66 @@ export const handleRunCommand = async (
161
194
 
162
195
  return handleResults(executionResult, options, shouldBeQuiet);
163
196
  } catch (error) {
164
- // Re-throw FileDiscoveryError so yargs fail handler can show help
165
- if ((error as ModestBenchError).code === ErrorCodes.FILE_DISCOVERY_FAILED) {
197
+ // Check if error has a code property before accessing it
198
+ const errorCode = hasErrorCode(error) ? error.code : undefined;
199
+
200
+ // Handle budget exceeded error
201
+ if (errorCode === ErrorCodes.BUDGET_EXCEEDED) {
202
+ if (!shouldBeQuiet) {
203
+ const budgetError = error as BudgetExceededError;
204
+ console.error(`\n❌ ${budgetError.message}`);
205
+ if (
206
+ budgetError.budgetSummary &&
207
+ budgetError.budgetSummary.results.length > 0
208
+ ) {
209
+ console.error('\nFailed budgets:');
210
+ for (const result of budgetError.budgetSummary.results) {
211
+ if (!result.passed) {
212
+ console.error(` • ${result.taskId}`);
213
+ for (const violation of result.violations) {
214
+ console.error(` ${violation.message}`);
215
+ }
216
+ }
217
+ }
218
+ }
219
+ }
220
+ return ExitCodes.BENCHMARK_FAILURES;
221
+ }
222
+
223
+ // Re-throw CLI errors so yargs fail handler can show help
224
+ if (errorCode === ErrorCodes.FILE_DISCOVERY_FAILED) {
225
+ throw error;
226
+ }
227
+ if (errorCode === ErrorCodes.CLI_INVALID_ARGUMENT) {
166
228
  throw error;
167
229
  }
168
230
 
169
231
  if (!shouldBeQuiet) {
170
- console.error(
171
- `Error: ${error instanceof Error ? error.message : String(error)}`,
172
- );
232
+ console.error(`Error: ${isError(error) ? error.message : String(error)}`);
173
233
  }
174
234
 
175
- // Return appropriate exit code based on error type
176
- if (error instanceof Error) {
177
- if (
178
- error.message.includes('Configuration error') ||
179
- error.message.includes('Config file not found') ||
180
- error.message.includes('Failed to load config')
181
- ) {
182
- return ExitCodes.ConfigurationError;
183
- }
184
- if (
185
- error.message.includes('No files found') ||
186
- error.message.includes('No benchmark files found') ||
187
- error.message.includes('File discovery')
188
- ) {
189
- return ExitCodes.FileDiscoveryError;
235
+ // Return appropriate exit code based on error code
236
+ if (
237
+ errorCode === ErrorCodes.CONFIG_LOAD_FAILED ||
238
+ errorCode === ErrorCodes.CONFIG_NOT_FOUND ||
239
+ errorCode === ErrorCodes.CONFIG_VALIDATION_FAILED ||
240
+ errorCode === ErrorCodes.CONFIG_UNSUPPORTED_FORMAT
241
+ ) {
242
+ return ExitCodes.CONFIG_ERROR;
243
+ }
244
+
245
+ if (errorCode === ErrorCodes.FILE_DISCOVERY_FAILED) {
246
+ return ExitCodes.DISCOVERY_ERROR;
247
+ }
248
+
249
+ // Fallback: check error message for cases where proper error types aren't thrown yet
250
+ if (isError(error)) {
251
+ if (error.message.includes('No benchmark files found')) {
252
+ return ExitCodes.DISCOVERY_ERROR;
190
253
  }
191
254
  }
192
255
 
193
- return ExitCodes.GeneralError;
256
+ return ExitCodes.BENCHMARK_FAILURES;
194
257
  }
195
258
  };
196
259
 
@@ -212,11 +275,11 @@ const handleResults = (
212
275
  if (executionResult && executionResult.summary) {
213
276
  // Return error if there are failed tasks OR file-level errors
214
277
  return executionResult.summary.failedTasks > 0 || hasFileErrors
215
- ? ExitCodes.GeneralError
216
- : ExitCodes.Success;
278
+ ? ExitCodes.BENCHMARK_FAILURES
279
+ : ExitCodes.SUCCESS;
217
280
  }
218
281
 
219
- return ExitCodes.Success;
282
+ return ExitCodes.SUCCESS;
220
283
  };
221
284
 
222
285
  /**
@@ -228,17 +291,20 @@ const loadConfiguration = async (context: CliContext, options: RunOptions) => {
228
291
  const cliArgs: Record<string, unknown> = {};
229
292
 
230
293
  // Map CLI arguments to config properties
231
- // Pass pattern as-is, even if empty (loader will provide defaults)
232
- if (options.pattern !== undefined) {
233
- // If pattern is provided, use it; if empty array, pass it (for defaults)
294
+ // Only pass pattern if explicitly provided (non-empty)
295
+ // Empty array means no CLI pattern, so config file or defaults should be used
296
+ if (options.pattern !== undefined && options.pattern.length > 0) {
234
297
  cliArgs.pattern =
235
298
  options.pattern.length === 1 ? options.pattern[0] : options.pattern;
236
299
  }
237
- if (options.reporters) {
300
+ if (options.reporters && options.reporters.length > 0) {
238
301
  cliArgs.reporters = options.reporters;
239
302
  }
240
303
  if (options.outputDir) {
241
- cliArgs.outputDir = resolve(options.cwd, options.outputDir);
304
+ cliArgs.outputDir = resolve(
305
+ options.cwd ?? process.cwd(),
306
+ options.outputDir,
307
+ );
242
308
  }
243
309
  if (options.iterations) {
244
310
  cliArgs.iterations = options.iterations;
@@ -252,7 +318,7 @@ const loadConfiguration = async (context: CliContext, options: RunOptions) => {
252
318
  if (options.bail !== undefined) {
253
319
  cliArgs.bail = options.bail;
254
320
  }
255
- if (options.exclude) {
321
+ if (options.exclude && options.exclude.length > 0) {
256
322
  cliArgs.exclude = options.exclude;
257
323
  }
258
324
  if (options.timeout) {
@@ -264,24 +330,30 @@ const loadConfiguration = async (context: CliContext, options: RunOptions) => {
264
330
  if (options.verbose !== undefined) {
265
331
  cliArgs.verbose = options.verbose;
266
332
  }
267
- if (options.tags) {
333
+ if (options.tags && options.tags.length > 0) {
268
334
  cliArgs.tags = options.tags;
269
335
  }
270
- if (options.excludeTags) {
336
+ if (options.excludeTags && options.excludeTags.length > 0) {
271
337
  cliArgs.excludeTags = options.excludeTags;
272
338
  }
273
339
 
274
340
  // Load configuration with CLI argument precedence
275
- const config = await context.configManager.load(options.config, cliArgs);
341
+ // Pass command defaults as the base layer
342
+ const config = await context.configManager.load(
343
+ options.config,
344
+ cliArgs,
345
+ RUN_COMMAND_DEFAULTS,
346
+ );
276
347
 
277
348
  return config;
278
349
  } catch (error) {
279
350
  // Re-throw our custom errors
280
- if ((error as ModestBenchError).code === ErrorCodes.CONFIG_LOAD_FAILED) {
351
+ const errorCode = hasErrorCode(error) ? error.code : undefined;
352
+ if (errorCode === ErrorCodes.CONFIG_LOAD_FAILED) {
281
353
  throw error;
282
354
  }
283
355
  throw new InvalidArgumentError(
284
- `Configuration error: ${error instanceof Error ? error.message : String(error)}`,
356
+ `Configuration error: ${isError(error) ? error.message : String(error)}`,
285
357
  { cause: error },
286
358
  );
287
359
  }
@@ -290,25 +362,20 @@ const loadConfiguration = async (context: CliContext, options: RunOptions) => {
290
362
  /**
291
363
  * Setup and configure reporters based on configuration
292
364
  */
293
- const setupReporters = async (
365
+ const setupReporters = (
294
366
  context: CliContext,
295
367
  config: { outputDir?: string; reporters?: string[] },
296
- shouldBeQuiet: boolean,
297
368
  isVerbose: boolean,
298
369
  showCliMessages: boolean,
299
370
  explicitQuiet: boolean,
300
371
  explicitOutputDir?: string,
372
+ explicitOutputFile?: string,
301
373
  progressOption?: boolean,
302
374
  ) => {
303
375
  try {
304
376
  const reporters = [];
305
- const requestedReporters = config.reporters || ['human'];
306
-
307
- // Dynamically import reporters for proper configuration
308
- const { HumanReporter } = await import('../../reporters/human.js');
309
- const { JsonReporter } = await import('../../reporters/json.js');
310
- const { CsvReporter } = await import('../../reporters/csv.js');
311
- const { SimpleReporter } = await import('../../reporters/simple.js');
377
+ // Dedupe requested reporters
378
+ const requestedReporters = [...new Set(config.reporters || ['human'])];
312
379
 
313
380
  // Only use file output if --output was explicitly provided
314
381
  // Use the explicit output dir if provided, otherwise check config
@@ -316,46 +383,76 @@ const setupReporters = async (
316
383
  ? resolve(explicitOutputDir)
317
384
  : undefined;
318
385
 
386
+ // Built-in reporter names for error messages
387
+ const builtInReporters = ['human', 'json', 'csv', 'simple'];
388
+
319
389
  for (const reporterName of requestedReporters) {
320
390
  let reporter;
321
391
 
322
392
  // Create reporter instances with output path configuration
323
- if (reporterName === 'human') {
324
- reporter = new HumanReporter({
325
- color: true,
326
- progress: progressOption ?? true,
327
- quiet: explicitQuiet, // Only applies explicit --quiet flag; JSON reporter forcing quiet mode does not affect HumanReporter progress output
328
- verbose: isVerbose,
329
- });
330
- } else if (reporterName === 'json') {
331
- reporter = new JsonReporter({
332
- ...(outputDir ? { outputPath: `${outputDir}/results.json` } : {}),
333
- prettyPrint: true,
334
- quiet: shouldBeQuiet, // JSON uses shouldBeQuiet to avoid polluting stdout
335
- verbose: isVerbose,
336
- });
337
- } else if (reporterName === 'csv') {
338
- reporter = new CsvReporter({
339
- includeHeaders: true,
340
- includeMetadata: true,
341
- ...(outputDir ? { outputPath: `${outputDir}/results.csv` } : {}),
342
- quiet: explicitQuiet, // Only applies explicit --quiet flag; CSV output can coexist with progress messages on different streams
343
- verbose: isVerbose,
344
- });
345
- } else if (reporterName === 'simple') {
346
- reporter = new SimpleReporter({
347
- quiet: explicitQuiet,
348
- verbose: isVerbose,
349
- });
350
- } else {
351
- // Fall back to registry for custom reporters
352
- reporter = context.reporterRegistry.get(reporterName);
353
- if (!reporter) {
354
- const availableReporters = ['human', 'json', 'csv', 'simple'];
355
- throw new UnknownReporterError(
356
- `Unknown reporter: ${reporterName}. Available: ${availableReporters.join(', ')}`,
393
+ switch (reporterName) {
394
+ case 'csv': {
395
+ const outputPath = resolveOutputPath(
396
+ outputDir,
397
+ explicitOutputFile,
398
+ 'results.csv',
357
399
  );
400
+ reporter = new CsvReporter({
401
+ includeHeaders: true,
402
+ includeMetadata: true,
403
+ ...(outputPath ? { outputPath } : {}),
404
+ quiet: explicitQuiet, // Only applies explicit --quiet flag; CSV output can coexist with progress messages on different streams
405
+ verbose: isVerbose,
406
+ });
407
+ break;
358
408
  }
409
+
410
+ case 'human':
411
+ reporter = new HumanReporter({
412
+ color: true,
413
+ progress: progressOption ?? true,
414
+ quiet: explicitQuiet, // Only applies explicit --quiet flag; JSON reporter forcing quiet mode does not affect HumanReporter progress output
415
+ verbose: isVerbose,
416
+ });
417
+ break;
418
+
419
+ case 'json': {
420
+ const outputPath = resolveOutputPath(
421
+ outputDir,
422
+ explicitOutputFile,
423
+ 'results.json',
424
+ );
425
+ reporter = new JsonReporter({
426
+ ...(outputPath ? { outputPath } : {}),
427
+ prettyPrint: true,
428
+ });
429
+ break;
430
+ }
431
+
432
+ case 'simple':
433
+ reporter = new SimpleReporter({
434
+ quiet: explicitQuiet,
435
+ verbose: isVerbose,
436
+ });
437
+ break;
438
+
439
+ default:
440
+ // Fall back to registry for custom reporters
441
+ reporter = context.reporterRegistry.get(reporterName);
442
+ if (!reporter) {
443
+ // Combine built-in reporters with registered custom reporters
444
+ const registeredReporters = Object.keys(
445
+ context.reporterRegistry.getAll(),
446
+ );
447
+ const availableReporters = [
448
+ ...builtInReporters,
449
+ ...registeredReporters,
450
+ ];
451
+ throw new UnknownReporterError(
452
+ `Unknown reporter: ${reporterName}. Available: ${availableReporters.join(', ')}`,
453
+ );
454
+ }
455
+ break;
359
456
  }
360
457
 
361
458
  reporters.push(reporter);
@@ -368,11 +465,12 @@ const setupReporters = async (
368
465
  return reporters;
369
466
  } catch (error) {
370
467
  // Re-throw our custom errors
371
- if ((error as ModestBenchError).code === ErrorCodes.REPORTER_UNKNOWN) {
468
+ const errorCode = hasErrorCode(error) ? error.code : undefined;
469
+ if (errorCode === ErrorCodes.REPORTER_UNKNOWN) {
372
470
  throw error;
373
471
  }
374
472
  throw new InvalidArgumentError(
375
- `Reporter setup error: ${error instanceof Error ? error.message : String(error)}`,
473
+ `Reporter setup error: ${isError(error) ? error.message : String(error)}`,
376
474
  { cause: error },
377
475
  );
378
476
  }