ppef 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +172 -0
- package/bin/ppef.mjs +20 -0
- package/dist/__tests__/framework-pipeline.integration.test.d.ts +7 -0
- package/dist/__tests__/framework-pipeline.integration.test.d.ts.map +1 -0
- package/dist/__tests__/framework-pipeline.integration.test.js +415 -0
- package/dist/__tests__/framework-pipeline.integration.test.js.map +1 -0
- package/dist/__tests__/index-exports.unit.test.d.ts +8 -0
- package/dist/__tests__/index-exports.unit.test.d.ts.map +1 -0
- package/dist/__tests__/index-exports.unit.test.js +127 -0
- package/dist/__tests__/index-exports.unit.test.js.map +1 -0
- package/dist/__tests__/registry-executor.integration.test.d.ts +5 -0
- package/dist/__tests__/registry-executor.integration.test.d.ts.map +1 -0
- package/dist/__tests__/registry-executor.integration.test.js +352 -0
- package/dist/__tests__/registry-executor.integration.test.js.map +1 -0
- package/dist/__tests__/test-helpers.d.ts +94 -0
- package/dist/__tests__/test-helpers.d.ts.map +1 -0
- package/dist/__tests__/test-helpers.js +271 -0
- package/dist/__tests__/test-helpers.js.map +1 -0
- package/dist/aggregation/__tests__/aggregators.unit.test.d.ts +7 -0
- package/dist/aggregation/__tests__/aggregators.unit.test.d.ts.map +1 -0
- package/dist/aggregation/__tests__/aggregators.unit.test.js +350 -0
- package/dist/aggregation/__tests__/aggregators.unit.test.js.map +1 -0
- package/dist/aggregation/__tests__/pipeline.unit.test.d.ts +7 -0
- package/dist/aggregation/__tests__/pipeline.unit.test.d.ts.map +1 -0
- package/dist/aggregation/__tests__/pipeline.unit.test.js +213 -0
- package/dist/aggregation/__tests__/pipeline.unit.test.js.map +1 -0
- package/dist/aggregation/aggregators.d.ts +63 -0
- package/dist/aggregation/aggregators.d.ts.map +1 -0
- package/dist/aggregation/aggregators.js +228 -0
- package/dist/aggregation/aggregators.js.map +1 -0
- package/dist/aggregation/index.d.ts +8 -0
- package/dist/aggregation/index.d.ts.map +1 -0
- package/dist/aggregation/index.js +8 -0
- package/dist/aggregation/index.js.map +1 -0
- package/dist/aggregation/pipeline.d.ts +38 -0
- package/dist/aggregation/pipeline.d.ts.map +1 -0
- package/dist/aggregation/pipeline.js +198 -0
- package/dist/aggregation/pipeline.js.map +1 -0
- package/dist/claims/__tests__/evaluator.unit.test.d.ts +12 -0
- package/dist/claims/__tests__/evaluator.unit.test.d.ts.map +1 -0
- package/dist/claims/__tests__/evaluator.unit.test.js +801 -0
- package/dist/claims/__tests__/evaluator.unit.test.js.map +1 -0
- package/dist/claims/evaluator.d.ts +33 -0
- package/dist/claims/evaluator.d.ts.map +1 -0
- package/dist/claims/evaluator.js +174 -0
- package/dist/claims/evaluator.js.map +1 -0
- package/dist/claims/index.d.ts +7 -0
- package/dist/claims/index.d.ts.map +1 -0
- package/dist/claims/index.js +7 -0
- package/dist/claims/index.js.map +1 -0
- package/dist/cli/__tests__/aggregate.command.unit.test.d.ts +7 -0
- package/dist/cli/__tests__/aggregate.command.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/aggregate.command.unit.test.js +396 -0
- package/dist/cli/__tests__/aggregate.command.unit.test.js.map +1 -0
- package/dist/cli/__tests__/commands.unit.test.d.ts +10 -0
- package/dist/cli/__tests__/commands.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/commands.unit.test.js +217 -0
- package/dist/cli/__tests__/commands.unit.test.js.map +1 -0
- package/dist/cli/__tests__/index.unit.test.d.ts +10 -0
- package/dist/cli/__tests__/index.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/index.unit.test.js +65 -0
- package/dist/cli/__tests__/index.unit.test.js.map +1 -0
- package/dist/cli/__tests__/logger.unit.test.d.ts +11 -0
- package/dist/cli/__tests__/logger.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/logger.unit.test.js +180 -0
- package/dist/cli/__tests__/logger.unit.test.js.map +1 -0
- package/dist/cli/__tests__/module-loader.unit.test.d.ts +11 -0
- package/dist/cli/__tests__/module-loader.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/module-loader.unit.test.js +262 -0
- package/dist/cli/__tests__/module-loader.unit.test.js.map +1 -0
- package/dist/cli/__tests__/output-writer.unit.test.d.ts +10 -0
- package/dist/cli/__tests__/output-writer.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/output-writer.unit.test.js +216 -0
- package/dist/cli/__tests__/output-writer.unit.test.js.map +1 -0
- package/dist/cli/__tests__/plan.command.unit.test.d.ts +7 -0
- package/dist/cli/__tests__/plan.command.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/plan.command.unit.test.js +289 -0
- package/dist/cli/__tests__/plan.command.unit.test.js.map +1 -0
- package/dist/cli/__tests__/run.command.unit.test.d.ts +7 -0
- package/dist/cli/__tests__/run.command.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/run.command.unit.test.js +422 -0
- package/dist/cli/__tests__/run.command.unit.test.js.map +1 -0
- package/dist/cli/__tests__/validate.command.unit.test.d.ts +7 -0
- package/dist/cli/__tests__/validate.command.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/validate.command.unit.test.js +226 -0
- package/dist/cli/__tests__/validate.command.unit.test.js.map +1 -0
- package/dist/cli/command-deps.d.ts +125 -0
- package/dist/cli/command-deps.d.ts.map +1 -0
- package/dist/cli/command-deps.js +7 -0
- package/dist/cli/command-deps.js.map +1 -0
- package/dist/cli/commands/aggregate.d.ts +35 -0
- package/dist/cli/commands/aggregate.d.ts.map +1 -0
- package/dist/cli/commands/aggregate.js +121 -0
- package/dist/cli/commands/aggregate.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +36 -0
- package/dist/cli/commands/plan.d.ts.map +1 -0
- package/dist/cli/commands/plan.js +109 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/run.d.ts +33 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +185 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +27 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +88 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/config-loader.d.ts +30 -0
- package/dist/cli/config-loader.d.ts.map +1 -0
- package/dist/cli/config-loader.js +181 -0
- package/dist/cli/config-loader.js.map +1 -0
- package/dist/cli/index.d.ts +26 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +58 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/logger.d.ts +75 -0
- package/dist/cli/logger.d.ts.map +1 -0
- package/dist/cli/logger.js +131 -0
- package/dist/cli/logger.js.map +1 -0
- package/dist/cli/module-loader.d.ts +46 -0
- package/dist/cli/module-loader.d.ts.map +1 -0
- package/dist/cli/module-loader.js +116 -0
- package/dist/cli/module-loader.js.map +1 -0
- package/dist/cli/output-writer.d.ts +51 -0
- package/dist/cli/output-writer.d.ts.map +1 -0
- package/dist/cli/output-writer.js +65 -0
- package/dist/cli/output-writer.js.map +1 -0
- package/dist/cli/types.d.ts +174 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +7 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/collector/__tests__/result-collector.unit.test.d.ts +7 -0
- package/dist/collector/__tests__/result-collector.unit.test.d.ts.map +1 -0
- package/dist/collector/__tests__/result-collector.unit.test.js +1021 -0
- package/dist/collector/__tests__/result-collector.unit.test.js.map +1 -0
- package/dist/collector/__tests__/schema.unit.test.d.ts +7 -0
- package/dist/collector/__tests__/schema.unit.test.d.ts.map +1 -0
- package/dist/collector/__tests__/schema.unit.test.js +360 -0
- package/dist/collector/__tests__/schema.unit.test.js.map +1 -0
- package/dist/collector/index.d.ts +8 -0
- package/dist/collector/index.d.ts.map +1 -0
- package/dist/collector/index.js +8 -0
- package/dist/collector/index.js.map +1 -0
- package/dist/collector/result-collector.d.ts +159 -0
- package/dist/collector/result-collector.d.ts.map +1 -0
- package/dist/collector/result-collector.js +213 -0
- package/dist/collector/result-collector.js.map +1 -0
- package/dist/collector/schema.d.ts +34 -0
- package/dist/collector/schema.d.ts.map +1 -0
- package/dist/collector/schema.js +145 -0
- package/dist/collector/schema.js.map +1 -0
- package/dist/executor/__tests__/checkpoint-hash-bug.diagnostic.test.d.ts +10 -0
- package/dist/executor/__tests__/checkpoint-hash-bug.diagnostic.test.d.ts.map +1 -0
- package/dist/executor/__tests__/checkpoint-hash-bug.diagnostic.test.js +122 -0
- package/dist/executor/__tests__/checkpoint-hash-bug.diagnostic.test.js.map +1 -0
- package/dist/executor/__tests__/checkpoint-manager.integration.test.d.ts +7 -0
- package/dist/executor/__tests__/checkpoint-manager.integration.test.d.ts.map +1 -0
- package/dist/executor/__tests__/checkpoint-manager.integration.test.js +330 -0
- package/dist/executor/__tests__/checkpoint-manager.integration.test.js.map +1 -0
- package/dist/executor/__tests__/checkpoint-manager.unit.test.d.ts +7 -0
- package/dist/executor/__tests__/checkpoint-manager.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/checkpoint-manager.unit.test.js +531 -0
- package/dist/executor/__tests__/checkpoint-manager.unit.test.js.map +1 -0
- package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.d.ts +8 -0
- package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.d.ts.map +1 -0
- package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.js +493 -0
- package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.js.map +1 -0
- package/dist/executor/__tests__/checkpoint-merge-bug.unit.test.d.ts +8 -0
- package/dist/executor/__tests__/checkpoint-merge-bug.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/checkpoint-merge-bug.unit.test.js +164 -0
- package/dist/executor/__tests__/checkpoint-merge-bug.unit.test.js.map +1 -0
- package/dist/executor/__tests__/checkpoint-storage.unit.test.d.ts +7 -0
- package/dist/executor/__tests__/checkpoint-storage.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/checkpoint-storage.unit.test.js +490 -0
- package/dist/executor/__tests__/checkpoint-storage.unit.test.js.map +1 -0
- package/dist/executor/__tests__/executor.unit.test.d.ts +7 -0
- package/dist/executor/__tests__/executor.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/executor.unit.test.js +202 -0
- package/dist/executor/__tests__/executor.unit.test.js.map +1 -0
- package/dist/executor/__tests__/memory-monitor.unit.test.d.ts +7 -0
- package/dist/executor/__tests__/memory-monitor.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/memory-monitor.unit.test.js +285 -0
- package/dist/executor/__tests__/memory-monitor.unit.test.js.map +1 -0
- package/dist/executor/__tests__/parallel-checkpoint-merge.integration.test.d.ts +12 -0
- package/dist/executor/__tests__/parallel-checkpoint-merge.integration.test.d.ts.map +1 -0
- package/dist/executor/__tests__/parallel-checkpoint-merge.integration.test.js +196 -0
- package/dist/executor/__tests__/parallel-checkpoint-merge.integration.test.js.map +1 -0
- package/dist/executor/__tests__/parallel-executor.integration.test.d.ts +7 -0
- package/dist/executor/__tests__/parallel-executor.integration.test.d.ts.map +1 -0
- package/dist/executor/__tests__/parallel-executor.integration.test.js +249 -0
- package/dist/executor/__tests__/parallel-executor.integration.test.js.map +1 -0
- package/dist/executor/__tests__/parallel-executor.unit.test.d.ts +8 -0
- package/dist/executor/__tests__/parallel-executor.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/parallel-executor.unit.test.js +473 -0
- package/dist/executor/__tests__/parallel-executor.unit.test.js.map +1 -0
- package/dist/executor/__tests__/run-id.unit.test.d.ts +8 -0
- package/dist/executor/__tests__/run-id.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/run-id.unit.test.js +156 -0
- package/dist/executor/__tests__/run-id.unit.test.js.map +1 -0
- package/dist/executor/__tests__/worker-entry.integration.test.d.ts +24 -0
- package/dist/executor/__tests__/worker-entry.integration.test.d.ts.map +1 -0
- package/dist/executor/__tests__/worker-entry.integration.test.js +82 -0
- package/dist/executor/__tests__/worker-entry.integration.test.js.map +1 -0
- package/dist/executor/__tests__/worker-entry.unit.test.d.ts +7 -0
- package/dist/executor/__tests__/worker-entry.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/worker-entry.unit.test.js +364 -0
- package/dist/executor/__tests__/worker-entry.unit.test.js.map +1 -0
- package/dist/executor/checkpoint-manager.d.ts +231 -0
- package/dist/executor/checkpoint-manager.d.ts.map +1 -0
- package/dist/executor/checkpoint-manager.js +395 -0
- package/dist/executor/checkpoint-manager.js.map +1 -0
- package/dist/executor/checkpoint-storage.d.ts +230 -0
- package/dist/executor/checkpoint-storage.d.ts.map +1 -0
- package/dist/executor/checkpoint-storage.js +370 -0
- package/dist/executor/checkpoint-storage.js.map +1 -0
- package/dist/executor/checkpoint-types.d.ts +48 -0
- package/dist/executor/checkpoint-types.d.ts.map +1 -0
- package/dist/executor/checkpoint-types.js +8 -0
- package/dist/executor/checkpoint-types.js.map +1 -0
- package/dist/executor/executor.d.ts +164 -0
- package/dist/executor/executor.d.ts.map +1 -0
- package/dist/executor/executor.js +408 -0
- package/dist/executor/executor.js.map +1 -0
- package/dist/executor/index.d.ts +11 -0
- package/dist/executor/index.d.ts.map +1 -0
- package/dist/executor/index.js +11 -0
- package/dist/executor/index.js.map +1 -0
- package/dist/executor/memory-monitor.d.ts +115 -0
- package/dist/executor/memory-monitor.d.ts.map +1 -0
- package/dist/executor/memory-monitor.js +168 -0
- package/dist/executor/memory-monitor.js.map +1 -0
- package/dist/executor/parallel-executor.d.ts +239 -0
- package/dist/executor/parallel-executor.d.ts.map +1 -0
- package/dist/executor/parallel-executor.js +329 -0
- package/dist/executor/parallel-executor.js.map +1 -0
- package/dist/executor/run-id.d.ts +71 -0
- package/dist/executor/run-id.d.ts.map +1 -0
- package/dist/executor/run-id.js +74 -0
- package/dist/executor/run-id.js.map +1 -0
- package/dist/executor/worker-entry.d.ts +10 -0
- package/dist/executor/worker-entry.d.ts.map +1 -0
- package/dist/executor/worker-entry.js +42 -0
- package/dist/executor/worker-entry.js.map +1 -0
- package/dist/executor/worker-executor.d.ts +156 -0
- package/dist/executor/worker-executor.d.ts.map +1 -0
- package/dist/executor/worker-executor.js +88 -0
- package/dist/executor/worker-executor.js.map +1 -0
- package/dist/index.cjs +11 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/registry/case-registry.d.ts +113 -0
- package/dist/registry/case-registry.d.ts.map +1 -0
- package/dist/registry/case-registry.js +160 -0
- package/dist/registry/case-registry.js.map +1 -0
- package/dist/registry/index.d.ts +8 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +8 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/sut-registry.d.ts +96 -0
- package/dist/registry/sut-registry.d.ts.map +1 -0
- package/dist/registry/sut-registry.js +126 -0
- package/dist/registry/sut-registry.js.map +1 -0
- package/dist/renderers/index.d.ts +10 -0
- package/dist/renderers/index.d.ts.map +1 -0
- package/dist/renderers/index.js +9 -0
- package/dist/renderers/index.js.map +1 -0
- package/dist/renderers/latex-renderer.d.ts +84 -0
- package/dist/renderers/latex-renderer.d.ts.map +1 -0
- package/dist/renderers/latex-renderer.js +208 -0
- package/dist/renderers/latex-renderer.js.map +1 -0
- package/dist/renderers/types.d.ts +106 -0
- package/dist/renderers/types.d.ts.map +1 -0
- package/dist/renderers/types.js +23 -0
- package/dist/renderers/types.js.map +1 -0
- package/dist/robustness/__tests__/analyzer.unit.test.d.ts +11 -0
- package/dist/robustness/__tests__/analyzer.unit.test.d.ts.map +1 -0
- package/dist/robustness/__tests__/analyzer.unit.test.js +455 -0
- package/dist/robustness/__tests__/analyzer.unit.test.js.map +1 -0
- package/dist/robustness/__tests__/perturbations.unit.test.d.ts +11 -0
- package/dist/robustness/__tests__/perturbations.unit.test.d.ts.map +1 -0
- package/dist/robustness/__tests__/perturbations.unit.test.js +284 -0
- package/dist/robustness/__tests__/perturbations.unit.test.js.map +1 -0
- package/dist/robustness/analyzer.d.ts +61 -0
- package/dist/robustness/analyzer.d.ts.map +1 -0
- package/dist/robustness/analyzer.js +191 -0
- package/dist/robustness/analyzer.js.map +1 -0
- package/dist/robustness/index.d.ts +8 -0
- package/dist/robustness/index.d.ts.map +1 -0
- package/dist/robustness/index.js +8 -0
- package/dist/robustness/index.js.map +1 -0
- package/dist/robustness/perturbations.d.ts +46 -0
- package/dist/robustness/perturbations.d.ts.map +1 -0
- package/dist/robustness/perturbations.js +184 -0
- package/dist/robustness/perturbations.js.map +1 -0
- package/dist/statistical/__tests__/mann-whitney-u.unit.test.d.ts +7 -0
- package/dist/statistical/__tests__/mann-whitney-u.unit.test.d.ts.map +1 -0
- package/dist/statistical/__tests__/mann-whitney-u.unit.test.js +185 -0
- package/dist/statistical/__tests__/mann-whitney-u.unit.test.js.map +1 -0
- package/dist/statistical/index.d.ts +8 -0
- package/dist/statistical/index.d.ts.map +1 -0
- package/dist/statistical/index.js +8 -0
- package/dist/statistical/index.js.map +1 -0
- package/dist/statistical/mann-whitney-u.d.ts +62 -0
- package/dist/statistical/mann-whitney-u.d.ts.map +1 -0
- package/dist/statistical/mann-whitney-u.js +127 -0
- package/dist/statistical/mann-whitney-u.js.map +1 -0
- package/dist/types/aggregate.d.ts +124 -0
- package/dist/types/aggregate.d.ts.map +1 -0
- package/dist/types/aggregate.js +9 -0
- package/dist/types/aggregate.js.map +1 -0
- package/dist/types/case.d.ts +105 -0
- package/dist/types/case.d.ts.map +1 -0
- package/dist/types/case.js +10 -0
- package/dist/types/case.js.map +1 -0
- package/dist/types/claims.d.ts +122 -0
- package/dist/types/claims.d.ts.map +1 -0
- package/dist/types/claims.js +14 -0
- package/dist/types/claims.js.map +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/perturbation.d.ts +105 -0
- package/dist/types/perturbation.d.ts.map +1 -0
- package/dist/types/perturbation.js +9 -0
- package/dist/types/perturbation.js.map +1 -0
- package/dist/types/result.d.ts +150 -0
- package/dist/types/result.d.ts.map +1 -0
- package/dist/types/result.js +12 -0
- package/dist/types/result.js.map +1 -0
- package/dist/types/sut.d.ts +128 -0
- package/dist/types/sut.d.ts.map +1 -0
- package/dist/types/sut.js +12 -0
- package/dist/types/sut.js.map +1 -0
- package/package.json +290 -7
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config Loader
|
|
3
|
+
*
|
|
4
|
+
* Loads and validates experiment configuration from JSON files.
|
|
5
|
+
*/
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
7
|
+
import { resolve, dirname } from "node:path";
|
|
8
|
+
/**
|
|
9
|
+
* Load and parse experiment configuration from a JSON file.
|
|
10
|
+
*
|
|
11
|
+
* @param configPath - Path to config file (can be absolute or relative)
|
|
12
|
+
* @returns Loaded configuration with base directory
|
|
13
|
+
* @throws Error if file cannot be read or parsed
|
|
14
|
+
*/
|
|
15
|
+
export async function loadConfig(configPath) {
|
|
16
|
+
// Resolve absolute path
|
|
17
|
+
const absolutePath = resolve(configPath);
|
|
18
|
+
// Read and parse JSON
|
|
19
|
+
const content = await readFile(absolutePath, "utf-8");
|
|
20
|
+
const config = JSON.parse(content);
|
|
21
|
+
// Get base directory (for resolving module paths)
|
|
22
|
+
const baseDir = dirname(absolutePath);
|
|
23
|
+
return {
|
|
24
|
+
config,
|
|
25
|
+
baseDir,
|
|
26
|
+
configPath: absolutePath,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Validate experiment configuration.
|
|
31
|
+
*
|
|
32
|
+
* @param config - Configuration to validate
|
|
33
|
+
* @returns Validation result with errors and warnings
|
|
34
|
+
*/
|
|
35
|
+
export function validateConfig(config) {
|
|
36
|
+
const errors = [];
|
|
37
|
+
const warnings = [];
|
|
38
|
+
// Validate experiment metadata
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
40
|
+
if (!config.experiment?.name) {
|
|
41
|
+
errors.push("experiment.name is required");
|
|
42
|
+
}
|
|
43
|
+
// Validate executor config
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
45
|
+
if (!config.executor) {
|
|
46
|
+
errors.push("executor configuration is required");
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
if (config.executor.repetitions !== undefined && config.executor.repetitions < 1) {
|
|
50
|
+
errors.push("executor.repetitions must be at least 1");
|
|
51
|
+
}
|
|
52
|
+
if (config.executor.seedBase !== undefined && config.executor.seedBase < 0) {
|
|
53
|
+
errors.push("executor.seedBase must be non-negative");
|
|
54
|
+
}
|
|
55
|
+
if (config.executor.timeoutMs !== undefined && config.executor.timeoutMs < 0) {
|
|
56
|
+
errors.push("executor.timeoutMs must be non-negative");
|
|
57
|
+
}
|
|
58
|
+
if (config.executor.concurrency !== undefined && config.executor.concurrency < 1) {
|
|
59
|
+
errors.push("executor.concurrency must be at least 1");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Validate SUTs
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
64
|
+
if (!config.suts || config.suts.length === 0) {
|
|
65
|
+
warnings.push("No SUTs configured - experiment will have nothing to execute");
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
for (let i = 0; i < config.suts.length; i++) {
|
|
69
|
+
const sut = config.suts[i];
|
|
70
|
+
if (!sut.id) {
|
|
71
|
+
errors.push(`suts[${i}].id is required`);
|
|
72
|
+
}
|
|
73
|
+
if (!sut.module) {
|
|
74
|
+
errors.push(`suts[${i}].module is required`);
|
|
75
|
+
}
|
|
76
|
+
if (!sut.exportName) {
|
|
77
|
+
errors.push(`suts[${i}].exportName is required`);
|
|
78
|
+
}
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
80
|
+
if (!sut.registration?.name) {
|
|
81
|
+
errors.push(`suts[${i}].registration.name is required`);
|
|
82
|
+
}
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
84
|
+
if (!sut.registration?.version) {
|
|
85
|
+
errors.push(`suts[${i}].registration.version is required`);
|
|
86
|
+
}
|
|
87
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
88
|
+
if (!sut.registration?.role) {
|
|
89
|
+
errors.push(`suts[${i}].registration.role is required`);
|
|
90
|
+
}
|
|
91
|
+
else if (!["primary", "baseline", "oracle"].includes(sut.registration.role)) {
|
|
92
|
+
errors.push(`suts[${i}].registration.role must be one of: primary, baseline, oracle`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Check for duplicate SUT IDs
|
|
96
|
+
const sutIds = new Set();
|
|
97
|
+
for (const sut of config.suts) {
|
|
98
|
+
if (sut.id && sutIds.has(sut.id)) {
|
|
99
|
+
errors.push(`Duplicate SUT ID: ${sut.id}`);
|
|
100
|
+
}
|
|
101
|
+
sutIds.add(sut.id);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Validate cases
|
|
105
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
106
|
+
if (!config.cases || config.cases.length === 0) {
|
|
107
|
+
warnings.push("No cases configured - experiment will have nothing to execute");
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
for (let i = 0; i < config.cases.length; i++) {
|
|
111
|
+
const testCase = config.cases[i];
|
|
112
|
+
if (!testCase.id) {
|
|
113
|
+
errors.push(`cases[${i}].id is required`);
|
|
114
|
+
}
|
|
115
|
+
if (!testCase.module) {
|
|
116
|
+
errors.push(`cases[${i}].module is required`);
|
|
117
|
+
}
|
|
118
|
+
if (!testCase.exportName) {
|
|
119
|
+
errors.push(`cases[${i}].exportName is required`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Check for duplicate case IDs
|
|
123
|
+
const caseIds = new Set();
|
|
124
|
+
for (const testCase of config.cases) {
|
|
125
|
+
if (testCase.id && caseIds.has(testCase.id)) {
|
|
126
|
+
errors.push(`Duplicate case ID: ${testCase.id}`);
|
|
127
|
+
}
|
|
128
|
+
caseIds.add(testCase.id);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Validate metrics extractor
|
|
132
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
133
|
+
if (!config.metricsExtractor) {
|
|
134
|
+
errors.push("metricsExtractor configuration is required");
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
if (!config.metricsExtractor.module) {
|
|
138
|
+
errors.push("metricsExtractor.module is required");
|
|
139
|
+
}
|
|
140
|
+
if (!config.metricsExtractor.exportName) {
|
|
141
|
+
errors.push("metricsExtractor.exportName is required");
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Validate output config
|
|
145
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
146
|
+
if (!config.output) {
|
|
147
|
+
warnings.push("No output configuration specified - using defaults");
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
if (config.output.format && !["json", "json-pretty"].includes(config.output.format)) {
|
|
151
|
+
errors.push('output.format must be one of: "json", "json-pretty"');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
valid: errors.length === 0,
|
|
156
|
+
errors,
|
|
157
|
+
warnings,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Load and validate experiment configuration.
|
|
162
|
+
*
|
|
163
|
+
* @param configPath - Path to config file
|
|
164
|
+
* @returns Loaded and validated configuration
|
|
165
|
+
* @throws Error if validation fails
|
|
166
|
+
*/
|
|
167
|
+
export async function loadAndValidateConfig(configPath) {
|
|
168
|
+
const loaded = await loadConfig(configPath);
|
|
169
|
+
const validation = validateConfig(loaded.config);
|
|
170
|
+
if (!validation.valid) {
|
|
171
|
+
throw new Error(`Configuration validation failed:\n${validation.errors.map((e) => ` - ${e}`).join("\n")}`);
|
|
172
|
+
}
|
|
173
|
+
// Print warnings if any
|
|
174
|
+
if (validation.warnings.length > 0) {
|
|
175
|
+
for (const warning of validation.warnings) {
|
|
176
|
+
console.warn(`Warning: ${warning}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return loaded;
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=config-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../src/cli/config-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PPEF CLI
|
|
3
|
+
*
|
|
4
|
+
* Command-line interface for the Portable Programmatic Evaluation Framework.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import { registerAggregateCommand } from "./commands/aggregate.js";
|
|
8
|
+
import { registerPlanCommand } from "./commands/plan.js";
|
|
9
|
+
import { registerRunCommand } from "./commands/run.js";
|
|
10
|
+
import { registerValidateCommand } from "./commands/validate.js";
|
|
11
|
+
/**
|
|
12
|
+
* Create and configure the CLI program.
|
|
13
|
+
*
|
|
14
|
+
* This function is exported for testing purposes.
|
|
15
|
+
*
|
|
16
|
+
* @returns Configured Commander program
|
|
17
|
+
*/
|
|
18
|
+
export declare function createCliProgram(): Command;
|
|
19
|
+
/**
|
|
20
|
+
* Run the CLI and return exit code.
|
|
21
|
+
*
|
|
22
|
+
* @returns Exit code (0 for success, 1 for error)
|
|
23
|
+
*/
|
|
24
|
+
export declare function runCli(): Promise<number>;
|
|
25
|
+
export { registerAggregateCommand, registerPlanCommand, registerRunCommand, registerValidateCommand, };
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEjE;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAe1C;AAED;;;;GAIG;AACH,wBAAsB,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAS9C;AAiBD,OAAO,EACN,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAClB,uBAAuB,GACvB,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PPEF CLI
|
|
3
|
+
*
|
|
4
|
+
* Command-line interface for the Portable Programmatic Evaluation Framework.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import { registerAggregateCommand } from "./commands/aggregate.js";
|
|
8
|
+
import { registerPlanCommand } from "./commands/plan.js";
|
|
9
|
+
import { registerRunCommand } from "./commands/run.js";
|
|
10
|
+
import { registerValidateCommand } from "./commands/validate.js";
|
|
11
|
+
/**
|
|
12
|
+
* Create and configure the CLI program.
|
|
13
|
+
*
|
|
14
|
+
* This function is exported for testing purposes.
|
|
15
|
+
*
|
|
16
|
+
* @returns Configured Commander program
|
|
17
|
+
*/
|
|
18
|
+
export function createCliProgram() {
|
|
19
|
+
const program = new Command();
|
|
20
|
+
program
|
|
21
|
+
.name("ppef")
|
|
22
|
+
.description("Portable Programmatic Evaluation Framework - CLI for experiment execution")
|
|
23
|
+
.version("1.0.1");
|
|
24
|
+
// Register commands
|
|
25
|
+
registerRunCommand(program);
|
|
26
|
+
registerValidateCommand(program);
|
|
27
|
+
registerPlanCommand(program);
|
|
28
|
+
registerAggregateCommand(program);
|
|
29
|
+
return program;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Run the CLI and return exit code.
|
|
33
|
+
*
|
|
34
|
+
* @returns Exit code (0 for success, 1 for error)
|
|
35
|
+
*/
|
|
36
|
+
export async function runCli() {
|
|
37
|
+
const program = createCliProgram();
|
|
38
|
+
try {
|
|
39
|
+
await program.parseAsync(process.argv);
|
|
40
|
+
return 0;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return 1;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Run CLI when executed directly (for development/testing).
|
|
48
|
+
*/
|
|
49
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
50
|
+
runCli().then((code) => {
|
|
51
|
+
process.exit(code);
|
|
52
|
+
}, (error) => {
|
|
53
|
+
console.error("Fatal error:", error);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
export { registerAggregateCommand, registerPlanCommand, registerRunCommand, registerValidateCommand, };
|
|
58
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEjE;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB;IAC/B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACL,IAAI,CAAC,MAAM,CAAC;SACZ,WAAW,CAAC,2EAA2E,CAAC;SACxF,OAAO,CAAC,OAAO,CAAC,CAAC;IAEnB,oBAAoB;IACpB,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAElC,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM;IAC3B,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IAEnC,IAAI,CAAC;QACJ,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvC,OAAO,CAAC,CAAC;IACV,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,CAAC,CAAC;IACV,CAAC;AACF,CAAC;AAED;;GAEG;AACH,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACrD,MAAM,EAAE,CAAC,IAAI,CACZ,CAAC,IAAI,EAAE,EAAE;QACR,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC,EACD,CAAC,KAAK,EAAE,EAAE;QACT,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC,CACD,CAAC;AACH,CAAC;AAED,OAAO,EACN,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAClB,uBAAuB,GACvB,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Logger
|
|
3
|
+
*
|
|
4
|
+
* Handles progress reporting, error messages, and output formatting.
|
|
5
|
+
*/
|
|
6
|
+
import type { ExecutionProgress } from "../executor/index.js";
|
|
7
|
+
/**
|
|
8
|
+
* Log level for controlling verbosity.
|
|
9
|
+
*/
|
|
10
|
+
export type LogLevel = "silent" | "error" | "warn" | "info" | "debug";
|
|
11
|
+
/**
|
|
12
|
+
* CLI logger for formatted output.
|
|
13
|
+
*/
|
|
14
|
+
export declare class CliLogger {
|
|
15
|
+
private readonly level;
|
|
16
|
+
private readonly quiet;
|
|
17
|
+
private showProgress;
|
|
18
|
+
private lastProgress;
|
|
19
|
+
constructor(options: {
|
|
20
|
+
verbose?: boolean;
|
|
21
|
+
quiet?: boolean;
|
|
22
|
+
});
|
|
23
|
+
/**
|
|
24
|
+
* Enable or disable progress bar updates.
|
|
25
|
+
*/
|
|
26
|
+
setProgress(enabled: boolean): void;
|
|
27
|
+
/**
|
|
28
|
+
* Log a debug message (only shown in verbose mode).
|
|
29
|
+
*/
|
|
30
|
+
debug(message: string): void;
|
|
31
|
+
/**
|
|
32
|
+
* Log an info message.
|
|
33
|
+
*/
|
|
34
|
+
info(message: string): void;
|
|
35
|
+
/**
|
|
36
|
+
* Log a warning message.
|
|
37
|
+
*/
|
|
38
|
+
warn(message: string): void;
|
|
39
|
+
/**
|
|
40
|
+
* Log an error message (always shown unless quiet).
|
|
41
|
+
*/
|
|
42
|
+
error(message: string): void;
|
|
43
|
+
/**
|
|
44
|
+
* Log execution progress.
|
|
45
|
+
*/
|
|
46
|
+
progress(progress: ExecutionProgress): void;
|
|
47
|
+
/**
|
|
48
|
+
* Clear the current progress line.
|
|
49
|
+
*/
|
|
50
|
+
clearProgress(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Log a header section.
|
|
53
|
+
*/
|
|
54
|
+
header(title: string): void;
|
|
55
|
+
/**
|
|
56
|
+
* Log a sub-header.
|
|
57
|
+
*/
|
|
58
|
+
subheader(title: string): void;
|
|
59
|
+
/**
|
|
60
|
+
* Create a progress reporter callback for the executor.
|
|
61
|
+
*/
|
|
62
|
+
createProgressReporter(): (progress: ExecutionProgress) => void;
|
|
63
|
+
/**
|
|
64
|
+
* Internal log method.
|
|
65
|
+
*/
|
|
66
|
+
private log;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Create a default logger instance.
|
|
70
|
+
*/
|
|
71
|
+
export declare function createLogger(options?: {
|
|
72
|
+
verbose?: boolean;
|
|
73
|
+
quiet?: boolean;
|
|
74
|
+
}): CliLogger;
|
|
75
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/cli/logger.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEtE;;GAEG;AACH,qBAAa,SAAS;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAChC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAAM;gBAEd,OAAO,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;IAK3D;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAInC;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAM5B;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAM3B;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAM3B;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAM5B;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IA0B3C;;OAEG;IACH,aAAa,IAAI,IAAI;IAOrB;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAQ3B;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAO9B;;OAEG;IACH,sBAAsB,IAAI,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI;IAM/D;;OAEG;IACH,OAAO,CAAC,GAAG;CAKX;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,SAAS,CAE5F"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Logger
|
|
3
|
+
*
|
|
4
|
+
* Handles progress reporting, error messages, and output formatting.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* CLI logger for formatted output.
|
|
8
|
+
*/
|
|
9
|
+
export class CliLogger {
|
|
10
|
+
level;
|
|
11
|
+
quiet;
|
|
12
|
+
showProgress = false;
|
|
13
|
+
lastProgress = "";
|
|
14
|
+
constructor(options) {
|
|
15
|
+
this.quiet = options.quiet ?? false;
|
|
16
|
+
this.level = options.verbose ? "debug" : this.quiet ? "silent" : "info";
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Enable or disable progress bar updates.
|
|
20
|
+
*/
|
|
21
|
+
setProgress(enabled) {
|
|
22
|
+
this.showProgress = enabled;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Log a debug message (only shown in verbose mode).
|
|
26
|
+
*/
|
|
27
|
+
debug(message) {
|
|
28
|
+
if (this.level === "debug") {
|
|
29
|
+
this.log(`[DEBUG] ${message}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Log an info message.
|
|
34
|
+
*/
|
|
35
|
+
info(message) {
|
|
36
|
+
if (this.level !== "silent") {
|
|
37
|
+
this.log(message);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Log a warning message.
|
|
42
|
+
*/
|
|
43
|
+
warn(message) {
|
|
44
|
+
if (this.level !== "silent") {
|
|
45
|
+
this.log(`Warning: ${message}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Log an error message (always shown unless quiet).
|
|
50
|
+
*/
|
|
51
|
+
error(message) {
|
|
52
|
+
if (this.level !== "silent") {
|
|
53
|
+
this.log(`Error: ${message}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Log execution progress.
|
|
58
|
+
*/
|
|
59
|
+
progress(progress) {
|
|
60
|
+
if (!this.showProgress || this.level === "silent") {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const percentage = Math.round((progress.completed / progress.total) * 100);
|
|
64
|
+
const currentSut = progress.currentSut ?? "unknown";
|
|
65
|
+
const currentCase = progress.currentCase ?? "unknown";
|
|
66
|
+
const currentRep = progress.currentRepetition ?? 0;
|
|
67
|
+
const elapsed = Math.round(progress.elapsedMs / 1000);
|
|
68
|
+
const message = `[${percentage}%] ${currentSut} / ${currentCase} (rep ${currentRep + 1}) - ${elapsed}s`;
|
|
69
|
+
// Only update if message changed (avoid flickering)
|
|
70
|
+
if (message !== this.lastProgress) {
|
|
71
|
+
// Use carriage return to overwrite line
|
|
72
|
+
process.stdout.write(`\r${message.padEnd(80)}`);
|
|
73
|
+
this.lastProgress = message;
|
|
74
|
+
}
|
|
75
|
+
// New line when complete
|
|
76
|
+
if (progress.completed >= progress.total) {
|
|
77
|
+
process.stdout.write("\n");
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Clear the current progress line.
|
|
82
|
+
*/
|
|
83
|
+
clearProgress() {
|
|
84
|
+
if (this.lastProgress) {
|
|
85
|
+
process.stdout.write("\r" + " ".repeat(80) + "\r");
|
|
86
|
+
this.lastProgress = "";
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Log a header section.
|
|
91
|
+
*/
|
|
92
|
+
header(title) {
|
|
93
|
+
if (this.level === "silent") {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
this.log("");
|
|
97
|
+
this.log(`=== ${title} ===`);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Log a sub-header.
|
|
101
|
+
*/
|
|
102
|
+
subheader(title) {
|
|
103
|
+
if (this.level === "silent") {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
this.log(`--- ${title}`);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Create a progress reporter callback for the executor.
|
|
110
|
+
*/
|
|
111
|
+
createProgressReporter() {
|
|
112
|
+
return (progress) => {
|
|
113
|
+
this.progress(progress);
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Internal log method.
|
|
118
|
+
*/
|
|
119
|
+
log(message) {
|
|
120
|
+
// Clear progress line before logging
|
|
121
|
+
this.clearProgress();
|
|
122
|
+
console.log(message);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Create a default logger instance.
|
|
127
|
+
*/
|
|
128
|
+
export function createLogger(options = {}) {
|
|
129
|
+
return new CliLogger(options);
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/cli/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module Loader
|
|
3
|
+
*
|
|
4
|
+
* Dynamically loads JavaScript/TypeScript modules containing SUT factories,
|
|
5
|
+
* case definitions, and metrics extractors.
|
|
6
|
+
*/
|
|
7
|
+
import type { CaseDefinition, SutDefinition } from "../types/index.js";
|
|
8
|
+
/**
|
|
9
|
+
* Load a SUT factory from a module.
|
|
10
|
+
*
|
|
11
|
+
* @param modulePath - Path to module file
|
|
12
|
+
* @param exportName - Name of the export to use
|
|
13
|
+
* @param baseDir - Base directory for resolving paths
|
|
14
|
+
* @returns SUT definition ready for registration
|
|
15
|
+
* @throws Error if export cannot be found or loaded
|
|
16
|
+
*/
|
|
17
|
+
export declare function loadSutFactory(modulePath: string, exportName: string, baseDir: string, registration: {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
version: string;
|
|
21
|
+
role: "primary" | "baseline" | "oracle";
|
|
22
|
+
config: Readonly<Record<string, unknown>>;
|
|
23
|
+
tags: readonly string[];
|
|
24
|
+
description?: string;
|
|
25
|
+
}, config?: Record<string, unknown>): Promise<SutDefinition>;
|
|
26
|
+
/**
|
|
27
|
+
* Load a case definition from a module.
|
|
28
|
+
*
|
|
29
|
+
* @param modulePath - Path to module file
|
|
30
|
+
* @param exportName - Name of the export to use
|
|
31
|
+
* @param baseDir - Base directory for resolving paths
|
|
32
|
+
* @returns Case definition ready for use
|
|
33
|
+
* @throws Error if export cannot be found or loaded
|
|
34
|
+
*/
|
|
35
|
+
export declare function loadCaseDefinition(modulePath: string, exportName: string, baseDir: string): Promise<CaseDefinition>;
|
|
36
|
+
/**
|
|
37
|
+
* Load a metrics extractor from a module.
|
|
38
|
+
*
|
|
39
|
+
* @param modulePath - Path to module file
|
|
40
|
+
* @param exportName - Name of the export to use
|
|
41
|
+
* @param baseDir - Base directory for resolving paths
|
|
42
|
+
* @returns Metrics extractor function
|
|
43
|
+
* @throws Error if export cannot be found or loaded
|
|
44
|
+
*/
|
|
45
|
+
export declare function loadMetricsExtractor(modulePath: string, exportName: string, baseDir: string): Promise<(result: unknown) => Record<string, number>>;
|
|
46
|
+
//# sourceMappingURL=module-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-loader.d.ts","sourceRoot":"","sources":["../../src/cli/module-loader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AA8BvE;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CACnC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;IACxC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1C,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB,EACD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,aAAa,CAAC,CA+BxB;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACvC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,cAAc,CAAC,CAqCzB;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACzC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAYtD"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module Loader
|
|
3
|
+
*
|
|
4
|
+
* Dynamically loads JavaScript/TypeScript modules containing SUT factories,
|
|
5
|
+
* case definitions, and metrics extractors.
|
|
6
|
+
*/
|
|
7
|
+
import { resolve } from "node:path";
|
|
8
|
+
import { pathToFileURL } from "node:url";
|
|
9
|
+
/**
|
|
10
|
+
* Load a module from a file path.
|
|
11
|
+
*
|
|
12
|
+
* @param modulePath - Path to module file (relative to base directory)
|
|
13
|
+
* @param baseDir - Base directory for resolving relative paths
|
|
14
|
+
* @returns Loaded module exports
|
|
15
|
+
* @throws Error if module cannot be loaded
|
|
16
|
+
*/
|
|
17
|
+
async function loadModule(modulePath, baseDir) {
|
|
18
|
+
const absolutePath = resolve(baseDir, modulePath);
|
|
19
|
+
// Use import with file:// URL for proper ESM support
|
|
20
|
+
const moduleUrl = pathToFileURL(absolutePath).href;
|
|
21
|
+
try {
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
23
|
+
const module = await import(moduleUrl);
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
25
|
+
return module;
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
if (error instanceof Error) {
|
|
29
|
+
throw new Error(`Failed to load module from ${modulePath}: ${error.message}`);
|
|
30
|
+
}
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Load a SUT factory from a module.
|
|
36
|
+
*
|
|
37
|
+
* @param modulePath - Path to module file
|
|
38
|
+
* @param exportName - Name of the export to use
|
|
39
|
+
* @param baseDir - Base directory for resolving paths
|
|
40
|
+
* @returns SUT definition ready for registration
|
|
41
|
+
* @throws Error if export cannot be found or loaded
|
|
42
|
+
*/
|
|
43
|
+
export async function loadSutFactory(modulePath, exportName, baseDir, registration, config) {
|
|
44
|
+
const module = await loadModule(modulePath, baseDir);
|
|
45
|
+
const factoryExport = module[exportName];
|
|
46
|
+
if (typeof factoryExport !== "function") {
|
|
47
|
+
throw new Error(`Export "${exportName}" in ${modulePath} is not a function. ` +
|
|
48
|
+
`Found type: ${typeof factoryExport}`);
|
|
49
|
+
}
|
|
50
|
+
// Wrap the factory to match our expected SutFactory type
|
|
51
|
+
const factory = (userConfig) => {
|
|
52
|
+
const instance = factoryExport({ ...config, ...userConfig });
|
|
53
|
+
const mergedConfig = { ...config, ...userConfig, ...(instance.config ?? {}) };
|
|
54
|
+
return {
|
|
55
|
+
id: registration.id,
|
|
56
|
+
config: mergedConfig,
|
|
57
|
+
run: instance.run,
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
return {
|
|
61
|
+
registration,
|
|
62
|
+
factory,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Load a case definition from a module.
|
|
67
|
+
*
|
|
68
|
+
* @param modulePath - Path to module file
|
|
69
|
+
* @param exportName - Name of the export to use
|
|
70
|
+
* @param baseDir - Base directory for resolving paths
|
|
71
|
+
* @returns Case definition ready for use
|
|
72
|
+
* @throws Error if export cannot be found or loaded
|
|
73
|
+
*/
|
|
74
|
+
export async function loadCaseDefinition(modulePath, exportName, baseDir) {
|
|
75
|
+
const module = await loadModule(modulePath, baseDir);
|
|
76
|
+
const caseExport = module[exportName];
|
|
77
|
+
if (typeof caseExport !== "function") {
|
|
78
|
+
throw new Error(`Export "${exportName}" in ${modulePath} is not a function. ` +
|
|
79
|
+
`Found type: ${typeof caseExport}`);
|
|
80
|
+
}
|
|
81
|
+
const definition = caseExport();
|
|
82
|
+
// Validate structure
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
84
|
+
if (!definition.case?.caseId) {
|
|
85
|
+
throw new Error(`Export "${exportName}" in ${modulePath} does not return a valid case definition. ` +
|
|
86
|
+
`Missing case.caseId.`);
|
|
87
|
+
}
|
|
88
|
+
if (typeof definition.getInput !== "function") {
|
|
89
|
+
throw new Error(`Export "${exportName}" in ${modulePath} does not return a valid case definition. ` +
|
|
90
|
+
`Missing getInput function.`);
|
|
91
|
+
}
|
|
92
|
+
if (typeof definition.getInputs !== "function") {
|
|
93
|
+
throw new Error(`Export "${exportName}" in ${modulePath} does not return a valid case definition. ` +
|
|
94
|
+
`Missing getInputs function.`);
|
|
95
|
+
}
|
|
96
|
+
return definition;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Load a metrics extractor from a module.
|
|
100
|
+
*
|
|
101
|
+
* @param modulePath - Path to module file
|
|
102
|
+
* @param exportName - Name of the export to use
|
|
103
|
+
* @param baseDir - Base directory for resolving paths
|
|
104
|
+
* @returns Metrics extractor function
|
|
105
|
+
* @throws Error if export cannot be found or loaded
|
|
106
|
+
*/
|
|
107
|
+
export async function loadMetricsExtractor(modulePath, exportName, baseDir) {
|
|
108
|
+
const module = await loadModule(modulePath, baseDir);
|
|
109
|
+
const extractorExport = module[exportName];
|
|
110
|
+
if (typeof extractorExport !== "function") {
|
|
111
|
+
throw new Error(`Export "${exportName}" in ${modulePath} is not a function. ` +
|
|
112
|
+
`Found type: ${typeof extractorExport}`);
|
|
113
|
+
}
|
|
114
|
+
return extractorExport;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=module-loader.js.map
|