modestbench 0.0.3 → 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.
- package/CHANGELOG.md +26 -0
- package/README.md +39 -31
- package/dist/bootstrap.cjs +10 -12
- package/dist/bootstrap.cjs.map +1 -1
- package/dist/bootstrap.d.cts.map +1 -1
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +5 -7
- package/dist/bootstrap.js.map +1 -1
- package/dist/cli/commands/history.cjs +108 -265
- package/dist/cli/commands/history.cjs.map +1 -1
- package/dist/cli/commands/history.d.cts +75 -12
- package/dist/cli/commands/history.d.cts.map +1 -1
- package/dist/cli/commands/history.d.ts +75 -12
- package/dist/cli/commands/history.d.ts.map +1 -1
- package/dist/cli/commands/history.js +105 -267
- package/dist/cli/commands/history.js.map +1 -1
- package/dist/cli/commands/init.cjs +5 -4
- package/dist/cli/commands/init.cjs.map +1 -1
- package/dist/cli/commands/init.d.cts.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +5 -4
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/run.cjs +32 -9
- package/dist/cli/commands/run.cjs.map +1 -1
- package/dist/cli/commands/run.d.cts +1 -0
- package/dist/cli/commands/run.d.cts.map +1 -1
- package/dist/cli/commands/run.d.ts +1 -0
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +32 -9
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/index.cjs +336 -103
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +1 -2
- package/dist/cli/index.d.cts.map +1 -1
- package/dist/cli/index.d.ts +1 -2
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +332 -99
- package/dist/cli/index.js.map +1 -1
- package/dist/constants.cjs +53 -1
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +36 -0
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.ts +36 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +52 -0
- package/dist/constants.js.map +1 -1
- package/dist/core/engine.cjs +23 -43
- package/dist/core/engine.cjs.map +1 -1
- package/dist/core/engine.d.cts +4 -3
- package/dist/core/engine.d.cts.map +1 -1
- package/dist/core/engine.d.ts +4 -3
- package/dist/core/engine.d.ts.map +1 -1
- package/dist/core/engine.js +23 -43
- package/dist/core/engine.js.map +1 -1
- package/dist/core/engines/accurate-engine.cjs +2 -1
- package/dist/core/engines/accurate-engine.cjs.map +1 -1
- package/dist/core/engines/accurate-engine.d.cts.map +1 -1
- package/dist/core/engines/accurate-engine.d.ts.map +1 -1
- package/dist/core/engines/accurate-engine.js +2 -1
- package/dist/core/engines/accurate-engine.js.map +1 -1
- package/dist/core/engines/tinybench-engine.cjs +6 -5
- package/dist/core/engines/tinybench-engine.cjs.map +1 -1
- package/dist/core/engines/tinybench-engine.d.cts.map +1 -1
- package/dist/core/engines/tinybench-engine.d.ts.map +1 -1
- package/dist/core/engines/tinybench-engine.js +6 -5
- package/dist/core/engines/tinybench-engine.js.map +1 -1
- package/dist/core/output-path-resolver.cjs +34 -0
- package/dist/core/output-path-resolver.cjs.map +1 -0
- package/dist/core/output-path-resolver.d.cts +10 -0
- package/dist/core/output-path-resolver.d.cts.map +1 -0
- package/dist/core/output-path-resolver.d.ts +10 -0
- package/dist/core/output-path-resolver.d.ts.map +1 -0
- package/dist/core/output-path-resolver.js +30 -0
- package/dist/core/output-path-resolver.js.map +1 -0
- package/dist/errors/base.cjs +130 -0
- package/dist/errors/base.cjs.map +1 -0
- package/dist/errors/base.d.cts +97 -0
- package/dist/errors/base.d.cts.map +1 -0
- package/dist/errors/base.d.ts +97 -0
- package/dist/errors/base.d.ts.map +1 -0
- package/dist/errors/base.js +124 -0
- package/dist/errors/base.js.map +1 -0
- package/dist/errors/cli.cjs +58 -0
- package/dist/errors/cli.cjs.map +1 -0
- package/dist/errors/cli.d.cts +44 -0
- package/dist/errors/cli.d.cts.map +1 -0
- package/dist/errors/cli.d.ts +44 -0
- package/dist/errors/cli.d.ts.map +1 -0
- package/dist/errors/cli.js +52 -0
- package/dist/errors/cli.js.map +1 -0
- package/dist/errors/configuration.cjs +48 -0
- package/dist/errors/configuration.cjs.map +1 -0
- package/dist/errors/configuration.d.cts +41 -0
- package/dist/errors/configuration.d.cts.map +1 -0
- package/dist/errors/configuration.d.ts +41 -0
- package/dist/errors/configuration.d.ts.map +1 -0
- package/dist/errors/configuration.js +41 -0
- package/dist/errors/configuration.js.map +1 -0
- package/dist/errors/execution.cjs +65 -0
- package/dist/errors/execution.cjs.map +1 -0
- package/dist/errors/execution.d.cts +56 -0
- package/dist/errors/execution.d.cts.map +1 -0
- package/dist/errors/execution.d.ts +56 -0
- package/dist/errors/execution.d.ts.map +1 -0
- package/dist/errors/execution.js +56 -0
- package/dist/errors/execution.js.map +1 -0
- package/dist/errors/file.cjs +56 -0
- package/dist/errors/file.cjs.map +1 -0
- package/dist/errors/file.d.cts +48 -0
- package/dist/errors/file.d.cts.map +1 -0
- package/dist/errors/file.d.ts +48 -0
- package/dist/errors/file.d.ts.map +1 -0
- package/dist/errors/file.js +48 -0
- package/dist/errors/file.js.map +1 -0
- package/dist/errors/index.cjs +59 -0
- package/dist/errors/index.cjs.map +1 -0
- package/dist/errors/index.d.cts +16 -0
- package/dist/errors/index.d.cts.map +1 -0
- package/dist/errors/index.d.ts +16 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +24 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/reporter.cjs +38 -0
- package/dist/errors/reporter.cjs.map +1 -0
- package/dist/errors/reporter.d.cts +32 -0
- package/dist/errors/reporter.d.cts.map +1 -0
- package/dist/errors/reporter.d.ts +32 -0
- package/dist/errors/reporter.d.ts.map +1 -0
- package/dist/errors/reporter.js +32 -0
- package/dist/errors/reporter.js.map +1 -0
- package/dist/errors/storage.cjs +55 -0
- package/dist/errors/storage.cjs.map +1 -0
- package/dist/errors/storage.d.cts +47 -0
- package/dist/errors/storage.d.cts.map +1 -0
- package/dist/errors/storage.d.ts +47 -0
- package/dist/errors/storage.d.ts.map +1 -0
- package/dist/errors/storage.js +47 -0
- package/dist/errors/storage.js.map +1 -0
- package/dist/errors/validation.cjs +38 -0
- package/dist/errors/validation.cjs.map +1 -0
- package/dist/errors/validation.d.cts +32 -0
- package/dist/errors/validation.d.cts.map +1 -0
- package/dist/errors/validation.d.ts +32 -0
- package/dist/errors/validation.d.ts.map +1 -0
- package/dist/errors/validation.js +32 -0
- package/dist/errors/validation.js.map +1 -0
- package/dist/formatters/history/base.cjs +9 -0
- package/dist/formatters/history/base.cjs.map +1 -0
- package/dist/formatters/history/base.d.cts +26 -0
- package/dist/formatters/history/base.d.cts.map +1 -0
- package/dist/formatters/history/base.d.ts +26 -0
- package/dist/formatters/history/base.d.ts.map +1 -0
- package/dist/formatters/history/base.js +8 -0
- package/dist/formatters/history/base.js.map +1 -0
- package/dist/formatters/history/compare.cjs +127 -0
- package/dist/formatters/history/compare.cjs.map +1 -0
- package/dist/formatters/history/compare.d.cts +21 -0
- package/dist/formatters/history/compare.d.cts.map +1 -0
- package/dist/formatters/history/compare.d.ts +21 -0
- package/dist/formatters/history/compare.d.ts.map +1 -0
- package/dist/formatters/history/compare.js +123 -0
- package/dist/formatters/history/compare.js.map +1 -0
- package/dist/formatters/history/list.cjs +74 -0
- package/dist/formatters/history/list.cjs.map +1 -0
- package/dist/formatters/history/list.d.cts +25 -0
- package/dist/formatters/history/list.d.cts.map +1 -0
- package/dist/formatters/history/list.d.ts +25 -0
- package/dist/formatters/history/list.d.ts.map +1 -0
- package/dist/formatters/history/list.js +70 -0
- package/dist/formatters/history/list.js.map +1 -0
- package/dist/formatters/history/show.cjs +98 -0
- package/dist/formatters/history/show.cjs.map +1 -0
- package/dist/formatters/history/show.d.cts +21 -0
- package/dist/formatters/history/show.d.cts.map +1 -0
- package/dist/formatters/history/show.d.ts +21 -0
- package/dist/formatters/history/show.d.ts.map +1 -0
- package/dist/formatters/history/show.js +94 -0
- package/dist/formatters/history/show.js.map +1 -0
- package/dist/formatters/history/trends.cjs +194 -0
- package/dist/formatters/history/trends.cjs.map +1 -0
- package/dist/formatters/history/trends.d.cts +22 -0
- package/dist/formatters/history/trends.d.cts.map +1 -0
- package/dist/formatters/history/trends.d.ts +22 -0
- package/dist/formatters/history/trends.d.ts.map +1 -0
- package/dist/formatters/history/trends.js +190 -0
- package/dist/formatters/history/trends.js.map +1 -0
- package/dist/formatters/history/visualization.cjs +79 -0
- package/dist/formatters/history/visualization.cjs.map +1 -0
- package/dist/formatters/history/visualization.d.cts +24 -0
- package/dist/formatters/history/visualization.d.cts.map +1 -0
- package/dist/formatters/history/visualization.d.ts +24 -0
- package/dist/formatters/history/visualization.d.ts.map +1 -0
- package/dist/formatters/history/visualization.js +74 -0
- package/dist/formatters/history/visualization.js.map +1 -0
- package/dist/index.cjs +17 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -11
- package/dist/index.js.map +1 -1
- package/dist/reporters/csv.cjs +5 -4
- package/dist/reporters/csv.cjs.map +1 -1
- package/dist/reporters/csv.d.cts +1 -1
- package/dist/reporters/csv.d.cts.map +1 -1
- package/dist/reporters/csv.d.ts +1 -1
- package/dist/reporters/csv.d.ts.map +1 -1
- package/dist/reporters/csv.js +4 -3
- package/dist/reporters/csv.js.map +1 -1
- package/dist/reporters/human.cjs +24 -62
- package/dist/reporters/human.cjs.map +1 -1
- package/dist/reporters/human.d.cts +1 -1
- package/dist/reporters/human.d.cts.map +1 -1
- package/dist/reporters/human.d.ts +1 -1
- package/dist/reporters/human.d.ts.map +1 -1
- package/dist/reporters/human.js +3 -41
- package/dist/reporters/human.js.map +1 -1
- package/dist/reporters/json.cjs +5 -4
- package/dist/reporters/json.cjs.map +1 -1
- package/dist/reporters/json.d.cts +1 -1
- package/dist/reporters/json.d.cts.map +1 -1
- package/dist/reporters/json.d.ts +1 -1
- package/dist/reporters/json.d.ts.map +1 -1
- package/dist/reporters/json.js +4 -3
- package/dist/reporters/json.js.map +1 -1
- package/dist/reporters/simple.cjs +3 -3
- package/dist/reporters/simple.cjs.map +1 -1
- package/dist/reporters/simple.d.cts +1 -1
- package/dist/reporters/simple.d.cts.map +1 -1
- package/dist/reporters/simple.d.ts +1 -1
- package/dist/reporters/simple.d.ts.map +1 -1
- package/dist/reporters/simple.js +2 -2
- package/dist/reporters/simple.js.map +1 -1
- package/dist/{config/manager.cjs → services/config-manager.cjs} +10 -4
- package/dist/services/config-manager.cjs.map +1 -0
- package/dist/{config/manager.d.cts → services/config-manager.d.cts} +1 -1
- package/dist/services/config-manager.d.cts.map +1 -0
- package/dist/{config/manager.d.ts → services/config-manager.d.ts} +1 -1
- package/dist/services/config-manager.d.ts.map +1 -0
- package/dist/{config/manager.js → services/config-manager.js} +10 -4
- package/dist/services/config-manager.js.map +1 -0
- package/dist/{core/loader.cjs → services/file-loader.cjs} +18 -7
- package/dist/services/file-loader.cjs.map +1 -0
- package/dist/{core/loader.d.cts → services/file-loader.d.cts} +1 -1
- package/dist/services/file-loader.d.cts.map +1 -0
- package/dist/{core/loader.d.ts → services/file-loader.d.ts} +1 -1
- package/dist/services/file-loader.d.ts.map +1 -0
- package/dist/{core/loader.js → services/file-loader.js} +18 -7
- package/dist/services/file-loader.js.map +1 -0
- package/dist/services/history/comparison.cjs +124 -0
- package/dist/services/history/comparison.cjs.map +1 -0
- package/dist/services/history/comparison.d.cts +18 -0
- package/dist/services/history/comparison.d.cts.map +1 -0
- package/dist/services/history/comparison.d.ts +18 -0
- package/dist/services/history/comparison.d.ts.map +1 -0
- package/dist/services/history/comparison.js +120 -0
- package/dist/services/history/comparison.js.map +1 -0
- package/dist/services/history/models.cjs +9 -0
- package/dist/services/history/models.cjs.map +1 -0
- package/dist/services/history/models.d.cts +139 -0
- package/dist/services/history/models.d.cts.map +1 -0
- package/dist/services/history/models.d.ts +139 -0
- package/dist/services/history/models.d.ts.map +1 -0
- package/dist/services/history/models.js +8 -0
- package/dist/services/history/models.js.map +1 -0
- package/dist/services/history/query.cjs +97 -0
- package/dist/services/history/query.cjs.map +1 -0
- package/dist/services/history/query.d.cts +38 -0
- package/dist/services/history/query.d.cts.map +1 -0
- package/dist/services/history/query.d.ts +38 -0
- package/dist/services/history/query.d.ts.map +1 -0
- package/dist/services/history/query.js +92 -0
- package/dist/services/history/query.js.map +1 -0
- package/dist/services/history/trend-analysis.cjs +187 -0
- package/dist/services/history/trend-analysis.cjs.map +1 -0
- package/dist/services/history/trend-analysis.d.cts +34 -0
- package/dist/services/history/trend-analysis.d.cts.map +1 -0
- package/dist/services/history/trend-analysis.d.ts +34 -0
- package/dist/services/history/trend-analysis.d.ts.map +1 -0
- package/dist/services/history/trend-analysis.js +179 -0
- package/dist/services/history/trend-analysis.js.map +1 -0
- package/dist/{storage/history.cjs → services/history-storage.cjs} +33 -12
- package/dist/services/history-storage.cjs.map +1 -0
- package/dist/{storage/history.d.cts → services/history-storage.d.cts} +1 -1
- package/dist/services/history-storage.d.cts.map +1 -0
- package/dist/{storage/history.d.ts → services/history-storage.d.ts} +1 -1
- package/dist/services/history-storage.d.ts.map +1 -0
- package/dist/{storage/history.js → services/history-storage.js} +33 -12
- package/dist/services/history-storage.js.map +1 -0
- package/dist/{progress/manager.cjs → services/progress-manager.cjs} +1 -1
- package/dist/services/progress-manager.cjs.map +1 -0
- package/dist/{progress/manager.d.cts → services/progress-manager.d.cts} +1 -1
- package/dist/services/progress-manager.d.cts.map +1 -0
- package/dist/{progress/manager.d.ts → services/progress-manager.d.ts} +1 -1
- package/dist/services/progress-manager.d.ts.map +1 -0
- package/dist/{progress/manager.js → services/progress-manager.js} +1 -1
- package/dist/services/progress-manager.js.map +1 -0
- package/dist/{reporters/registry.cjs → services/reporter-registry.cjs} +4 -3
- package/dist/services/reporter-registry.cjs.map +1 -0
- package/dist/{reporters/registry.d.cts → services/reporter-registry.d.cts} +1 -1
- package/dist/services/reporter-registry.d.cts.map +1 -0
- package/dist/{reporters/registry.d.ts → services/reporter-registry.d.ts} +1 -1
- package/dist/services/reporter-registry.d.ts.map +1 -0
- package/dist/{reporters/registry.js → services/reporter-registry.js} +4 -3
- package/dist/services/reporter-registry.js.map +1 -0
- package/dist/types/cli.d.cts +3 -0
- package/dist/types/cli.d.cts.map +1 -1
- package/dist/types/cli.d.ts +3 -0
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/interfaces.d.cts +1 -34
- package/dist/types/interfaces.d.cts.map +1 -1
- package/dist/types/interfaces.d.ts +1 -34
- package/dist/types/interfaces.d.ts.map +1 -1
- package/dist/utils/ansi.cjs +61 -0
- package/dist/utils/ansi.cjs.map +1 -0
- package/dist/utils/ansi.d.cts +53 -0
- package/dist/utils/ansi.d.cts.map +1 -0
- package/dist/utils/ansi.d.ts +53 -0
- package/dist/utils/ansi.d.ts.map +1 -0
- package/dist/utils/ansi.js +57 -0
- package/dist/utils/ansi.js.map +1 -0
- package/package.json +10 -8
- package/src/bootstrap.ts +5 -7
- package/src/cli/commands/history.ts +195 -341
- package/src/cli/commands/init.ts +14 -4
- package/src/cli/commands/run.ts +52 -7
- package/src/cli/index.ts +393 -119
- package/src/constants.ts +60 -0
- package/src/core/engine.ts +40 -48
- package/src/core/engines/accurate-engine.ts +4 -1
- package/src/core/engines/tinybench-engine.ts +12 -5
- package/src/core/output-path-resolver.ts +38 -0
- package/src/errors/base.ts +152 -0
- package/src/errors/cli.ts +59 -0
- package/src/errors/configuration.ts +45 -0
- package/src/errors/execution.ts +62 -0
- package/src/errors/file.ts +53 -0
- package/src/errors/index.ts +71 -0
- package/src/errors/reporter.ts +35 -0
- package/src/errors/storage.ts +52 -0
- package/src/errors/validation.ts +35 -0
- package/src/formatters/history/base.ts +28 -0
- package/src/formatters/history/compare.ts +186 -0
- package/src/formatters/history/list.ts +101 -0
- package/src/formatters/history/show.ts +155 -0
- package/src/formatters/history/trends.ts +281 -0
- package/src/formatters/history/visualization.ts +93 -0
- package/src/index.ts +10 -14
- package/src/reporters/csv.ts +5 -3
- package/src/reporters/human.ts +3 -43
- package/src/reporters/json.ts +5 -3
- package/src/reporters/simple.ts +2 -2
- package/src/{config/manager.ts → services/config-manager.ts} +13 -3
- package/src/{core/loader.ts → services/file-loader.ts} +28 -6
- package/src/services/history/comparison.ts +130 -0
- package/src/services/history/models.ts +148 -0
- package/src/services/history/query.ts +116 -0
- package/src/services/history/trend-analysis.ts +238 -0
- package/src/{storage/history.ts → services/history-storage.ts} +58 -11
- package/src/{reporters/registry.ts → services/reporter-registry.ts} +9 -2
- package/src/types/cli.ts +3 -0
- package/src/types/interfaces.ts +0 -43
- package/src/utils/ansi.ts +59 -0
- package/dist/config/manager.cjs.map +0 -1
- package/dist/config/manager.d.cts.map +0 -1
- package/dist/config/manager.d.ts.map +0 -1
- package/dist/config/manager.js.map +0 -1
- package/dist/core/error-manager.cjs +0 -303
- package/dist/core/error-manager.cjs.map +0 -1
- package/dist/core/error-manager.d.cts +0 -77
- package/dist/core/error-manager.d.cts.map +0 -1
- package/dist/core/error-manager.d.ts +0 -77
- package/dist/core/error-manager.d.ts.map +0 -1
- package/dist/core/error-manager.js +0 -299
- package/dist/core/error-manager.js.map +0 -1
- package/dist/core/loader.cjs.map +0 -1
- package/dist/core/loader.d.cts.map +0 -1
- package/dist/core/loader.d.ts.map +0 -1
- package/dist/core/loader.js.map +0 -1
- package/dist/progress/manager.cjs.map +0 -1
- package/dist/progress/manager.d.cts.map +0 -1
- package/dist/progress/manager.d.ts.map +0 -1
- package/dist/progress/manager.js.map +0 -1
- package/dist/reporters/registry.cjs.map +0 -1
- package/dist/reporters/registry.d.cts.map +0 -1
- package/dist/reporters/registry.d.ts.map +0 -1
- package/dist/reporters/registry.js.map +0 -1
- package/dist/storage/history.cjs.map +0 -1
- package/dist/storage/history.d.cts.map +0 -1
- package/dist/storage/history.d.ts.map +0 -1
- package/dist/storage/history.js.map +0 -1
- package/src/core/error-manager.ts +0 -372
- /package/src/{progress/manager.ts → services/progress-manager.ts} +0 -0
|
@@ -5,70 +5,94 @@
|
|
|
5
5
|
* comparing, and cleaning historical data.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type {
|
|
8
|
+
import type {
|
|
9
|
+
HistoryQuery,
|
|
10
|
+
HistoryStorage,
|
|
11
|
+
RetentionPolicy,
|
|
12
|
+
} from '../../types/index.js';
|
|
9
13
|
import type { CliContext } from '../index.js';
|
|
10
14
|
|
|
15
|
+
import { HistoryCompareFormatter } from '../../formatters/history/compare.js';
|
|
16
|
+
import { HistoryListFormatter } from '../../formatters/history/list.js';
|
|
17
|
+
import { HistoryShowFormatter } from '../../formatters/history/show.js';
|
|
18
|
+
import { HistoryTrendsFormatter } from '../../formatters/history/trends.js';
|
|
19
|
+
import { ComparisonService } from '../../services/history/comparison.js';
|
|
20
|
+
import {
|
|
21
|
+
HistoryQueryService,
|
|
22
|
+
parseDate,
|
|
23
|
+
} from '../../services/history/query.js';
|
|
24
|
+
import { TrendAnalysisService } from '../../services/history/trend-analysis.js';
|
|
25
|
+
|
|
11
26
|
/**
|
|
12
|
-
*
|
|
27
|
+
* Base options shared by all history subcommands
|
|
13
28
|
*/
|
|
14
|
-
interface
|
|
15
|
-
args?: string[] | undefined; // Additional arguments after subcommand
|
|
16
|
-
confirm?: boolean | undefined;
|
|
29
|
+
interface BaseHistoryOptions {
|
|
17
30
|
cwd: string;
|
|
18
|
-
|
|
19
|
-
|
|
31
|
+
quiet?: boolean | undefined;
|
|
32
|
+
verbose?: boolean | undefined;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Options for history clean command
|
|
37
|
+
*/
|
|
38
|
+
interface HistoryCleanOptions extends BaseHistoryOptions {
|
|
39
|
+
confirm?: boolean | undefined;
|
|
20
40
|
maxAge?: number | undefined;
|
|
21
41
|
maxRuns?: number | undefined;
|
|
22
42
|
maxSize?: number | undefined;
|
|
23
|
-
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Options for history compare command
|
|
47
|
+
*/
|
|
48
|
+
interface HistoryCompareOptions extends BaseHistoryOptions {
|
|
49
|
+
format?: 'human' | 'json' | undefined;
|
|
50
|
+
runId1: string;
|
|
51
|
+
runId2: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Options for history export command
|
|
56
|
+
*/
|
|
57
|
+
interface HistoryExportOptions extends BaseHistoryOptions {
|
|
58
|
+
format?: 'csv' | 'json' | undefined;
|
|
59
|
+
outputPath: string;
|
|
60
|
+
since?: string | undefined;
|
|
61
|
+
until?: string | undefined;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Options for history list command
|
|
66
|
+
*/
|
|
67
|
+
interface HistoryListOptions extends BaseHistoryOptions {
|
|
68
|
+
format?: 'csv' | 'human' | 'json' | undefined;
|
|
69
|
+
limit?: number | undefined;
|
|
24
70
|
pattern?: string | undefined;
|
|
25
|
-
quiet?: boolean | undefined;
|
|
26
71
|
since?: string | undefined;
|
|
27
|
-
subcommand: 'clean' | 'compare' | 'export' | 'list' | 'show' | 'trends';
|
|
28
72
|
tags?: string[] | undefined;
|
|
29
73
|
until?: string | undefined;
|
|
30
|
-
verbose?: boolean | undefined;
|
|
31
74
|
}
|
|
32
75
|
|
|
33
76
|
/**
|
|
34
|
-
*
|
|
77
|
+
* Options for history show command
|
|
35
78
|
*/
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
case 'show':
|
|
54
|
-
return await handleShowCommand(context, options);
|
|
55
|
-
case 'trends':
|
|
56
|
-
return await handleTrendsCommand(context, options);
|
|
57
|
-
default:
|
|
58
|
-
console.error(`Unknown history subcommand: ${subcommand || '(none)'}`);
|
|
59
|
-
console.error(
|
|
60
|
-
'Available subcommands: list, show, compare, trends, clean, export',
|
|
61
|
-
);
|
|
62
|
-
return 2; // Config error
|
|
63
|
-
}
|
|
64
|
-
} catch (error) {
|
|
65
|
-
console.error(
|
|
66
|
-
'History command failed:',
|
|
67
|
-
error instanceof Error ? error.message : String(error),
|
|
68
|
-
);
|
|
69
|
-
return 2; // Configuration/runtime errors
|
|
70
|
-
}
|
|
71
|
-
};
|
|
79
|
+
interface HistoryShowOptions extends BaseHistoryOptions {
|
|
80
|
+
format?: 'csv' | 'human' | 'json' | undefined;
|
|
81
|
+
runId: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Options for history trends command
|
|
86
|
+
*/
|
|
87
|
+
interface HistoryTrendsOptions extends BaseHistoryOptions {
|
|
88
|
+
all?: boolean | undefined;
|
|
89
|
+
format?: 'human' | 'json' | undefined;
|
|
90
|
+
limit?: number | undefined;
|
|
91
|
+
pattern?: string | undefined;
|
|
92
|
+
since?: string | undefined;
|
|
93
|
+
tags?: string[] | undefined;
|
|
94
|
+
until?: string | undefined;
|
|
95
|
+
}
|
|
72
96
|
|
|
73
97
|
/**
|
|
74
98
|
* Format bytes in human-readable format
|
|
@@ -86,12 +110,38 @@ const formatBytes = (bytes: number): string => {
|
|
|
86
110
|
return `${size.toFixed(1)} ${units[unitIndex]}`;
|
|
87
111
|
};
|
|
88
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Resolve a partial run ID to a full ID by checking prefix match
|
|
115
|
+
*
|
|
116
|
+
* Supports Git-style partial ID matching (e.g., "k3m" matches "k3m9x2p")
|
|
117
|
+
*/
|
|
118
|
+
const resolveRunId = async (
|
|
119
|
+
storage: HistoryStorage,
|
|
120
|
+
partialId: string,
|
|
121
|
+
): Promise<null | string> => {
|
|
122
|
+
// First try exact match
|
|
123
|
+
const exactRun = await storage.loadRun(partialId);
|
|
124
|
+
if (exactRun) {
|
|
125
|
+
return partialId;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Query all runs to find a prefix match
|
|
129
|
+
const allRuns = await storage.queryRuns({});
|
|
130
|
+
|
|
131
|
+
const prefixMatch = allRuns.find((run) => run.id.startsWith(partialId));
|
|
132
|
+
if (prefixMatch) {
|
|
133
|
+
return prefixMatch.id;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return null;
|
|
137
|
+
};
|
|
138
|
+
|
|
89
139
|
/**
|
|
90
140
|
* Handle the clean subcommand
|
|
91
141
|
*/
|
|
92
|
-
const handleCleanCommand = async (
|
|
142
|
+
export const handleCleanCommand = async (
|
|
93
143
|
context: CliContext,
|
|
94
|
-
options:
|
|
144
|
+
options: HistoryCleanOptions,
|
|
95
145
|
): Promise<number> => {
|
|
96
146
|
try {
|
|
97
147
|
// Build retention policy from arguments
|
|
@@ -158,69 +208,38 @@ const handleCleanCommand = async (
|
|
|
158
208
|
/**
|
|
159
209
|
* Handle the compare subcommand
|
|
160
210
|
*/
|
|
161
|
-
const handleCompareCommand = async (
|
|
211
|
+
export const handleCompareCommand = async (
|
|
162
212
|
context: CliContext,
|
|
163
|
-
options:
|
|
213
|
+
options: HistoryCompareOptions,
|
|
164
214
|
): Promise<number> => {
|
|
165
215
|
try {
|
|
166
|
-
// For compare command, IDs come from args after the subcommand
|
|
167
|
-
const id1 = options.args?.[0];
|
|
168
|
-
const id2 = options.args?.[1];
|
|
169
|
-
|
|
170
|
-
if (!id1 || !id2) {
|
|
171
|
-
console.error('Two run IDs are required for compare command');
|
|
172
|
-
console.error('Usage: modestbench history compare <run-id1> <run-id2>');
|
|
173
|
-
return 2;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
216
|
const [run1, run2] = await Promise.all([
|
|
177
|
-
context.historyStorage.loadRun(
|
|
178
|
-
context.historyStorage.loadRun(
|
|
217
|
+
context.historyStorage.loadRun(options.runId1),
|
|
218
|
+
context.historyStorage.loadRun(options.runId2),
|
|
179
219
|
]);
|
|
180
220
|
|
|
181
221
|
if (!run1) {
|
|
182
|
-
console.error(`Run not found: ${
|
|
222
|
+
console.error(`Run not found: ${options.runId1}`);
|
|
183
223
|
return 1;
|
|
184
224
|
}
|
|
185
225
|
|
|
186
226
|
if (!run2) {
|
|
187
|
-
console.error(`Run not found: ${
|
|
227
|
+
console.error(`Run not found: ${options.runId2}`);
|
|
188
228
|
return 1;
|
|
189
229
|
}
|
|
190
230
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
run2: { id: run2.id, summary: run2.summary },
|
|
195
|
-
// TODO: Add detailed comparison logic
|
|
196
|
-
};
|
|
197
|
-
console.log(JSON.stringify(comparison, null, 2));
|
|
198
|
-
} else {
|
|
199
|
-
// Human format comparison
|
|
200
|
-
console.log(`Comparing runs:`);
|
|
201
|
-
console.log(` Run 1: ${run1.id} (${run1.startTime.toLocaleString()})`);
|
|
202
|
-
console.log(` Run 2: ${run2.id} (${run2.startTime.toLocaleString()})`);
|
|
203
|
-
console.log();
|
|
231
|
+
// Compare using service
|
|
232
|
+
const comparisonService = new ComparisonService();
|
|
233
|
+
const result = comparisonService.compareRuns(run1, run2);
|
|
204
234
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
);
|
|
212
|
-
console.log(
|
|
213
|
-
` Passed: ${run1.summary.passedTasks} vs ${run2.summary.passedTasks}`,
|
|
214
|
-
);
|
|
215
|
-
console.log(
|
|
216
|
-
` Failed: ${run1.summary.failedTasks} vs ${run2.summary.failedTasks}`,
|
|
217
|
-
);
|
|
218
|
-
|
|
219
|
-
// TODO: Add detailed performance comparison
|
|
220
|
-
console.log();
|
|
221
|
-
console.log('Note: Detailed performance comparison not yet implemented.');
|
|
222
|
-
}
|
|
235
|
+
// Format output
|
|
236
|
+
const formatter = new HistoryCompareFormatter();
|
|
237
|
+
const output =
|
|
238
|
+
options.format === 'json'
|
|
239
|
+
? formatter.formatJson(result)
|
|
240
|
+
: formatter.formatHuman(result);
|
|
223
241
|
|
|
242
|
+
console.log(output);
|
|
224
243
|
return 0;
|
|
225
244
|
} catch (error) {
|
|
226
245
|
console.error(
|
|
@@ -234,9 +253,9 @@ const handleCompareCommand = async (
|
|
|
234
253
|
/**
|
|
235
254
|
* Handle the export subcommand
|
|
236
255
|
*/
|
|
237
|
-
const handleExportCommand = async (
|
|
256
|
+
export const handleExportCommand = async (
|
|
238
257
|
context: CliContext,
|
|
239
|
-
options:
|
|
258
|
+
options: HistoryExportOptions,
|
|
240
259
|
): Promise<number> => {
|
|
241
260
|
try {
|
|
242
261
|
const format = options.format || 'json';
|
|
@@ -247,21 +266,13 @@ const handleExportCommand = async (
|
|
|
247
266
|
...(options.until && { until: parseDate(options.until) }),
|
|
248
267
|
} as Partial<HistoryQuery>;
|
|
249
268
|
|
|
250
|
-
const exportData = await context.historyStorage.export(
|
|
251
|
-
format as 'csv' | 'json',
|
|
252
|
-
query,
|
|
253
|
-
);
|
|
269
|
+
const exportData = await context.historyStorage.export(format, query);
|
|
254
270
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
console.log(`Exported history to ${options.outputDir}`);
|
|
261
|
-
}
|
|
262
|
-
} else {
|
|
263
|
-
// Write to stdout
|
|
264
|
-
console.log(exportData);
|
|
271
|
+
// Write to file
|
|
272
|
+
const fs = await import('node:fs/promises');
|
|
273
|
+
await fs.writeFile(options.outputPath, exportData, 'utf8');
|
|
274
|
+
if (!options.quiet) {
|
|
275
|
+
console.log(`Exported history to ${options.outputPath}`);
|
|
265
276
|
}
|
|
266
277
|
|
|
267
278
|
return 0;
|
|
@@ -277,110 +288,39 @@ const handleExportCommand = async (
|
|
|
277
288
|
/**
|
|
278
289
|
* Handle the list subcommand
|
|
279
290
|
*/
|
|
280
|
-
const handleListCommand = async (
|
|
291
|
+
export const handleListCommand = async (
|
|
281
292
|
context: CliContext,
|
|
282
|
-
options:
|
|
293
|
+
options: HistoryListOptions,
|
|
283
294
|
): Promise<number> => {
|
|
284
295
|
try {
|
|
285
|
-
//
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
parsedUntil = parseDate(options.until);
|
|
304
|
-
} catch (error) {
|
|
305
|
-
console.error(
|
|
306
|
-
'Invalid until date:',
|
|
307
|
-
error instanceof Error ? error.message : String(error),
|
|
308
|
-
);
|
|
309
|
-
return 2; // Invalid date format
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
const query = {
|
|
314
|
-
...(parsedSince && { since: parsedSince }),
|
|
315
|
-
...(parsedUntil && { until: parsedUntil }),
|
|
316
|
-
...(options.pattern && { pattern: options.pattern }),
|
|
317
|
-
...(options.tags && options.tags.length > 0 && { tags: options.tags }),
|
|
318
|
-
...(options.limit && { limit: options.limit }),
|
|
319
|
-
} as Partial<HistoryQuery>;
|
|
296
|
+
// Query runs using service
|
|
297
|
+
const queryService = new HistoryQueryService(context.historyStorage);
|
|
298
|
+
const runs = await queryService.queryWithDateParsing(options);
|
|
299
|
+
|
|
300
|
+
// Transform to result format
|
|
301
|
+
const result = {
|
|
302
|
+
runs: runs.map((run) => ({
|
|
303
|
+
duration: run.duration,
|
|
304
|
+
id: run.id,
|
|
305
|
+
startTime: run.startTime,
|
|
306
|
+
summary: run.summary,
|
|
307
|
+
})),
|
|
308
|
+
totalCount: runs.length,
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
// Format output
|
|
312
|
+
const formatter = new HistoryListFormatter();
|
|
313
|
+
let output: string;
|
|
320
314
|
|
|
321
|
-
// Query historical runs
|
|
322
|
-
const runs = await context.historyStorage.queryRuns(query);
|
|
323
|
-
|
|
324
|
-
// Display results based on format
|
|
325
315
|
if (options.format === 'json') {
|
|
326
|
-
|
|
327
|
-
console.log('[]'); // Empty JSON array for no data
|
|
328
|
-
} else {
|
|
329
|
-
console.log(
|
|
330
|
-
JSON.stringify(
|
|
331
|
-
runs.map((run) => ({
|
|
332
|
-
duration: run.duration,
|
|
333
|
-
failed: run.summary.failedTasks,
|
|
334
|
-
files: run.summary.totalFiles,
|
|
335
|
-
id: run.id,
|
|
336
|
-
passed: run.summary.passedTasks,
|
|
337
|
-
startTime: run.startTime,
|
|
338
|
-
tasks: run.summary.totalTasks,
|
|
339
|
-
})),
|
|
340
|
-
null,
|
|
341
|
-
2,
|
|
342
|
-
),
|
|
343
|
-
);
|
|
344
|
-
}
|
|
316
|
+
output = formatter.formatJson(result);
|
|
345
317
|
} else if (options.format === 'csv') {
|
|
346
|
-
|
|
347
|
-
if (runs.length > 0) {
|
|
348
|
-
for (const run of runs) {
|
|
349
|
-
console.log(
|
|
350
|
-
`${run.id},${run.startTime.toISOString()},${run.duration},${run.summary.totalFiles},${run.summary.totalTasks},${run.summary.passedTasks},${run.summary.failedTasks}`,
|
|
351
|
-
);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
// For CSV, no additional message needed - header is sufficient
|
|
318
|
+
output = formatter.formatCsv(result);
|
|
355
319
|
} else {
|
|
356
|
-
|
|
357
|
-
if (runs.length === 0) {
|
|
358
|
-
if (!options.quiet) {
|
|
359
|
-
console.log('No historical data found matching criteria.');
|
|
360
|
-
}
|
|
361
|
-
} else {
|
|
362
|
-
console.log('Recent benchmark runs:');
|
|
363
|
-
console.log();
|
|
364
|
-
|
|
365
|
-
for (const run of runs) {
|
|
366
|
-
const dateStr = run.startTime.toLocaleString();
|
|
367
|
-
const durationStr = `${(run.duration / 1000).toFixed(1)}s`;
|
|
368
|
-
const statusStr =
|
|
369
|
-
run.summary.failedTasks > 0
|
|
370
|
-
? `${run.summary.passedTasks} passed, ${run.summary.failedTasks} failed`
|
|
371
|
-
: `${run.summary.passedTasks} passed`;
|
|
372
|
-
|
|
373
|
-
console.log(
|
|
374
|
-
` ${run.id.substring(0, 8)} - ${dateStr} (${durationStr})`,
|
|
375
|
-
);
|
|
376
|
-
console.log(
|
|
377
|
-
` ${run.summary.totalFiles} files, ${run.summary.totalTasks} tasks: ${statusStr}`,
|
|
378
|
-
);
|
|
379
|
-
console.log();
|
|
380
|
-
}
|
|
381
|
-
}
|
|
320
|
+
output = formatter.formatHuman(result);
|
|
382
321
|
}
|
|
383
322
|
|
|
323
|
+
console.log(output);
|
|
384
324
|
return 0;
|
|
385
325
|
} catch (error) {
|
|
386
326
|
console.error(
|
|
@@ -394,68 +334,34 @@ const handleListCommand = async (
|
|
|
394
334
|
/**
|
|
395
335
|
* Handle the show subcommand
|
|
396
336
|
*/
|
|
397
|
-
const handleShowCommand = async (
|
|
337
|
+
export const handleShowCommand = async (
|
|
398
338
|
context: CliContext,
|
|
399
|
-
options:
|
|
339
|
+
options: HistoryShowOptions,
|
|
400
340
|
): Promise<number> => {
|
|
401
341
|
try {
|
|
402
|
-
//
|
|
403
|
-
const
|
|
342
|
+
// Resolve partial ID to full ID
|
|
343
|
+
const fullRunId = await resolveRunId(context.historyStorage, options.runId);
|
|
404
344
|
|
|
405
|
-
if (!
|
|
406
|
-
console.error(
|
|
407
|
-
|
|
408
|
-
return 2;
|
|
345
|
+
if (!fullRunId) {
|
|
346
|
+
console.error(`Run not found: ${options.runId}`);
|
|
347
|
+
return 1;
|
|
409
348
|
}
|
|
410
349
|
|
|
411
|
-
const run = await context.historyStorage.loadRun(
|
|
350
|
+
const run = await context.historyStorage.loadRun(fullRunId);
|
|
412
351
|
|
|
413
352
|
if (!run) {
|
|
414
|
-
console.error(`Run not found: ${runId}`);
|
|
353
|
+
console.error(`Run not found: ${options.runId}`);
|
|
415
354
|
return 1;
|
|
416
355
|
}
|
|
417
356
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
console.log(`Duration: ${(run.duration / 1000).toFixed(1)}s`);
|
|
425
|
-
console.log(
|
|
426
|
-
`Environment: Node.js ${run.environment.nodeVersion} on ${run.environment.platform}`,
|
|
427
|
-
);
|
|
428
|
-
|
|
429
|
-
if (run.git) {
|
|
430
|
-
console.log(`Git: ${run.git.branch}@${run.git.commit.substring(0, 8)}`);
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
console.log();
|
|
434
|
-
console.log('Summary:');
|
|
435
|
-
console.log(` Files: ${run.summary.totalFiles}`);
|
|
436
|
-
console.log(` Suites: ${run.summary.totalSuites}`);
|
|
437
|
-
console.log(` Tasks: ${run.summary.totalTasks}`);
|
|
438
|
-
console.log(` Passed: ${run.summary.passedTasks}`);
|
|
439
|
-
console.log(` Failed: ${run.summary.failedTasks}`);
|
|
440
|
-
|
|
441
|
-
// TODO: Show detailed file/suite/task results
|
|
442
|
-
console.log();
|
|
443
|
-
console.log('Detailed results:');
|
|
444
|
-
for (const file of run.files) {
|
|
445
|
-
console.log(` 📁 ${file.filePath}`);
|
|
446
|
-
for (const suite of file.suites) {
|
|
447
|
-
console.log(` 📊 ${suite.name}`);
|
|
448
|
-
for (const task of suite.tasks) {
|
|
449
|
-
const status = task.error ? '❌' : '✅';
|
|
450
|
-
const timing = task.error
|
|
451
|
-
? 'failed'
|
|
452
|
-
: `${(task.mean / 1000000).toFixed(2)}ms`;
|
|
453
|
-
console.log(` ${status} ${task.name} - ${timing}`);
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
}
|
|
357
|
+
// Format output
|
|
358
|
+
const formatter = new HistoryShowFormatter();
|
|
359
|
+
const output =
|
|
360
|
+
options.format === 'json'
|
|
361
|
+
? formatter.formatJson(run)
|
|
362
|
+
: formatter.formatHuman(run);
|
|
458
363
|
|
|
364
|
+
console.log(output);
|
|
459
365
|
return 0;
|
|
460
366
|
} catch (error) {
|
|
461
367
|
console.error(
|
|
@@ -469,101 +375,49 @@ const handleShowCommand = async (
|
|
|
469
375
|
/**
|
|
470
376
|
* Handle the trends subcommand
|
|
471
377
|
*/
|
|
472
|
-
const handleTrendsCommand = async (
|
|
378
|
+
export const handleTrendsCommand = async (
|
|
473
379
|
context: CliContext,
|
|
474
|
-
options:
|
|
380
|
+
options: HistoryTrendsOptions,
|
|
475
381
|
): Promise<number> => {
|
|
476
382
|
try {
|
|
477
|
-
//
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
'Invalid since date:',
|
|
487
|
-
error instanceof Error ? error.message : String(error),
|
|
488
|
-
);
|
|
489
|
-
return 2; // Invalid date format
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
if (options.until) {
|
|
494
|
-
try {
|
|
495
|
-
parsedUntil = parseDate(options.until);
|
|
496
|
-
} catch (error) {
|
|
497
|
-
console.error(
|
|
498
|
-
'Invalid until date:',
|
|
499
|
-
error instanceof Error ? error.message : String(error),
|
|
500
|
-
);
|
|
501
|
-
return 2; // Invalid date format
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
// Get pattern from args or explicit pattern option
|
|
506
|
-
const pattern = options.args?.[0] || options.pattern;
|
|
507
|
-
|
|
508
|
-
const query = {
|
|
509
|
-
...(parsedSince && { since: parsedSince }),
|
|
510
|
-
...(parsedUntil && { until: parsedUntil }),
|
|
511
|
-
...(pattern && { pattern }),
|
|
512
|
-
...(options.tags && options.tags.length > 0 && { tags: options.tags }),
|
|
513
|
-
...(options.limit && { limit: options.limit }),
|
|
514
|
-
} as Partial<HistoryQuery>;
|
|
515
|
-
|
|
516
|
-
// Query historical runs
|
|
517
|
-
const runs = await context.historyStorage.queryRuns(query);
|
|
383
|
+
// Query runs using service
|
|
384
|
+
const queryService = new HistoryQueryService(context.historyStorage);
|
|
385
|
+
const runs = await queryService.queryWithDateParsing({
|
|
386
|
+
limit: options.all ? undefined : options.limit,
|
|
387
|
+
pattern: options.pattern,
|
|
388
|
+
since: options.since,
|
|
389
|
+
tags: options.tags,
|
|
390
|
+
until: options.until,
|
|
391
|
+
});
|
|
518
392
|
|
|
519
393
|
if (runs.length === 0) {
|
|
520
394
|
if (!options.quiet) {
|
|
521
395
|
console.log('No historical data found matching criteria');
|
|
522
396
|
}
|
|
523
|
-
return 0;
|
|
397
|
+
return 0;
|
|
524
398
|
}
|
|
525
399
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
if (!options.quiet) {
|
|
540
|
-
console.log(`Performance trends for ${runs.length} runs:`);
|
|
541
|
-
console.log(
|
|
542
|
-
`Time range: ${runs[runs.length - 1]?.startTime} to ${runs[0]?.startTime}`,
|
|
543
|
-
);
|
|
544
|
-
// TODO: Add trend analysis and visualization
|
|
545
|
-
console.log('(Trend analysis not yet implemented)');
|
|
546
|
-
}
|
|
400
|
+
// Analyze trends using service
|
|
401
|
+
const analysisService = new TrendAnalysisService();
|
|
402
|
+
const result = analysisService.analyzeTrends(runs);
|
|
403
|
+
|
|
404
|
+
// Format output
|
|
405
|
+
const formatter = new HistoryTrendsFormatter();
|
|
406
|
+
const output =
|
|
407
|
+
options.format === 'json'
|
|
408
|
+
? formatter.formatJson(result)
|
|
409
|
+
: formatter.formatHuman(result);
|
|
410
|
+
|
|
411
|
+
if (!options.quiet || options.format !== 'human') {
|
|
412
|
+
console.log(output);
|
|
547
413
|
}
|
|
548
414
|
|
|
549
|
-
return 0;
|
|
415
|
+
return 0;
|
|
550
416
|
} catch (error) {
|
|
551
|
-
console.error(
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
/**
|
|
557
|
-
* Parse date string (ISO 8601 or relative)
|
|
558
|
-
*/
|
|
559
|
-
const parseDate = (dateStr: string): Date => {
|
|
560
|
-
// Try parsing as ISO 8601 first
|
|
561
|
-
const isoDate = new Date(dateStr);
|
|
562
|
-
if (!isNaN(isoDate.getTime())) {
|
|
563
|
-
return isoDate;
|
|
417
|
+
console.error(
|
|
418
|
+
'Failed to show trends:',
|
|
419
|
+
error instanceof Error ? error.message : String(error),
|
|
420
|
+
);
|
|
421
|
+
return 5;
|
|
564
422
|
}
|
|
565
|
-
|
|
566
|
-
// TODO: Parse relative dates like "1 week ago", "3 days ago", etc.
|
|
567
|
-
// For now, throw error for invalid dates
|
|
568
|
-
throw new Error(`Invalid date format: "${dateStr}"`);
|
|
569
423
|
};
|