modestbench 0.1.0 → 0.2.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 (267) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +39 -31
  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/history.cjs +108 -266
  10. package/dist/cli/commands/history.cjs.map +1 -1
  11. package/dist/cli/commands/history.d.cts +75 -12
  12. package/dist/cli/commands/history.d.cts.map +1 -1
  13. package/dist/cli/commands/history.d.ts +75 -12
  14. package/dist/cli/commands/history.d.ts.map +1 -1
  15. package/dist/cli/commands/history.js +105 -268
  16. package/dist/cli/commands/history.js.map +1 -1
  17. package/dist/cli/commands/run.cjs +18 -5
  18. package/dist/cli/commands/run.cjs.map +1 -1
  19. package/dist/cli/commands/run.d.cts +1 -0
  20. package/dist/cli/commands/run.d.cts.map +1 -1
  21. package/dist/cli/commands/run.d.ts +1 -0
  22. package/dist/cli/commands/run.d.ts.map +1 -1
  23. package/dist/cli/commands/run.js +18 -5
  24. package/dist/cli/commands/run.js.map +1 -1
  25. package/dist/cli/index.cjs +307 -91
  26. package/dist/cli/index.cjs.map +1 -1
  27. package/dist/cli/index.d.cts.map +1 -1
  28. package/dist/cli/index.d.ts.map +1 -1
  29. package/dist/cli/index.js +308 -92
  30. package/dist/cli/index.js.map +1 -1
  31. package/dist/core/engine.cjs +8 -1
  32. package/dist/core/engine.cjs.map +1 -1
  33. package/dist/core/engine.d.cts +3 -0
  34. package/dist/core/engine.d.cts.map +1 -1
  35. package/dist/core/engine.d.ts +3 -0
  36. package/dist/core/engine.d.ts.map +1 -1
  37. package/dist/core/engine.js +8 -1
  38. package/dist/core/engine.js.map +1 -1
  39. package/dist/core/output-path-resolver.cjs +34 -0
  40. package/dist/core/output-path-resolver.cjs.map +1 -0
  41. package/dist/core/output-path-resolver.d.cts +10 -0
  42. package/dist/core/output-path-resolver.d.cts.map +1 -0
  43. package/dist/core/output-path-resolver.d.ts +10 -0
  44. package/dist/core/output-path-resolver.d.ts.map +1 -0
  45. package/dist/core/output-path-resolver.js +30 -0
  46. package/dist/core/output-path-resolver.js.map +1 -0
  47. package/dist/formatters/history/base.cjs +9 -0
  48. package/dist/formatters/history/base.cjs.map +1 -0
  49. package/dist/formatters/history/base.d.cts +26 -0
  50. package/dist/formatters/history/base.d.cts.map +1 -0
  51. package/dist/formatters/history/base.d.ts +26 -0
  52. package/dist/formatters/history/base.d.ts.map +1 -0
  53. package/dist/formatters/history/base.js +8 -0
  54. package/dist/formatters/history/base.js.map +1 -0
  55. package/dist/formatters/history/compare.cjs +127 -0
  56. package/dist/formatters/history/compare.cjs.map +1 -0
  57. package/dist/formatters/history/compare.d.cts +21 -0
  58. package/dist/formatters/history/compare.d.cts.map +1 -0
  59. package/dist/formatters/history/compare.d.ts +21 -0
  60. package/dist/formatters/history/compare.d.ts.map +1 -0
  61. package/dist/formatters/history/compare.js +123 -0
  62. package/dist/formatters/history/compare.js.map +1 -0
  63. package/dist/formatters/history/list.cjs +74 -0
  64. package/dist/formatters/history/list.cjs.map +1 -0
  65. package/dist/formatters/history/list.d.cts +25 -0
  66. package/dist/formatters/history/list.d.cts.map +1 -0
  67. package/dist/formatters/history/list.d.ts +25 -0
  68. package/dist/formatters/history/list.d.ts.map +1 -0
  69. package/dist/formatters/history/list.js +70 -0
  70. package/dist/formatters/history/list.js.map +1 -0
  71. package/dist/formatters/history/show.cjs +98 -0
  72. package/dist/formatters/history/show.cjs.map +1 -0
  73. package/dist/formatters/history/show.d.cts +21 -0
  74. package/dist/formatters/history/show.d.cts.map +1 -0
  75. package/dist/formatters/history/show.d.ts +21 -0
  76. package/dist/formatters/history/show.d.ts.map +1 -0
  77. package/dist/formatters/history/show.js +94 -0
  78. package/dist/formatters/history/show.js.map +1 -0
  79. package/dist/formatters/history/trends.cjs +194 -0
  80. package/dist/formatters/history/trends.cjs.map +1 -0
  81. package/dist/formatters/history/trends.d.cts +22 -0
  82. package/dist/formatters/history/trends.d.cts.map +1 -0
  83. package/dist/formatters/history/trends.d.ts +22 -0
  84. package/dist/formatters/history/trends.d.ts.map +1 -0
  85. package/dist/formatters/history/trends.js +190 -0
  86. package/dist/formatters/history/trends.js.map +1 -0
  87. package/dist/formatters/history/visualization.cjs +79 -0
  88. package/dist/formatters/history/visualization.cjs.map +1 -0
  89. package/dist/formatters/history/visualization.d.cts +24 -0
  90. package/dist/formatters/history/visualization.d.cts.map +1 -0
  91. package/dist/formatters/history/visualization.d.ts +24 -0
  92. package/dist/formatters/history/visualization.d.ts.map +1 -0
  93. package/dist/formatters/history/visualization.js +74 -0
  94. package/dist/formatters/history/visualization.js.map +1 -0
  95. package/dist/index.cjs +15 -17
  96. package/dist/index.cjs.map +1 -1
  97. package/dist/index.d.cts +5 -5
  98. package/dist/index.d.cts.map +1 -1
  99. package/dist/index.d.ts +5 -5
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +7 -9
  102. package/dist/index.js.map +1 -1
  103. package/dist/reporters/csv.cjs +2 -2
  104. package/dist/reporters/csv.cjs.map +1 -1
  105. package/dist/reporters/csv.d.cts +1 -1
  106. package/dist/reporters/csv.d.cts.map +1 -1
  107. package/dist/reporters/csv.d.ts +1 -1
  108. package/dist/reporters/csv.d.ts.map +1 -1
  109. package/dist/reporters/csv.js +1 -1
  110. package/dist/reporters/csv.js.map +1 -1
  111. package/dist/reporters/human.cjs +24 -62
  112. package/dist/reporters/human.cjs.map +1 -1
  113. package/dist/reporters/human.d.cts +1 -1
  114. package/dist/reporters/human.d.cts.map +1 -1
  115. package/dist/reporters/human.d.ts +1 -1
  116. package/dist/reporters/human.d.ts.map +1 -1
  117. package/dist/reporters/human.js +2 -40
  118. package/dist/reporters/human.js.map +1 -1
  119. package/dist/reporters/json.cjs +2 -2
  120. package/dist/reporters/json.cjs.map +1 -1
  121. package/dist/reporters/json.d.cts +1 -1
  122. package/dist/reporters/json.d.cts.map +1 -1
  123. package/dist/reporters/json.d.ts +1 -1
  124. package/dist/reporters/json.d.ts.map +1 -1
  125. package/dist/reporters/json.js +1 -1
  126. package/dist/reporters/json.js.map +1 -1
  127. package/dist/reporters/simple.cjs +2 -2
  128. package/dist/reporters/simple.cjs.map +1 -1
  129. package/dist/reporters/simple.d.cts +1 -1
  130. package/dist/reporters/simple.d.cts.map +1 -1
  131. package/dist/reporters/simple.d.ts +1 -1
  132. package/dist/reporters/simple.d.ts.map +1 -1
  133. package/dist/reporters/simple.js +1 -1
  134. package/dist/reporters/simple.js.map +1 -1
  135. package/dist/{config/manager.cjs → services/config-manager.cjs} +2 -2
  136. package/dist/services/config-manager.cjs.map +1 -0
  137. package/dist/{config/manager.d.cts → services/config-manager.d.cts} +1 -1
  138. package/dist/services/config-manager.d.cts.map +1 -0
  139. package/dist/{config/manager.d.ts → services/config-manager.d.ts} +1 -1
  140. package/dist/services/config-manager.d.ts.map +1 -0
  141. package/dist/{config/manager.js → services/config-manager.js} +2 -2
  142. package/dist/services/config-manager.js.map +1 -0
  143. package/dist/{core/loader.cjs → services/file-loader.cjs} +2 -2
  144. package/dist/services/file-loader.cjs.map +1 -0
  145. package/dist/{core/loader.d.cts → services/file-loader.d.cts} +1 -1
  146. package/dist/services/file-loader.d.cts.map +1 -0
  147. package/dist/{core/loader.d.ts → services/file-loader.d.ts} +1 -1
  148. package/dist/services/file-loader.d.ts.map +1 -0
  149. package/dist/{core/loader.js → services/file-loader.js} +2 -2
  150. package/dist/services/file-loader.js.map +1 -0
  151. package/dist/services/history/comparison.cjs +124 -0
  152. package/dist/services/history/comparison.cjs.map +1 -0
  153. package/dist/services/history/comparison.d.cts +18 -0
  154. package/dist/services/history/comparison.d.cts.map +1 -0
  155. package/dist/services/history/comparison.d.ts +18 -0
  156. package/dist/services/history/comparison.d.ts.map +1 -0
  157. package/dist/services/history/comparison.js +120 -0
  158. package/dist/services/history/comparison.js.map +1 -0
  159. package/dist/services/history/models.cjs +9 -0
  160. package/dist/services/history/models.cjs.map +1 -0
  161. package/dist/services/history/models.d.cts +139 -0
  162. package/dist/services/history/models.d.cts.map +1 -0
  163. package/dist/services/history/models.d.ts +139 -0
  164. package/dist/services/history/models.d.ts.map +1 -0
  165. package/dist/services/history/models.js +8 -0
  166. package/dist/services/history/models.js.map +1 -0
  167. package/dist/services/history/query.cjs +97 -0
  168. package/dist/services/history/query.cjs.map +1 -0
  169. package/dist/services/history/query.d.cts +38 -0
  170. package/dist/services/history/query.d.cts.map +1 -0
  171. package/dist/services/history/query.d.ts +38 -0
  172. package/dist/services/history/query.d.ts.map +1 -0
  173. package/dist/services/history/query.js +92 -0
  174. package/dist/services/history/query.js.map +1 -0
  175. package/dist/services/history/trend-analysis.cjs +187 -0
  176. package/dist/services/history/trend-analysis.cjs.map +1 -0
  177. package/dist/services/history/trend-analysis.d.cts +34 -0
  178. package/dist/services/history/trend-analysis.d.cts.map +1 -0
  179. package/dist/services/history/trend-analysis.d.ts +34 -0
  180. package/dist/services/history/trend-analysis.d.ts.map +1 -0
  181. package/dist/services/history/trend-analysis.js +179 -0
  182. package/dist/services/history/trend-analysis.js.map +1 -0
  183. package/dist/{storage/history.cjs → services/history-storage.cjs} +1 -1
  184. package/dist/services/history-storage.cjs.map +1 -0
  185. package/dist/{storage/history.d.cts → services/history-storage.d.cts} +1 -1
  186. package/dist/services/history-storage.d.cts.map +1 -0
  187. package/dist/{storage/history.d.ts → services/history-storage.d.ts} +1 -1
  188. package/dist/services/history-storage.d.ts.map +1 -0
  189. package/dist/{storage/history.js → services/history-storage.js} +1 -1
  190. package/dist/services/history-storage.js.map +1 -0
  191. package/dist/{progress/manager.cjs → services/progress-manager.cjs} +1 -1
  192. package/dist/services/progress-manager.cjs.map +1 -0
  193. package/dist/{progress/manager.d.cts → services/progress-manager.d.cts} +1 -1
  194. package/dist/services/progress-manager.d.cts.map +1 -0
  195. package/dist/{progress/manager.d.ts → services/progress-manager.d.ts} +1 -1
  196. package/dist/services/progress-manager.d.ts.map +1 -0
  197. package/dist/{progress/manager.js → services/progress-manager.js} +1 -1
  198. package/dist/services/progress-manager.js.map +1 -0
  199. package/dist/{reporters/registry.cjs → services/reporter-registry.cjs} +1 -1
  200. package/dist/services/reporter-registry.cjs.map +1 -0
  201. package/dist/{reporters/registry.d.cts → services/reporter-registry.d.cts} +1 -1
  202. package/dist/services/reporter-registry.d.cts.map +1 -0
  203. package/dist/{reporters/registry.d.ts → services/reporter-registry.d.ts} +1 -1
  204. package/dist/services/reporter-registry.d.ts.map +1 -0
  205. package/dist/{reporters/registry.js → services/reporter-registry.js} +1 -1
  206. package/dist/services/reporter-registry.js.map +1 -0
  207. package/dist/types/cli.d.cts +3 -0
  208. package/dist/types/cli.d.cts.map +1 -1
  209. package/dist/types/cli.d.ts +3 -0
  210. package/dist/types/cli.d.ts.map +1 -1
  211. package/dist/utils/ansi.cjs +61 -0
  212. package/dist/utils/ansi.cjs.map +1 -0
  213. package/dist/utils/ansi.d.cts +53 -0
  214. package/dist/utils/ansi.d.cts.map +1 -0
  215. package/dist/utils/ansi.d.ts +53 -0
  216. package/dist/utils/ansi.d.ts.map +1 -0
  217. package/dist/utils/ansi.js +57 -0
  218. package/dist/utils/ansi.js.map +1 -0
  219. package/package.json +5 -4
  220. package/src/bootstrap.ts +5 -5
  221. package/src/cli/commands/history.ts +194 -342
  222. package/src/cli/commands/run.ts +32 -3
  223. package/src/cli/index.ts +361 -106
  224. package/src/core/engine.ts +9 -1
  225. package/src/core/output-path-resolver.ts +38 -0
  226. package/src/formatters/history/base.ts +28 -0
  227. package/src/formatters/history/compare.ts +186 -0
  228. package/src/formatters/history/list.ts +101 -0
  229. package/src/formatters/history/show.ts +155 -0
  230. package/src/formatters/history/trends.ts +281 -0
  231. package/src/formatters/history/visualization.ts +93 -0
  232. package/src/index.ts +7 -11
  233. package/src/reporters/csv.ts +1 -1
  234. package/src/reporters/human.ts +2 -42
  235. package/src/reporters/json.ts +1 -1
  236. package/src/reporters/simple.ts +1 -1
  237. package/src/{config/manager.ts → services/config-manager.ts} +1 -1
  238. package/src/{core/loader.ts → services/file-loader.ts} +1 -1
  239. package/src/services/history/comparison.ts +130 -0
  240. package/src/services/history/models.ts +148 -0
  241. package/src/services/history/query.ts +116 -0
  242. package/src/services/history/trend-analysis.ts +238 -0
  243. package/src/types/cli.ts +3 -0
  244. package/src/utils/ansi.ts +59 -0
  245. package/dist/config/manager.cjs.map +0 -1
  246. package/dist/config/manager.d.cts.map +0 -1
  247. package/dist/config/manager.d.ts.map +0 -1
  248. package/dist/config/manager.js.map +0 -1
  249. package/dist/core/loader.cjs.map +0 -1
  250. package/dist/core/loader.d.cts.map +0 -1
  251. package/dist/core/loader.d.ts.map +0 -1
  252. package/dist/core/loader.js.map +0 -1
  253. package/dist/progress/manager.cjs.map +0 -1
  254. package/dist/progress/manager.d.cts.map +0 -1
  255. package/dist/progress/manager.d.ts.map +0 -1
  256. package/dist/progress/manager.js.map +0 -1
  257. package/dist/reporters/registry.cjs.map +0 -1
  258. package/dist/reporters/registry.d.cts.map +0 -1
  259. package/dist/reporters/registry.d.ts.map +0 -1
  260. package/dist/reporters/registry.js.map +0 -1
  261. package/dist/storage/history.cjs.map +0 -1
  262. package/dist/storage/history.d.cts.map +0 -1
  263. package/dist/storage/history.d.ts.map +0 -1
  264. package/dist/storage/history.js.map +0 -1
  265. /package/src/{storage/history.ts → services/history-storage.ts} +0 -0
  266. /package/src/{progress/manager.ts → services/progress-manager.ts} +0 -0
  267. /package/src/{reporters/registry.ts → services/reporter-registry.ts} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.0](https://github.com/boneskull/modestbench/compare/modestbench-v0.1.0...modestbench-v0.2.0) (2025-10-26)
4
+
5
+
6
+ ### Features
7
+
8
+ * add --output-file CLI option ([#66](https://github.com/boneskull/modestbench/issues/66)) ([09bb5ae](https://github.com/boneskull/modestbench/commit/09bb5ae7468c9d5eb9d1e9641c58350a5b3856dd))
9
+ * **history:** implement trend analysis and comparison ([#64](https://github.com/boneskull/modestbench/issues/64)) ([acf7dda](https://github.com/boneskull/modestbench/commit/acf7ddaa91f7ae242c2a2df86fd610ce88f8ac91))
10
+ * **history:** implement trends and comparison ([acf7dda](https://github.com/boneskull/modestbench/commit/acf7ddaa91f7ae242c2a2df86fd610ce88f8ac91))
11
+ * implement date parsing, compare, and trend analysis core ([acf7dda](https://github.com/boneskull/modestbench/commit/acf7ddaa91f7ae242c2a2df86fd610ce88f8ac91))
12
+ * implement full trends command with visualizations ([acf7dda](https://github.com/boneskull/modestbench/commit/acf7ddaa91f7ae242c2a2df86fd610ce88f8ac91))
13
+
3
14
  ## [0.1.0](https://github.com/boneskull/modestbench/compare/modestbench-v0.0.3...modestbench-v0.1.0) (2025-10-24)
4
15
 
5
16
 
package/README.md CHANGED
@@ -130,37 +130,7 @@ modestbench --iterations 5000 --reporters human,json
130
130
 
131
131
  ### View Results
132
132
 
133
- ```text
134
- 🚀 ModestBench
135
-
136
- Environment:
137
- Node.js: v24.10.0
138
- Platform: darwin arm64
139
- CPU: Apple M4 Max (16 cores)
140
- Memory: 48.0 GB
141
-
142
- Found 1 benchmark file(s)
143
-
144
- ▶ benchmarks/example.bench.js
145
-
146
- ▶ Array Operations
147
- ✓ Array.push()
148
- 810.05μs ±2.45% (1.23M ops/sec)
149
- ✓ Array spread
150
- 81.01ms ±4.12% (12.34K ops/sec)
151
- ✓ 2 passed
152
-
153
- ✓ All 2 tasks passed
154
-
155
- 📊 Results
156
-
157
- ✓ All tests passed: 2
158
- 📁 Files: 1
159
- 📊 Suites: 1
160
- ⏱️ Duration: 1.82s
161
-
162
- 🎉 All benchmarks completed successfully!
163
- ```
133
+ ![Example output showing colorful terminal display with benchmark results](./public/human-reporter.png)
164
134
 
165
135
  ## Getting Started
166
136
 
@@ -273,6 +243,44 @@ modestbench --tags fast --exclude-tags experimental
273
243
 
274
244
  See [Tagging and Filtering](#tagging-and-filtering) for detailed examples.
275
245
 
246
+ #### Output Options
247
+
248
+ Control where and how benchmark results are saved:
249
+
250
+ ```bash
251
+ # Write to a directory (creates results.json, results.csv, etc.)
252
+ modestbench --reporters json,csv --output ./results
253
+
254
+ # Custom filename for single reporter
255
+ modestbench --reporters json --output-file my-benchmarks.json
256
+
257
+ # Custom filename in specific directory
258
+ modestbench --reporters json --output ./results --output-file benchmarks-2024.json
259
+
260
+ # Custom filename with absolute path
261
+ modestbench --reporters json --output-file /tmp/my-benchmarks.json
262
+
263
+ # With subdirectories
264
+ modestbench --reporters csv --output ./results --output-file reports/performance.csv
265
+
266
+ # Short flag alias
267
+ modestbench --reporters json --of custom.json
268
+ ```
269
+
270
+ **Key Options:**
271
+
272
+ - `--output <dir>`, `-o <dir>` - Directory to write output files (default: stdout)
273
+ - `--output-file <filename>`, `--of <filename>` - Custom filename for output
274
+ - Works with absolute or relative paths
275
+ - Requires exactly one reporter (e.g., `--reporters json`)
276
+ - When used with `--output`, the filename is relative to that directory
277
+ - When used alone, the path is relative to current working directory
278
+
279
+ **Limitations:**
280
+
281
+ - `--output-file` only works with a single reporter
282
+ - For multiple reporters, use `--output <dir>` (defaults to `results.json`, `results.csv`, etc.)
283
+
276
284
  ### History Management
277
285
 
278
286
  **modestbench** automatically tracks benchmark results over time in a local `.modestbench/` directory. This history enables you to:
@@ -7,12 +7,12 @@
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.bootstrap = void 0;
10
- const manager_js_1 = require("./config/manager.cjs");
11
10
  const index_js_1 = require("./core/engines/index.cjs");
12
- const loader_js_1 = require("./core/loader.cjs");
13
- const manager_js_2 = require("./progress/manager.cjs");
14
- const registry_js_1 = require("./reporters/registry.cjs");
15
- const history_js_1 = require("./storage/history.cjs");
11
+ const config_manager_js_1 = require("./services/config-manager.cjs");
12
+ const file_loader_js_1 = require("./services/file-loader.cjs");
13
+ const history_storage_js_1 = require("./services/history-storage.cjs");
14
+ const progress_manager_js_1 = require("./services/progress-manager.cjs");
15
+ const reporter_registry_js_1 = require("./services/reporter-registry.cjs");
16
16
  /**
17
17
  * Initializes the ModestBench engine with default dependencies.
18
18
  *
@@ -23,11 +23,11 @@ const history_js_1 = require("./storage/history.cjs");
23
23
  */
24
24
  const bootstrap = () => {
25
25
  const engine = new index_js_1.TinybenchEngine({
26
- configManager: new manager_js_1.ModestBenchConfigurationManager(),
27
- fileLoader: new loader_js_1.BenchmarkFileLoader(),
28
- historyStorage: new history_js_1.FileHistoryStorage(),
29
- progressManager: new manager_js_2.ModestBenchProgressManager(),
30
- reporterRegistry: new registry_js_1.ModestBenchReporterRegistry(),
26
+ configManager: new config_manager_js_1.ModestBenchConfigurationManager(),
27
+ fileLoader: new file_loader_js_1.BenchmarkFileLoader(),
28
+ historyStorage: new history_storage_js_1.FileHistoryStorage(),
29
+ progressManager: new progress_manager_js_1.ModestBenchProgressManager(),
30
+ reporterRegistry: new reporter_registry_js_1.ModestBenchReporterRegistry(),
31
31
  });
32
32
  return engine;
33
33
  };
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,qDAAsE;AAEtE,uDAA0D;AAC1D,iDAAuD;AACvD,uDAAmE;AACnE,0DAAsE;AACtE,sDAA0D;AAE1D;;;;;;;GAOG;AACI,MAAM,SAAS,GAAG,GAAsB,EAAE;IAC/C,MAAM,MAAM,GAAG,IAAI,0BAAe,CAAC;QACjC,aAAa,EAAE,IAAI,4CAA+B,EAAE;QACpD,UAAU,EAAE,IAAI,+BAAmB,EAAE;QACrC,cAAc,EAAE,IAAI,+BAAkB,EAAE;QACxC,eAAe,EAAE,IAAI,uCAA0B,EAAE;QACjD,gBAAgB,EAAE,IAAI,yCAA2B,EAAE;KACpD,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AATW,QAAA,SAAS,aASpB"}
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAGH,uDAA0D;AAC1D,qEAA+E;AAC/E,+DAAgE;AAChE,uEAAmE;AACnE,yEAA4E;AAC5E,2EAA8E;AAE9E;;;;;;;GAOG;AACI,MAAM,SAAS,GAAG,GAAsB,EAAE;IAC/C,MAAM,MAAM,GAAG,IAAI,0BAAe,CAAC;QACjC,aAAa,EAAE,IAAI,mDAA+B,EAAE;QACpD,UAAU,EAAE,IAAI,oCAAmB,EAAE;QACrC,cAAc,EAAE,IAAI,uCAAkB,EAAE;QACxC,eAAe,EAAE,IAAI,gDAA0B,EAAE;QACjD,gBAAgB,EAAE,IAAI,kDAA2B,EAAE;KACpD,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AATW,QAAA,SAAS,aASpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,KAAK,iBAAiB,EAAE,0BAAyB;AAO1D;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,QAAO,iBAS5B,CAAC"}
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,iBAAiB,EAAE,0BAAyB;AAQ1D;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,QAAO,iBAS5B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,KAAK,iBAAiB,EAAE,yBAAyB;AAO1D;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,QAAO,iBAS5B,CAAC"}
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,iBAAiB,EAAE,yBAAyB;AAQ1D;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,QAAO,iBAS5B,CAAC"}
package/dist/bootstrap.js CHANGED
@@ -4,12 +4,12 @@
4
4
  *
5
5
  * @packageDocumentation
6
6
  */
7
- import { ModestBenchConfigurationManager } from "./config/manager.js";
8
7
  import { TinybenchEngine } from "./core/engines/index.js";
9
- import { BenchmarkFileLoader } from "./core/loader.js";
10
- import { ModestBenchProgressManager } from "./progress/manager.js";
11
- import { ModestBenchReporterRegistry } from "./reporters/registry.js";
12
- import { FileHistoryStorage } from "./storage/history.js";
8
+ import { ModestBenchConfigurationManager } from "./services/config-manager.js";
9
+ import { BenchmarkFileLoader } from "./services/file-loader.js";
10
+ import { FileHistoryStorage } from "./services/history-storage.js";
11
+ import { ModestBenchProgressManager } from "./services/progress-manager.js";
12
+ import { ModestBenchReporterRegistry } from "./services/reporter-registry.js";
13
13
  /**
14
14
  * Initializes the ModestBench engine with default dependencies.
15
15
  *
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,+BAA+B,EAAE,4BAA4B;AAEtE,OAAO,EAAE,eAAe,EAAE,gCAAgC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,yBAAyB;AACvD,OAAO,EAAE,0BAA0B,EAAE,8BAA8B;AACnE,OAAO,EAAE,2BAA2B,EAAE,gCAAgC;AACtE,OAAO,EAAE,kBAAkB,EAAE,6BAA6B;AAE1D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,GAAsB,EAAE;IAC/C,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,aAAa,EAAE,IAAI,+BAA+B,EAAE;QACpD,UAAU,EAAE,IAAI,mBAAmB,EAAE;QACrC,cAAc,EAAE,IAAI,kBAAkB,EAAE;QACxC,eAAe,EAAE,IAAI,0BAA0B,EAAE;QACjD,gBAAgB,EAAE,IAAI,2BAA2B,EAAE;KACpD,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,eAAe,EAAE,gCAAgC;AAC1D,OAAO,EAAE,+BAA+B,EAAE,qCAAqC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,kCAAkC;AAChE,OAAO,EAAE,kBAAkB,EAAE,sCAAsC;AACnE,OAAO,EAAE,0BAA0B,EAAE,uCAAuC;AAC5E,OAAO,EAAE,2BAA2B,EAAE,wCAAwC;AAE9E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,GAAsB,EAAE;IAC/C,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,aAAa,EAAE,IAAI,+BAA+B,EAAE;QACpD,UAAU,EAAE,IAAI,mBAAmB,EAAE;QACrC,cAAc,EAAE,IAAI,kBAAkB,EAAE;QACxC,eAAe,EAAE,IAAI,0BAA0B,EAAE;QACjD,gBAAgB,EAAE,IAAI,2BAA2B,EAAE;KACpD,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
@@ -39,40 +39,14 @@ var __importStar = (this && this.__importStar) || (function () {
39
39
  };
40
40
  })();
41
41
  Object.defineProperty(exports, "__esModule", { value: true });
42
- exports.handleHistoryCommand = void 0;
43
- const index_js_1 = require("../../errors/index.cjs");
44
- /**
45
- * Handle history command
46
- */
47
- const handleHistoryCommand = async (context, options) => {
48
- try {
49
- // Get the subcommand
50
- const subcommand = options.subcommand;
51
- switch (subcommand) {
52
- case 'clean':
53
- return await handleCleanCommand(context, options);
54
- case 'compare':
55
- return await handleCompareCommand(context, options);
56
- case 'export':
57
- return await handleExportCommand(context, options);
58
- case 'list':
59
- return await handleListCommand(context, options);
60
- case 'show':
61
- return await handleShowCommand(context, options);
62
- case 'trends':
63
- return await handleTrendsCommand(context, options);
64
- default:
65
- console.error(`Unknown history subcommand: ${subcommand || '(none)'}`);
66
- console.error('Available subcommands: list, show, compare, trends, clean, export');
67
- return 2; // Config error
68
- }
69
- }
70
- catch (error) {
71
- console.error('History command failed:', error instanceof Error ? error.message : String(error));
72
- return 2; // Configuration/runtime errors
73
- }
74
- };
75
- exports.handleHistoryCommand = handleHistoryCommand;
42
+ exports.handleTrendsCommand = exports.handleShowCommand = exports.handleListCommand = exports.handleExportCommand = exports.handleCompareCommand = exports.handleCleanCommand = void 0;
43
+ const compare_js_1 = require("../../formatters/history/compare.cjs");
44
+ const list_js_1 = require("../../formatters/history/list.cjs");
45
+ const show_js_1 = require("../../formatters/history/show.cjs");
46
+ const trends_js_1 = require("../../formatters/history/trends.cjs");
47
+ const comparison_js_1 = require("../../services/history/comparison.cjs");
48
+ const query_js_1 = require("../../services/history/query.cjs");
49
+ const trend_analysis_js_1 = require("../../services/history/trend-analysis.cjs");
76
50
  /**
77
51
  * Format bytes in human-readable format
78
52
  */
@@ -86,6 +60,25 @@ const formatBytes = (bytes) => {
86
60
  }
87
61
  return `${size.toFixed(1)} ${units[unitIndex]}`;
88
62
  };
63
+ /**
64
+ * Resolve a partial run ID to a full ID by checking prefix match
65
+ *
66
+ * Supports Git-style partial ID matching (e.g., "k3m" matches "k3m9x2p")
67
+ */
68
+ const resolveRunId = async (storage, partialId) => {
69
+ // First try exact match
70
+ const exactRun = await storage.loadRun(partialId);
71
+ if (exactRun) {
72
+ return partialId;
73
+ }
74
+ // Query all runs to find a prefix match
75
+ const allRuns = await storage.queryRuns({});
76
+ const prefixMatch = allRuns.find((run) => run.id.startsWith(partialId));
77
+ if (prefixMatch) {
78
+ return prefixMatch.id;
79
+ }
80
+ return null;
81
+ };
89
82
  /**
90
83
  * Handle the clean subcommand
91
84
  */
@@ -137,54 +130,33 @@ const handleCleanCommand = async (context, options) => {
137
130
  return 5;
138
131
  }
139
132
  };
133
+ exports.handleCleanCommand = handleCleanCommand;
140
134
  /**
141
135
  * Handle the compare subcommand
142
136
  */
143
137
  const handleCompareCommand = async (context, options) => {
144
138
  try {
145
- // For compare command, IDs come from args after the subcommand
146
- const id1 = options.args?.[0];
147
- const id2 = options.args?.[1];
148
- if (!id1 || !id2) {
149
- console.error('Two run IDs are required for compare command');
150
- console.error('Usage: modestbench history compare <run-id1> <run-id2>');
151
- return 2;
152
- }
153
139
  const [run1, run2] = await Promise.all([
154
- context.historyStorage.loadRun(id1),
155
- context.historyStorage.loadRun(id2),
140
+ context.historyStorage.loadRun(options.runId1),
141
+ context.historyStorage.loadRun(options.runId2),
156
142
  ]);
157
143
  if (!run1) {
158
- console.error(`Run not found: ${id1}`);
144
+ console.error(`Run not found: ${options.runId1}`);
159
145
  return 1;
160
146
  }
161
147
  if (!run2) {
162
- console.error(`Run not found: ${id2}`);
148
+ console.error(`Run not found: ${options.runId2}`);
163
149
  return 1;
164
150
  }
165
- if (options.format === 'json') {
166
- const comparison = {
167
- run1: { id: run1.id, summary: run1.summary },
168
- run2: { id: run2.id, summary: run2.summary },
169
- // TODO: Add detailed comparison logic
170
- };
171
- console.log(JSON.stringify(comparison, null, 2));
172
- }
173
- else {
174
- // Human format comparison
175
- console.log(`Comparing runs:`);
176
- console.log(` Run 1: ${run1.id} (${run1.startTime.toLocaleString()})`);
177
- console.log(` Run 2: ${run2.id} (${run2.startTime.toLocaleString()})`);
178
- console.log();
179
- console.log('Summary comparison:');
180
- console.log(` Files: ${run1.summary.totalFiles} vs ${run2.summary.totalFiles}`);
181
- console.log(` Tasks: ${run1.summary.totalTasks} vs ${run2.summary.totalTasks}`);
182
- console.log(` Passed: ${run1.summary.passedTasks} vs ${run2.summary.passedTasks}`);
183
- console.log(` Failed: ${run1.summary.failedTasks} vs ${run2.summary.failedTasks}`);
184
- // TODO: Add detailed performance comparison
185
- console.log();
186
- console.log('Note: Detailed performance comparison not yet implemented.');
187
- }
151
+ // Compare using service
152
+ const comparisonService = new comparison_js_1.ComparisonService();
153
+ const result = comparisonService.compareRuns(run1, run2);
154
+ // Format output
155
+ const formatter = new compare_js_1.HistoryCompareFormatter();
156
+ const output = options.format === 'json'
157
+ ? formatter.formatJson(result)
158
+ : formatter.formatHuman(result);
159
+ console.log(output);
188
160
  return 0;
189
161
  }
190
162
  catch (error) {
@@ -192,6 +164,7 @@ const handleCompareCommand = async (context, options) => {
192
164
  return 5;
193
165
  }
194
166
  };
167
+ exports.handleCompareCommand = handleCompareCommand;
195
168
  /**
196
169
  * Handle the export subcommand
197
170
  */
@@ -200,21 +173,15 @@ const handleExportCommand = async (context, options) => {
200
173
  const format = options.format || 'json';
201
174
  // Build query for export
202
175
  const query = {
203
- ...(options.since && { since: parseDate(options.since) }),
204
- ...(options.until && { until: parseDate(options.until) }),
176
+ ...(options.since && { since: (0, query_js_1.parseDate)(options.since) }),
177
+ ...(options.until && { until: (0, query_js_1.parseDate)(options.until) }),
205
178
  };
206
179
  const exportData = await context.historyStorage.export(format, query);
207
- if (options.outputDir) {
208
- // Write to file
209
- const fs = await Promise.resolve().then(() => __importStar(require('node:fs/promises')));
210
- await fs.writeFile(options.outputDir, exportData, 'utf8');
211
- if (!options.quiet) {
212
- console.log(`Exported history to ${options.outputDir}`);
213
- }
214
- }
215
- else {
216
- // Write to stdout
217
- console.log(exportData);
180
+ // Write to file
181
+ const fs = await Promise.resolve().then(() => __importStar(require('node:fs/promises')));
182
+ await fs.writeFile(options.outputPath, exportData, 'utf8');
183
+ if (!options.quiet) {
184
+ console.log(`Exported history to ${options.outputPath}`);
218
185
  }
219
186
  return 0;
220
187
  }
@@ -223,89 +190,38 @@ const handleExportCommand = async (context, options) => {
223
190
  return 5;
224
191
  }
225
192
  };
193
+ exports.handleExportCommand = handleExportCommand;
226
194
  /**
227
195
  * Handle the list subcommand
228
196
  */
229
197
  const handleListCommand = async (context, options) => {
230
198
  try {
231
- // Build query from command line arguments
232
- let parsedSince;
233
- let parsedUntil;
234
- if (options.since) {
235
- try {
236
- parsedSince = parseDate(options.since);
237
- }
238
- catch (error) {
239
- console.error('Invalid since date:', error instanceof Error ? error.message : String(error));
240
- return 2; // Invalid date format
241
- }
242
- }
243
- if (options.until) {
244
- try {
245
- parsedUntil = parseDate(options.until);
246
- }
247
- catch (error) {
248
- console.error('Invalid until date:', error instanceof Error ? error.message : String(error));
249
- return 2; // Invalid date format
250
- }
251
- }
252
- const query = {
253
- ...(parsedSince && { since: parsedSince }),
254
- ...(parsedUntil && { until: parsedUntil }),
255
- ...(options.pattern && { pattern: options.pattern }),
256
- ...(options.tags && options.tags.length > 0 && { tags: options.tags }),
257
- ...(options.limit && { limit: options.limit }),
199
+ // Query runs using service
200
+ const queryService = new query_js_1.HistoryQueryService(context.historyStorage);
201
+ const runs = await queryService.queryWithDateParsing(options);
202
+ // Transform to result format
203
+ const result = {
204
+ runs: runs.map((run) => ({
205
+ duration: run.duration,
206
+ id: run.id,
207
+ startTime: run.startTime,
208
+ summary: run.summary,
209
+ })),
210
+ totalCount: runs.length,
258
211
  };
259
- // Query historical runs
260
- const runs = await context.historyStorage.queryRuns(query);
261
- // Display results based on format
212
+ // Format output
213
+ const formatter = new list_js_1.HistoryListFormatter();
214
+ let output;
262
215
  if (options.format === 'json') {
263
- if (runs.length === 0) {
264
- console.log('[]'); // Empty JSON array for no data
265
- }
266
- else {
267
- console.log(JSON.stringify(runs.map((run) => ({
268
- duration: run.duration,
269
- failed: run.summary.failedTasks,
270
- files: run.summary.totalFiles,
271
- id: run.id,
272
- passed: run.summary.passedTasks,
273
- startTime: run.startTime,
274
- tasks: run.summary.totalTasks,
275
- })), null, 2));
276
- }
216
+ output = formatter.formatJson(result);
277
217
  }
278
218
  else if (options.format === 'csv') {
279
- console.log('id,startTime,duration,files,tasks,passed,failed');
280
- if (runs.length > 0) {
281
- for (const run of runs) {
282
- console.log(`${run.id},${run.startTime.toISOString()},${run.duration},${run.summary.totalFiles},${run.summary.totalTasks},${run.summary.passedTasks},${run.summary.failedTasks}`);
283
- }
284
- }
285
- // For CSV, no additional message needed - header is sufficient
219
+ output = formatter.formatCsv(result);
286
220
  }
287
221
  else {
288
- // Human format
289
- if (runs.length === 0) {
290
- if (!options.quiet) {
291
- console.log('No historical data found matching criteria.');
292
- }
293
- }
294
- else {
295
- console.log('Recent benchmark runs:');
296
- console.log();
297
- for (const run of runs) {
298
- const dateStr = run.startTime.toLocaleString();
299
- const durationStr = `${(run.duration / 1000).toFixed(1)}s`;
300
- const statusStr = run.summary.failedTasks > 0
301
- ? `${run.summary.passedTasks} passed, ${run.summary.failedTasks} failed`
302
- : `${run.summary.passedTasks} passed`;
303
- console.log(` ${run.id.substring(0, 8)} - ${dateStr} (${durationStr})`);
304
- console.log(` ${run.summary.totalFiles} files, ${run.summary.totalTasks} tasks: ${statusStr}`);
305
- console.log();
306
- }
307
- }
222
+ output = formatter.formatHuman(result);
308
223
  }
224
+ console.log(output);
309
225
  return 0;
310
226
  }
311
227
  catch (error) {
@@ -313,59 +229,29 @@ const handleListCommand = async (context, options) => {
313
229
  return 5;
314
230
  }
315
231
  };
232
+ exports.handleListCommand = handleListCommand;
316
233
  /**
317
234
  * Handle the show subcommand
318
235
  */
319
236
  const handleShowCommand = async (context, options) => {
320
237
  try {
321
- // For show command, ID comes from the args after the subcommand
322
- const runId = options.args?.[0];
323
- if (!runId) {
324
- console.error('Run ID is required for show command');
325
- console.error('Usage: modestbench history show <run-id>');
326
- return 2;
238
+ // Resolve partial ID to full ID
239
+ const fullRunId = await resolveRunId(context.historyStorage, options.runId);
240
+ if (!fullRunId) {
241
+ console.error(`Run not found: ${options.runId}`);
242
+ return 1;
327
243
  }
328
- const run = await context.historyStorage.loadRun(runId);
244
+ const run = await context.historyStorage.loadRun(fullRunId);
329
245
  if (!run) {
330
- console.error(`Run not found: ${runId}`);
246
+ console.error(`Run not found: ${options.runId}`);
331
247
  return 1;
332
248
  }
333
- if (options.format === 'json') {
334
- console.log(JSON.stringify(run, null, 2));
335
- }
336
- else {
337
- // Human format
338
- console.log(`Benchmark Run: ${run.id}`);
339
- console.log(`Date: ${run.startTime.toLocaleString()}`);
340
- console.log(`Duration: ${(run.duration / 1000).toFixed(1)}s`);
341
- console.log(`Environment: Node.js ${run.environment.nodeVersion} on ${run.environment.platform}`);
342
- if (run.git) {
343
- console.log(`Git: ${run.git.branch}@${run.git.commit.substring(0, 8)}`);
344
- }
345
- console.log();
346
- console.log('Summary:');
347
- console.log(` Files: ${run.summary.totalFiles}`);
348
- console.log(` Suites: ${run.summary.totalSuites}`);
349
- console.log(` Tasks: ${run.summary.totalTasks}`);
350
- console.log(` Passed: ${run.summary.passedTasks}`);
351
- console.log(` Failed: ${run.summary.failedTasks}`);
352
- // TODO: Show detailed file/suite/task results
353
- console.log();
354
- console.log('Detailed results:');
355
- for (const file of run.files) {
356
- console.log(` 📁 ${file.filePath}`);
357
- for (const suite of file.suites) {
358
- console.log(` 📊 ${suite.name}`);
359
- for (const task of suite.tasks) {
360
- const status = task.error ? '❌' : '✅';
361
- const timing = task.error
362
- ? 'failed'
363
- : `${(task.mean / 1000000).toFixed(2)}ms`;
364
- console.log(` ${status} ${task.name} - ${timing}`);
365
- }
366
- }
367
- }
368
- }
249
+ // Format output
250
+ const formatter = new show_js_1.HistoryShowFormatter();
251
+ const output = options.format === 'json'
252
+ ? formatter.formatJson(run)
253
+ : formatter.formatHuman(run);
254
+ console.log(output);
369
255
  return 0;
370
256
  }
371
257
  catch (error) {
@@ -373,88 +259,44 @@ const handleShowCommand = async (context, options) => {
373
259
  return 5;
374
260
  }
375
261
  };
262
+ exports.handleShowCommand = handleShowCommand;
376
263
  /**
377
264
  * Handle the trends subcommand
378
265
  */
379
266
  const handleTrendsCommand = async (context, options) => {
380
267
  try {
381
- // Build query from command line arguments (same as list command)
382
- let parsedSince;
383
- let parsedUntil;
384
- if (options.since) {
385
- try {
386
- parsedSince = parseDate(options.since);
387
- }
388
- catch (error) {
389
- console.error('Invalid since date:', error instanceof Error ? error.message : String(error));
390
- return 2; // Invalid date format
391
- }
392
- }
393
- if (options.until) {
394
- try {
395
- parsedUntil = parseDate(options.until);
396
- }
397
- catch (error) {
398
- console.error('Invalid until date:', error instanceof Error ? error.message : String(error));
399
- return 2; // Invalid date format
400
- }
401
- }
402
- // Get pattern from args or explicit pattern option
403
- const pattern = options.args?.[0] || options.pattern;
404
- const query = {
405
- ...(parsedSince && { since: parsedSince }),
406
- ...(parsedUntil && { until: parsedUntil }),
407
- ...(pattern && { pattern }),
408
- ...(options.tags && options.tags.length > 0 && { tags: options.tags }),
409
- ...(options.limit && { limit: options.limit }),
410
- };
411
- // Query historical runs
412
- const runs = await context.historyStorage.queryRuns(query);
268
+ // Query runs using service
269
+ const queryService = new query_js_1.HistoryQueryService(context.historyStorage);
270
+ const runs = await queryService.queryWithDateParsing({
271
+ limit: options.all ? undefined : options.limit,
272
+ pattern: options.pattern,
273
+ since: options.since,
274
+ tags: options.tags,
275
+ until: options.until,
276
+ });
413
277
  if (runs.length === 0) {
414
278
  if (!options.quiet) {
415
279
  console.log('No historical data found matching criteria');
416
280
  }
417
- return 0; // Success - no data is not an error
418
- }
419
- if (options.format === 'json') {
420
- // TODO: Generate trends data in JSON format
421
- const trendsData = {
422
- runs: runs.length,
423
- timespan: {
424
- end: runs[0]?.startTime,
425
- start: runs[runs.length - 1]?.startTime,
426
- },
427
- // TODO: Add actual trend calculations
428
- };
429
- console.log(JSON.stringify(trendsData, null, 2));
281
+ return 0;
430
282
  }
431
- else {
432
- // Human format trends
433
- if (!options.quiet) {
434
- console.log(`Performance trends for ${runs.length} runs:`);
435
- console.log(`Time range: ${runs[runs.length - 1]?.startTime} to ${runs[0]?.startTime}`);
436
- // TODO: Add trend analysis and visualization
437
- console.log('(Trend analysis not yet implemented)');
438
- }
283
+ // Analyze trends using service
284
+ const analysisService = new trend_analysis_js_1.TrendAnalysisService();
285
+ const result = analysisService.analyzeTrends(runs);
286
+ // Format output
287
+ const formatter = new trends_js_1.HistoryTrendsFormatter();
288
+ const output = options.format === 'json'
289
+ ? formatter.formatJson(result)
290
+ : formatter.formatHuman(result);
291
+ if (!options.quiet || options.format !== 'human') {
292
+ console.log(output);
439
293
  }
440
- return 0; // Success
294
+ return 0;
441
295
  }
442
296
  catch (error) {
443
- console.error('Error showing trends:', error);
444
- return 3; // Runtime error
445
- }
446
- };
447
- /**
448
- * Parse date string (ISO 8601 or relative)
449
- */
450
- const parseDate = (dateStr) => {
451
- // Try parsing as ISO 8601 first
452
- const isoDate = new Date(dateStr);
453
- if (!isNaN(isoDate.getTime())) {
454
- return isoDate;
297
+ console.error('Failed to show trends:', error instanceof Error ? error.message : String(error));
298
+ return 5;
455
299
  }
456
- // TODO: Parse relative dates like "1 week ago", "3 days ago", etc.
457
- // For now, throw error for invalid dates
458
- throw new index_js_1.InvalidDateFormatError(`Invalid date format: "${dateStr}"`);
459
300
  };
301
+ exports.handleTrendsCommand = handleTrendsCommand;
460
302
  //# sourceMappingURL=history.js.map