@evalgate/sdk 2.0.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 +638 -0
- package/README.md +398 -0
- package/dist/assertions.d.ts +189 -0
- package/dist/assertions.js +662 -0
- package/dist/batch.d.ts +68 -0
- package/dist/batch.js +179 -0
- package/dist/cache.d.ts +65 -0
- package/dist/cache.js +131 -0
- package/dist/cli/api.d.ts +108 -0
- package/dist/cli/api.js +132 -0
- package/dist/cli/baseline.d.ts +10 -0
- package/dist/cli/baseline.js +172 -0
- package/dist/cli/check.d.ts +73 -0
- package/dist/cli/check.js +355 -0
- package/dist/cli/ci-context.d.ts +6 -0
- package/dist/cli/ci-context.js +112 -0
- package/dist/cli/ci.d.ts +45 -0
- package/dist/cli/ci.js +192 -0
- package/dist/cli/config.d.ts +30 -0
- package/dist/cli/config.js +230 -0
- package/dist/cli/constants.d.ts +15 -0
- package/dist/cli/constants.js +18 -0
- package/dist/cli/diff.d.ts +173 -0
- package/dist/cli/diff.js +685 -0
- package/dist/cli/discover.d.ts +84 -0
- package/dist/cli/discover.js +419 -0
- package/dist/cli/doctor.d.ts +88 -0
- package/dist/cli/doctor.js +675 -0
- package/dist/cli/env.d.ts +21 -0
- package/dist/cli/env.js +42 -0
- package/dist/cli/explain.d.ts +58 -0
- package/dist/cli/explain.js +561 -0
- package/dist/cli/formatters/github.d.ts +8 -0
- package/dist/cli/formatters/github.js +135 -0
- package/dist/cli/formatters/human.d.ts +6 -0
- package/dist/cli/formatters/human.js +110 -0
- package/dist/cli/formatters/json.d.ts +6 -0
- package/dist/cli/formatters/json.js +10 -0
- package/dist/cli/formatters/pr-comment.d.ts +12 -0
- package/dist/cli/formatters/pr-comment.js +103 -0
- package/dist/cli/formatters/types.d.ts +103 -0
- package/dist/cli/formatters/types.js +8 -0
- package/dist/cli/gate.d.ts +21 -0
- package/dist/cli/gate.js +179 -0
- package/dist/cli/impact-analysis.d.ts +63 -0
- package/dist/cli/impact-analysis.js +252 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.js +332 -0
- package/dist/cli/init.d.ts +16 -0
- package/dist/cli/init.js +292 -0
- package/dist/cli/manifest.d.ts +103 -0
- package/dist/cli/manifest.js +282 -0
- package/dist/cli/migrate.d.ts +41 -0
- package/dist/cli/migrate.js +349 -0
- package/dist/cli/policy-packs.d.ts +23 -0
- package/dist/cli/policy-packs.js +89 -0
- package/dist/cli/print-config.d.ts +29 -0
- package/dist/cli/print-config.js +270 -0
- package/dist/cli/profiles.d.ts +28 -0
- package/dist/cli/profiles.js +30 -0
- package/dist/cli/reason-codes.d.ts +17 -0
- package/dist/cli/reason-codes.js +19 -0
- package/dist/cli/regression-gate.d.ts +15 -0
- package/dist/cli/regression-gate.js +341 -0
- package/dist/cli/render/snippet.d.ts +5 -0
- package/dist/cli/render/snippet.js +15 -0
- package/dist/cli/render/sort.d.ts +10 -0
- package/dist/cli/render/sort.js +24 -0
- package/dist/cli/report/build-check-report.d.ts +19 -0
- package/dist/cli/report/build-check-report.js +132 -0
- package/dist/cli/run.d.ts +101 -0
- package/dist/cli/run.js +395 -0
- package/dist/cli/share.d.ts +17 -0
- package/dist/cli/share.js +91 -0
- package/dist/cli/upgrade.d.ts +15 -0
- package/dist/cli/upgrade.js +492 -0
- package/dist/cli/workspace.d.ts +31 -0
- package/dist/cli/workspace.js +68 -0
- package/dist/client.d.ts +368 -0
- package/dist/client.js +893 -0
- package/dist/client.request.test.d.ts +1 -0
- package/dist/client.request.test.js +232 -0
- package/dist/context.d.ts +134 -0
- package/dist/context.js +215 -0
- package/dist/errors.d.ts +82 -0
- package/dist/errors.js +298 -0
- package/dist/export.d.ts +195 -0
- package/dist/export.js +344 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.js +153 -0
- package/dist/integrations/anthropic.d.ts +91 -0
- package/dist/integrations/anthropic.js +163 -0
- package/dist/integrations/openai-eval.d.ts +57 -0
- package/dist/integrations/openai-eval.js +232 -0
- package/dist/integrations/openai.d.ts +92 -0
- package/dist/integrations/openai.js +160 -0
- package/dist/local.d.ts +39 -0
- package/dist/local.js +148 -0
- package/dist/logger.d.ts +128 -0
- package/dist/logger.js +227 -0
- package/dist/matchers/index.d.ts +1 -0
- package/dist/matchers/index.js +6 -0
- package/dist/matchers/to-pass-gate.d.ts +29 -0
- package/dist/matchers/to-pass-gate.js +35 -0
- package/dist/pagination.d.ts +74 -0
- package/dist/pagination.js +139 -0
- package/dist/regression.d.ts +100 -0
- package/dist/regression.js +44 -0
- package/dist/runtime/adapters/config-to-dsl.d.ts +33 -0
- package/dist/runtime/adapters/config-to-dsl.js +400 -0
- package/dist/runtime/adapters/testsuite-to-dsl.d.ts +63 -0
- package/dist/runtime/adapters/testsuite-to-dsl.js +276 -0
- package/dist/runtime/context.d.ts +26 -0
- package/dist/runtime/context.js +74 -0
- package/dist/runtime/eval.d.ts +46 -0
- package/dist/runtime/eval.js +244 -0
- package/dist/runtime/execution-mode.d.ts +80 -0
- package/dist/runtime/execution-mode.js +357 -0
- package/dist/runtime/executor.d.ts +16 -0
- package/dist/runtime/executor.js +152 -0
- package/dist/runtime/registry.d.ts +78 -0
- package/dist/runtime/registry.js +403 -0
- package/dist/runtime/run-report.d.ts +200 -0
- package/dist/runtime/run-report.js +222 -0
- package/dist/runtime/types.d.ts +356 -0
- package/dist/runtime/types.js +76 -0
- package/dist/snapshot.d.ts +176 -0
- package/dist/snapshot.js +322 -0
- package/dist/streaming.d.ts +173 -0
- package/dist/streaming.js +268 -0
- package/dist/testing.d.ts +273 -0
- package/dist/testing.js +317 -0
- package/dist/types.d.ts +754 -0
- package/dist/types.js +54 -0
- package/dist/utils/input-hash.d.ts +8 -0
- package/dist/utils/input-hash.js +41 -0
- package/dist/version.d.ts +7 -0
- package/dist/version.js +10 -0
- package/dist/workflows.d.ts +389 -0
- package/dist/workflows.js +671 -0
- package/package.json +117 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TICKET 2 — Evaluation Manifest Generation
|
|
3
|
+
*
|
|
4
|
+
* Goal: turn discovery output into a stable, versioned, machine-consumable artifact
|
|
5
|
+
* that becomes the input to run / impact / diff.
|
|
6
|
+
*
|
|
7
|
+
* This is the compiler output that everything else consumes.
|
|
8
|
+
*/
|
|
9
|
+
import type { ExecutionModeConfig } from "../runtime/execution-mode";
|
|
10
|
+
import { SDK_VERSION } from "../version";
|
|
11
|
+
import type { SpecAnalysis } from "./discover";
|
|
12
|
+
export { SDK_VERSION };
|
|
13
|
+
/**
|
|
14
|
+
* Manifest schema version
|
|
15
|
+
*/
|
|
16
|
+
export declare const MANIFEST_SCHEMA_VERSION = 1;
|
|
17
|
+
/**
|
|
18
|
+
* Evaluation Manifest Schema
|
|
19
|
+
*/
|
|
20
|
+
export interface EvaluationManifest {
|
|
21
|
+
/** Schema version for compatibility */
|
|
22
|
+
schemaVersion: number;
|
|
23
|
+
/** When this manifest was generated */
|
|
24
|
+
generatedAt: number;
|
|
25
|
+
/** Project metadata */
|
|
26
|
+
project: {
|
|
27
|
+
name: string;
|
|
28
|
+
root: string;
|
|
29
|
+
namespace: string;
|
|
30
|
+
};
|
|
31
|
+
/** Runtime information */
|
|
32
|
+
runtime: {
|
|
33
|
+
mode: "spec" | "legacy";
|
|
34
|
+
sdkVersion: string;
|
|
35
|
+
};
|
|
36
|
+
/** Spec files with hashes */
|
|
37
|
+
specFiles: SpecFile[];
|
|
38
|
+
/** Individual specifications */
|
|
39
|
+
specs: Spec[];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Spec file information
|
|
43
|
+
*/
|
|
44
|
+
export interface SpecFile {
|
|
45
|
+
/** POSIX-relative file path */
|
|
46
|
+
filePath: string;
|
|
47
|
+
/** SHA-256 hash of file content */
|
|
48
|
+
fileHash: string;
|
|
49
|
+
/** Number of specs in this file */
|
|
50
|
+
specCount: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Individual specification
|
|
54
|
+
*/
|
|
55
|
+
export interface Spec {
|
|
56
|
+
/** Stable canonical ID */
|
|
57
|
+
id: string;
|
|
58
|
+
/** Spec name */
|
|
59
|
+
name: string;
|
|
60
|
+
/** Suite path from tags or file structure */
|
|
61
|
+
suitePath: string[];
|
|
62
|
+
/** POSIX-relative file path */
|
|
63
|
+
filePath: string;
|
|
64
|
+
/** Position in file */
|
|
65
|
+
position: {
|
|
66
|
+
line: number;
|
|
67
|
+
column: number;
|
|
68
|
+
};
|
|
69
|
+
/** Tags/categories */
|
|
70
|
+
tags: string[];
|
|
71
|
+
/** Dependencies */
|
|
72
|
+
dependsOn: {
|
|
73
|
+
prompts: string[];
|
|
74
|
+
datasets: string[];
|
|
75
|
+
tools: string[];
|
|
76
|
+
code: string[];
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Lock file for caching
|
|
81
|
+
*/
|
|
82
|
+
export interface ManifestLock {
|
|
83
|
+
/** When lock was generated */
|
|
84
|
+
generatedAt: number;
|
|
85
|
+
/** File hashes for incremental updates */
|
|
86
|
+
fileHashes: Record<string, string>;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Generate evaluation manifest from discovery results
|
|
90
|
+
*/
|
|
91
|
+
export declare function generateManifest(specs: SpecAnalysis[], projectRoot: string, projectName: string, executionMode: ExecutionModeConfig): Promise<EvaluationManifest>;
|
|
92
|
+
/**
|
|
93
|
+
* Write manifest to disk
|
|
94
|
+
*/
|
|
95
|
+
export declare function writeManifest(manifest: EvaluationManifest, projectRoot: string): Promise<void>;
|
|
96
|
+
/**
|
|
97
|
+
* Read existing manifest
|
|
98
|
+
*/
|
|
99
|
+
export declare function readManifest(projectRoot: string): Promise<EvaluationManifest | null>;
|
|
100
|
+
/**
|
|
101
|
+
* Read existing lock file
|
|
102
|
+
*/
|
|
103
|
+
export declare function readLock(projectRoot: string): Promise<ManifestLock | null>;
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TICKET 2 — Evaluation Manifest Generation
|
|
4
|
+
*
|
|
5
|
+
* Goal: turn discovery output into a stable, versioned, machine-consumable artifact
|
|
6
|
+
* that becomes the input to run / impact / diff.
|
|
7
|
+
*
|
|
8
|
+
* This is the compiler output that everything else consumes.
|
|
9
|
+
*/
|
|
10
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(o, k2, desc);
|
|
17
|
+
}) : (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
o[k2] = m[k];
|
|
20
|
+
}));
|
|
21
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
22
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
23
|
+
}) : function(o, v) {
|
|
24
|
+
o["default"] = v;
|
|
25
|
+
});
|
|
26
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
27
|
+
var ownKeys = function(o) {
|
|
28
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
29
|
+
var ar = [];
|
|
30
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
31
|
+
return ar;
|
|
32
|
+
};
|
|
33
|
+
return ownKeys(o);
|
|
34
|
+
};
|
|
35
|
+
return function (mod) {
|
|
36
|
+
if (mod && mod.__esModule) return mod;
|
|
37
|
+
var result = {};
|
|
38
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
39
|
+
__setModuleDefault(result, mod);
|
|
40
|
+
return result;
|
|
41
|
+
};
|
|
42
|
+
})();
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.MANIFEST_SCHEMA_VERSION = exports.SDK_VERSION = void 0;
|
|
45
|
+
exports.generateManifest = generateManifest;
|
|
46
|
+
exports.writeManifest = writeManifest;
|
|
47
|
+
exports.readManifest = readManifest;
|
|
48
|
+
exports.readLock = readLock;
|
|
49
|
+
const crypto = __importStar(require("node:crypto"));
|
|
50
|
+
const fs = __importStar(require("node:fs/promises"));
|
|
51
|
+
const path = __importStar(require("node:path"));
|
|
52
|
+
const version_1 = require("../version");
|
|
53
|
+
Object.defineProperty(exports, "SDK_VERSION", { enumerable: true, get: function () { return version_1.SDK_VERSION; } });
|
|
54
|
+
/**
|
|
55
|
+
* Manifest schema version
|
|
56
|
+
*/
|
|
57
|
+
exports.MANIFEST_SCHEMA_VERSION = 1;
|
|
58
|
+
/**
|
|
59
|
+
* Generate evaluation manifest from discovery results
|
|
60
|
+
*/
|
|
61
|
+
async function generateManifest(specs, projectRoot, projectName, executionMode) {
|
|
62
|
+
const generatedAt = Math.floor(Date.now() / 1000);
|
|
63
|
+
const namespace = generateNamespace(projectRoot);
|
|
64
|
+
// Process spec files and specs
|
|
65
|
+
const specFiles = [];
|
|
66
|
+
const processedSpecs = [];
|
|
67
|
+
// Group specs by file
|
|
68
|
+
const specsByFile = new Map();
|
|
69
|
+
for (const spec of specs) {
|
|
70
|
+
const normalizedPath = normalizePath(spec.file, projectRoot);
|
|
71
|
+
if (!specsByFile.has(normalizedPath)) {
|
|
72
|
+
specsByFile.set(normalizedPath, []);
|
|
73
|
+
}
|
|
74
|
+
specsByFile.get(normalizedPath)?.push(spec);
|
|
75
|
+
}
|
|
76
|
+
// Process each file
|
|
77
|
+
for (const [filePath, fileSpecs] of specsByFile) {
|
|
78
|
+
const absolutePath = path.join(projectRoot, filePath);
|
|
79
|
+
const fileHash = await hashFile(absolutePath);
|
|
80
|
+
specFiles.push({
|
|
81
|
+
filePath,
|
|
82
|
+
fileHash,
|
|
83
|
+
specCount: fileSpecs.length,
|
|
84
|
+
});
|
|
85
|
+
// Process individual specs
|
|
86
|
+
for (const spec of fileSpecs) {
|
|
87
|
+
const processedSpec = await processSpec(spec, filePath, projectRoot);
|
|
88
|
+
processedSpecs.push(processedSpec);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
schemaVersion: exports.MANIFEST_SCHEMA_VERSION,
|
|
93
|
+
generatedAt,
|
|
94
|
+
project: {
|
|
95
|
+
name: projectName,
|
|
96
|
+
root: ".",
|
|
97
|
+
namespace,
|
|
98
|
+
},
|
|
99
|
+
runtime: {
|
|
100
|
+
mode: executionMode.mode,
|
|
101
|
+
sdkVersion: version_1.SDK_VERSION,
|
|
102
|
+
},
|
|
103
|
+
specFiles,
|
|
104
|
+
specs: processedSpecs,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Process individual specification
|
|
109
|
+
*/
|
|
110
|
+
async function processSpec(spec, filePath, projectRoot) {
|
|
111
|
+
const absolutePath = path.join(projectRoot, filePath);
|
|
112
|
+
const content = await fs.readFile(absolutePath, "utf-8");
|
|
113
|
+
// Extract position from AST analysis (simplified for now)
|
|
114
|
+
const position = extractPosition(content, spec.name);
|
|
115
|
+
// Extract dependencies from content
|
|
116
|
+
const dependsOn = extractDependencies(content);
|
|
117
|
+
// Generate suite path from tags or file structure
|
|
118
|
+
const suitePath = generateSuitePath(spec.tags, filePath);
|
|
119
|
+
return {
|
|
120
|
+
id: spec.id,
|
|
121
|
+
name: spec.name,
|
|
122
|
+
suitePath,
|
|
123
|
+
filePath: normalizePath(spec.file, projectRoot),
|
|
124
|
+
position,
|
|
125
|
+
tags: spec.tags,
|
|
126
|
+
dependsOn,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Extract position from content (simplified implementation)
|
|
131
|
+
*/
|
|
132
|
+
function extractPosition(content, specName) {
|
|
133
|
+
const lines = content.split("\n");
|
|
134
|
+
const specPattern = new RegExp(`defineEval\\s*\\(\\s*["'\`]${specName}["'\`]`, "g");
|
|
135
|
+
let match = null;
|
|
136
|
+
let line = 1;
|
|
137
|
+
let column = 1;
|
|
138
|
+
for (let i = 0; i < lines.length; i++) {
|
|
139
|
+
const lineContent = lines[i];
|
|
140
|
+
specPattern.lastIndex = 0;
|
|
141
|
+
match = specPattern.exec(lineContent);
|
|
142
|
+
if (match) {
|
|
143
|
+
line = i + 1;
|
|
144
|
+
column = match.index + 1;
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return { line, column };
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Extract dependencies from content
|
|
152
|
+
*/
|
|
153
|
+
function extractDependencies(content) {
|
|
154
|
+
const dependsOn = {
|
|
155
|
+
prompts: [],
|
|
156
|
+
datasets: [],
|
|
157
|
+
tools: [],
|
|
158
|
+
code: [],
|
|
159
|
+
};
|
|
160
|
+
// Extract from dependsOn option if present
|
|
161
|
+
const dependsOnMatch = content.match(/dependsOn\s*:\s*({[^}]+})/s);
|
|
162
|
+
if (dependsOnMatch) {
|
|
163
|
+
try {
|
|
164
|
+
// Use JSON.parse instead of eval for safety
|
|
165
|
+
const deps = JSON.parse(dependsOnMatch[1]);
|
|
166
|
+
return {
|
|
167
|
+
prompts: deps.prompts || [],
|
|
168
|
+
datasets: deps.datasets || [],
|
|
169
|
+
tools: deps.tools || [],
|
|
170
|
+
code: deps.code || [],
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
catch (_error) {
|
|
174
|
+
// If parsing fails, return empty dependencies
|
|
175
|
+
return {
|
|
176
|
+
prompts: [],
|
|
177
|
+
datasets: [],
|
|
178
|
+
tools: [],
|
|
179
|
+
code: [],
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Simple extraction as fallback
|
|
184
|
+
const patterns = {
|
|
185
|
+
prompts: /["']([^"']*\.md)["']/g,
|
|
186
|
+
datasets: /["']([^"']*\.json)["']/g,
|
|
187
|
+
tools: /["']([^"']*\.ts)["']/g,
|
|
188
|
+
code: /import.*from\s*["']([^"']+)["']/g,
|
|
189
|
+
};
|
|
190
|
+
for (const [type, pattern] of Object.entries(patterns)) {
|
|
191
|
+
let match;
|
|
192
|
+
match = pattern.exec(content);
|
|
193
|
+
while (match !== null) {
|
|
194
|
+
dependsOn[type].push(match[1]);
|
|
195
|
+
match = pattern.exec(content);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return dependsOn;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Generate suite path from tags or file structure
|
|
202
|
+
*/
|
|
203
|
+
function generateSuitePath(tags, filePath) {
|
|
204
|
+
// Use tags as primary suite path
|
|
205
|
+
if (tags.length > 0) {
|
|
206
|
+
return [tags[0]];
|
|
207
|
+
}
|
|
208
|
+
// Fall back to file structure
|
|
209
|
+
const parts = filePath.split("/");
|
|
210
|
+
if (parts.length > 1) {
|
|
211
|
+
return [parts[0]];
|
|
212
|
+
}
|
|
213
|
+
return ["general"];
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Generate namespace from project root
|
|
217
|
+
*/
|
|
218
|
+
function generateNamespace(projectRoot) {
|
|
219
|
+
const hash = crypto.createHash("sha256");
|
|
220
|
+
hash.update(projectRoot);
|
|
221
|
+
return hash.digest("hex").slice(0, 8);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Normalize path to POSIX format
|
|
225
|
+
*/
|
|
226
|
+
function normalizePath(filePath, projectRoot) {
|
|
227
|
+
const relativePath = path.relative(projectRoot, filePath);
|
|
228
|
+
return relativePath.replace(/\\/g, "/");
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Hash file content
|
|
232
|
+
*/
|
|
233
|
+
async function hashFile(filePath) {
|
|
234
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
235
|
+
const hash = crypto.createHash("sha256");
|
|
236
|
+
hash.update(content);
|
|
237
|
+
return `sha256:${hash.digest("hex")}`;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Write manifest to disk
|
|
241
|
+
*/
|
|
242
|
+
async function writeManifest(manifest, projectRoot) {
|
|
243
|
+
const evalgateDir = path.join(projectRoot, ".evalgate");
|
|
244
|
+
// Ensure .evalgate directory exists
|
|
245
|
+
await fs.mkdir(evalgateDir, { recursive: true });
|
|
246
|
+
// Write manifest.json
|
|
247
|
+
const manifestPath = path.join(evalgateDir, "manifest.json");
|
|
248
|
+
await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
249
|
+
// Write lock file
|
|
250
|
+
const lock = {
|
|
251
|
+
generatedAt: manifest.generatedAt,
|
|
252
|
+
fileHashes: Object.fromEntries(manifest.specFiles.map((f) => [f.filePath, f.fileHash])),
|
|
253
|
+
};
|
|
254
|
+
const lockPath = path.join(evalgateDir, "manifest.lock.json");
|
|
255
|
+
await fs.writeFile(lockPath, JSON.stringify(lock, null, 2), "utf-8");
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Read existing manifest
|
|
259
|
+
*/
|
|
260
|
+
async function readManifest(projectRoot) {
|
|
261
|
+
const manifestPath = path.join(projectRoot, ".evalgate", "manifest.json");
|
|
262
|
+
try {
|
|
263
|
+
const content = await fs.readFile(manifestPath, "utf-8");
|
|
264
|
+
return JSON.parse(content);
|
|
265
|
+
}
|
|
266
|
+
catch (_error) {
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Read existing lock file
|
|
272
|
+
*/
|
|
273
|
+
async function readLock(projectRoot) {
|
|
274
|
+
const lockPath = path.join(projectRoot, ".evalgate", "manifest.lock.json");
|
|
275
|
+
try {
|
|
276
|
+
const content = await fs.readFile(lockPath, "utf-8");
|
|
277
|
+
return JSON.parse(content);
|
|
278
|
+
}
|
|
279
|
+
catch (_error) {
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COMPAT-203: Config → DSL migration generator (file-based)
|
|
3
|
+
*
|
|
4
|
+
* CLI command: evalgate migrate config --in evalgate.config.json --out eval/legacy.spec.ts
|
|
5
|
+
* Generates defineEval() calls with comments and TODOs for manual completion
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from "commander";
|
|
8
|
+
/**
|
|
9
|
+
* Migration options
|
|
10
|
+
*/
|
|
11
|
+
interface MigrateOptions {
|
|
12
|
+
/** Input config file path */
|
|
13
|
+
input: string;
|
|
14
|
+
/** Output DSL file path */
|
|
15
|
+
output: string;
|
|
16
|
+
/** Include detailed comments */
|
|
17
|
+
verbose?: boolean;
|
|
18
|
+
/** Generate helper functions */
|
|
19
|
+
helpers?: boolean;
|
|
20
|
+
/** Preserve original test IDs */
|
|
21
|
+
preserveIds?: boolean;
|
|
22
|
+
/** Include provenance metadata */
|
|
23
|
+
provenance?: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Main migration function
|
|
27
|
+
*/
|
|
28
|
+
export declare function migrateConfig(options: MigrateOptions): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* CLI command definition
|
|
31
|
+
*/
|
|
32
|
+
export declare function createMigrateCommand(): Command;
|
|
33
|
+
/**
|
|
34
|
+
* Validate config file structure
|
|
35
|
+
*/
|
|
36
|
+
export declare function validateConfigFile(filePath: string): Promise<boolean>;
|
|
37
|
+
/**
|
|
38
|
+
* Show migration preview without writing files
|
|
39
|
+
*/
|
|
40
|
+
export declare function previewMigration(filePath: string): Promise<void>;
|
|
41
|
+
export {};
|