@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.
Files changed (141) hide show
  1. package/CHANGELOG.md +638 -0
  2. package/README.md +398 -0
  3. package/dist/assertions.d.ts +189 -0
  4. package/dist/assertions.js +662 -0
  5. package/dist/batch.d.ts +68 -0
  6. package/dist/batch.js +179 -0
  7. package/dist/cache.d.ts +65 -0
  8. package/dist/cache.js +131 -0
  9. package/dist/cli/api.d.ts +108 -0
  10. package/dist/cli/api.js +132 -0
  11. package/dist/cli/baseline.d.ts +10 -0
  12. package/dist/cli/baseline.js +172 -0
  13. package/dist/cli/check.d.ts +73 -0
  14. package/dist/cli/check.js +355 -0
  15. package/dist/cli/ci-context.d.ts +6 -0
  16. package/dist/cli/ci-context.js +112 -0
  17. package/dist/cli/ci.d.ts +45 -0
  18. package/dist/cli/ci.js +192 -0
  19. package/dist/cli/config.d.ts +30 -0
  20. package/dist/cli/config.js +230 -0
  21. package/dist/cli/constants.d.ts +15 -0
  22. package/dist/cli/constants.js +18 -0
  23. package/dist/cli/diff.d.ts +173 -0
  24. package/dist/cli/diff.js +685 -0
  25. package/dist/cli/discover.d.ts +84 -0
  26. package/dist/cli/discover.js +419 -0
  27. package/dist/cli/doctor.d.ts +88 -0
  28. package/dist/cli/doctor.js +675 -0
  29. package/dist/cli/env.d.ts +21 -0
  30. package/dist/cli/env.js +42 -0
  31. package/dist/cli/explain.d.ts +58 -0
  32. package/dist/cli/explain.js +561 -0
  33. package/dist/cli/formatters/github.d.ts +8 -0
  34. package/dist/cli/formatters/github.js +135 -0
  35. package/dist/cli/formatters/human.d.ts +6 -0
  36. package/dist/cli/formatters/human.js +110 -0
  37. package/dist/cli/formatters/json.d.ts +6 -0
  38. package/dist/cli/formatters/json.js +10 -0
  39. package/dist/cli/formatters/pr-comment.d.ts +12 -0
  40. package/dist/cli/formatters/pr-comment.js +103 -0
  41. package/dist/cli/formatters/types.d.ts +103 -0
  42. package/dist/cli/formatters/types.js +8 -0
  43. package/dist/cli/gate.d.ts +21 -0
  44. package/dist/cli/gate.js +179 -0
  45. package/dist/cli/impact-analysis.d.ts +63 -0
  46. package/dist/cli/impact-analysis.js +252 -0
  47. package/dist/cli/index.d.ts +9 -0
  48. package/dist/cli/index.js +332 -0
  49. package/dist/cli/init.d.ts +16 -0
  50. package/dist/cli/init.js +292 -0
  51. package/dist/cli/manifest.d.ts +103 -0
  52. package/dist/cli/manifest.js +282 -0
  53. package/dist/cli/migrate.d.ts +41 -0
  54. package/dist/cli/migrate.js +349 -0
  55. package/dist/cli/policy-packs.d.ts +23 -0
  56. package/dist/cli/policy-packs.js +89 -0
  57. package/dist/cli/print-config.d.ts +29 -0
  58. package/dist/cli/print-config.js +270 -0
  59. package/dist/cli/profiles.d.ts +28 -0
  60. package/dist/cli/profiles.js +30 -0
  61. package/dist/cli/reason-codes.d.ts +17 -0
  62. package/dist/cli/reason-codes.js +19 -0
  63. package/dist/cli/regression-gate.d.ts +15 -0
  64. package/dist/cli/regression-gate.js +341 -0
  65. package/dist/cli/render/snippet.d.ts +5 -0
  66. package/dist/cli/render/snippet.js +15 -0
  67. package/dist/cli/render/sort.d.ts +10 -0
  68. package/dist/cli/render/sort.js +24 -0
  69. package/dist/cli/report/build-check-report.d.ts +19 -0
  70. package/dist/cli/report/build-check-report.js +132 -0
  71. package/dist/cli/run.d.ts +101 -0
  72. package/dist/cli/run.js +395 -0
  73. package/dist/cli/share.d.ts +17 -0
  74. package/dist/cli/share.js +91 -0
  75. package/dist/cli/upgrade.d.ts +15 -0
  76. package/dist/cli/upgrade.js +492 -0
  77. package/dist/cli/workspace.d.ts +31 -0
  78. package/dist/cli/workspace.js +68 -0
  79. package/dist/client.d.ts +368 -0
  80. package/dist/client.js +893 -0
  81. package/dist/client.request.test.d.ts +1 -0
  82. package/dist/client.request.test.js +232 -0
  83. package/dist/context.d.ts +134 -0
  84. package/dist/context.js +215 -0
  85. package/dist/errors.d.ts +82 -0
  86. package/dist/errors.js +298 -0
  87. package/dist/export.d.ts +195 -0
  88. package/dist/export.js +344 -0
  89. package/dist/index.d.ts +44 -0
  90. package/dist/index.js +153 -0
  91. package/dist/integrations/anthropic.d.ts +91 -0
  92. package/dist/integrations/anthropic.js +163 -0
  93. package/dist/integrations/openai-eval.d.ts +57 -0
  94. package/dist/integrations/openai-eval.js +232 -0
  95. package/dist/integrations/openai.d.ts +92 -0
  96. package/dist/integrations/openai.js +160 -0
  97. package/dist/local.d.ts +39 -0
  98. package/dist/local.js +148 -0
  99. package/dist/logger.d.ts +128 -0
  100. package/dist/logger.js +227 -0
  101. package/dist/matchers/index.d.ts +1 -0
  102. package/dist/matchers/index.js +6 -0
  103. package/dist/matchers/to-pass-gate.d.ts +29 -0
  104. package/dist/matchers/to-pass-gate.js +35 -0
  105. package/dist/pagination.d.ts +74 -0
  106. package/dist/pagination.js +139 -0
  107. package/dist/regression.d.ts +100 -0
  108. package/dist/regression.js +44 -0
  109. package/dist/runtime/adapters/config-to-dsl.d.ts +33 -0
  110. package/dist/runtime/adapters/config-to-dsl.js +400 -0
  111. package/dist/runtime/adapters/testsuite-to-dsl.d.ts +63 -0
  112. package/dist/runtime/adapters/testsuite-to-dsl.js +276 -0
  113. package/dist/runtime/context.d.ts +26 -0
  114. package/dist/runtime/context.js +74 -0
  115. package/dist/runtime/eval.d.ts +46 -0
  116. package/dist/runtime/eval.js +244 -0
  117. package/dist/runtime/execution-mode.d.ts +80 -0
  118. package/dist/runtime/execution-mode.js +357 -0
  119. package/dist/runtime/executor.d.ts +16 -0
  120. package/dist/runtime/executor.js +152 -0
  121. package/dist/runtime/registry.d.ts +78 -0
  122. package/dist/runtime/registry.js +403 -0
  123. package/dist/runtime/run-report.d.ts +200 -0
  124. package/dist/runtime/run-report.js +222 -0
  125. package/dist/runtime/types.d.ts +356 -0
  126. package/dist/runtime/types.js +76 -0
  127. package/dist/snapshot.d.ts +176 -0
  128. package/dist/snapshot.js +322 -0
  129. package/dist/streaming.d.ts +173 -0
  130. package/dist/streaming.js +268 -0
  131. package/dist/testing.d.ts +273 -0
  132. package/dist/testing.js +317 -0
  133. package/dist/types.d.ts +754 -0
  134. package/dist/types.js +54 -0
  135. package/dist/utils/input-hash.d.ts +8 -0
  136. package/dist/utils/input-hash.js +41 -0
  137. package/dist/version.d.ts +7 -0
  138. package/dist/version.js +10 -0
  139. package/dist/workflows.d.ts +389 -0
  140. package/dist/workflows.js +671 -0
  141. package/package.json +117 -0
@@ -0,0 +1,80 @@
1
+ /**
2
+ * COMPAT-204: Dual-path execution toggle
3
+ *
4
+ * Environment flag EVALGATE_RUNTIME=legacy|spec|auto
5
+ * Auto uses spec runtime if manifest/specs exist, else legacy
6
+ * Existing projects continue unchanged; new projects can use DSL only
7
+ */
8
+ /**
9
+ * Execution mode types
10
+ */
11
+ export type ExecutionMode = "legacy" | "spec" | "auto";
12
+ /**
13
+ * Execution mode configuration
14
+ */
15
+ export interface ExecutionModeConfig {
16
+ /** Current execution mode */
17
+ mode: ExecutionMode;
18
+ /** Whether spec runtime is available */
19
+ hasSpecRuntime: boolean;
20
+ /** Whether legacy runtime is available */
21
+ hasLegacyRuntime: boolean;
22
+ /** Project root path */
23
+ projectRoot: string;
24
+ /** Detected spec files */
25
+ specFiles: string[];
26
+ /** Detected legacy config */
27
+ legacyConfig?: string;
28
+ }
29
+ /**
30
+ * Get execution mode from environment or auto-detection
31
+ */
32
+ export declare function getExecutionMode(projectRoot?: string): Promise<ExecutionModeConfig>;
33
+ /**
34
+ * Check if project can run in spec mode
35
+ */
36
+ export declare function canRunSpecMode(config: ExecutionModeConfig): boolean;
37
+ /**
38
+ * Check if project can run in legacy mode
39
+ */
40
+ export declare function canRunLegacyMode(config: ExecutionModeConfig): boolean;
41
+ /**
42
+ * Get recommended execution mode for project
43
+ */
44
+ export declare function getRecommendedExecutionMode(config: ExecutionModeConfig): ExecutionMode;
45
+ /**
46
+ * Validate execution mode compatibility
47
+ */
48
+ export declare function validateExecutionMode(config: ExecutionModeConfig): {
49
+ valid: boolean;
50
+ warnings: string[];
51
+ errors: string[];
52
+ };
53
+ /**
54
+ * Print execution mode information
55
+ */
56
+ export declare function printExecutionModeInfo(config: ExecutionModeConfig): void;
57
+ /**
58
+ * Environment variable helpers
59
+ */
60
+ export declare const ENV_VARS: {
61
+ readonly EXECUTION_MODE: "EVALGATE_RUNTIME";
62
+ readonly POSSIBLE_VALUES: readonly ["legacy", "spec", "auto"];
63
+ readonly DEFAULT: "auto";
64
+ };
65
+ /**
66
+ * Check if environment variable is set
67
+ */
68
+ export declare function hasExecutionModeEnv(): boolean;
69
+ /**
70
+ * Get current environment variable value
71
+ */
72
+ export declare function getExecutionModeEnv(): string | undefined;
73
+ /**
74
+ * Set execution mode environment variable
75
+ */
76
+ export declare function setExecutionModeEnv(mode: ExecutionMode): void;
77
+ /**
78
+ * Clear execution mode environment variable
79
+ */
80
+ export declare function clearExecutionModeEnv(): void;
@@ -0,0 +1,357 @@
1
+ "use strict";
2
+ /**
3
+ * COMPAT-204: Dual-path execution toggle
4
+ *
5
+ * Environment flag EVALGATE_RUNTIME=legacy|spec|auto
6
+ * Auto uses spec runtime if manifest/specs exist, else legacy
7
+ * Existing projects continue unchanged; new projects can use DSL only
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.ENV_VARS = void 0;
44
+ exports.getExecutionMode = getExecutionMode;
45
+ exports.canRunSpecMode = canRunSpecMode;
46
+ exports.canRunLegacyMode = canRunLegacyMode;
47
+ exports.getRecommendedExecutionMode = getRecommendedExecutionMode;
48
+ exports.validateExecutionMode = validateExecutionMode;
49
+ exports.printExecutionModeInfo = printExecutionModeInfo;
50
+ exports.hasExecutionModeEnv = hasExecutionModeEnv;
51
+ exports.getExecutionModeEnv = getExecutionModeEnv;
52
+ exports.setExecutionModeEnv = setExecutionModeEnv;
53
+ exports.clearExecutionModeEnv = clearExecutionModeEnv;
54
+ const fs = __importStar(require("node:fs/promises"));
55
+ const path = __importStar(require("node:path"));
56
+ /**
57
+ * Get execution mode from environment or auto-detection
58
+ */
59
+ async function getExecutionMode(projectRoot = process.cwd()) {
60
+ // Check environment variable first
61
+ const envMode = process.env.EVALGATE_RUNTIME?.toLowerCase();
62
+ if (envMode === "legacy" || envMode === "spec" || envMode === "auto") {
63
+ return {
64
+ mode: envMode,
65
+ hasSpecRuntime: envMode !== "legacy",
66
+ hasLegacyRuntime: envMode !== "spec",
67
+ projectRoot,
68
+ specFiles: envMode !== "legacy" ? await findSpecFiles(projectRoot) : [],
69
+ legacyConfig: envMode !== "spec" ? await findLegacyConfig(projectRoot) : undefined,
70
+ };
71
+ }
72
+ // Auto-detect mode
73
+ return await autoDetectExecutionMode(projectRoot);
74
+ }
75
+ /**
76
+ * Auto-detect execution mode based on project structure
77
+ */
78
+ async function autoDetectExecutionMode(projectRoot) {
79
+ const specFiles = await findSpecFiles(projectRoot);
80
+ const legacyConfig = await findLegacyConfig(projectRoot);
81
+ const hasSpecRuntime = specFiles.length > 0;
82
+ const hasLegacyRuntime = !!legacyConfig;
83
+ let mode = "auto";
84
+ // If both are available, prefer spec runtime for new projects
85
+ if (hasSpecRuntime && hasLegacyRuntime) {
86
+ mode = "spec"; // Prefer spec for mixed projects
87
+ }
88
+ else if (hasSpecRuntime) {
89
+ mode = "spec";
90
+ }
91
+ else if (hasLegacyRuntime) {
92
+ mode = "legacy";
93
+ }
94
+ else {
95
+ mode = "auto"; // Default to auto for empty projects
96
+ }
97
+ return {
98
+ mode,
99
+ hasSpecRuntime,
100
+ hasLegacyRuntime,
101
+ projectRoot,
102
+ specFiles,
103
+ legacyConfig,
104
+ };
105
+ }
106
+ /**
107
+ * Find spec files in project
108
+ */
109
+ async function findSpecFiles(projectRoot) {
110
+ const specPatterns = [
111
+ "eval/**/*.spec.ts",
112
+ "eval/**/*.spec.js",
113
+ "src/**/*.spec.ts",
114
+ "src/**/*.spec.js",
115
+ "tests/**/*.spec.ts",
116
+ "tests/**/*.spec.js",
117
+ "spec/**/*.ts",
118
+ "spec/**/*.js",
119
+ ];
120
+ const foundFiles = [];
121
+ for (const pattern of specPatterns) {
122
+ try {
123
+ const files = await searchFiles(projectRoot, pattern, projectRoot);
124
+ foundFiles.push(...files);
125
+ }
126
+ catch (_error) {
127
+ // Ignore errors for non-existent paths
128
+ }
129
+ }
130
+ // Filter for files that contain defineEval calls
131
+ const specFilesWithDefineEval = [];
132
+ for (const file of foundFiles) {
133
+ try {
134
+ const content = await fs.readFile(file, "utf-8");
135
+ if (content.includes("defineEval")) {
136
+ specFilesWithDefineEval.push(file);
137
+ }
138
+ }
139
+ catch (_error) {
140
+ // Ignore read errors
141
+ }
142
+ }
143
+ return specFilesWithDefineEval;
144
+ }
145
+ /**
146
+ * Simple file search (placeholder for proper glob implementation)
147
+ */
148
+ async function searchFiles(dir, pattern, projectRoot) {
149
+ const results = [];
150
+ try {
151
+ const entries = await fs.readdir(dir, { withFileTypes: true });
152
+ for (let i = 0; i < entries.length; i++) {
153
+ const entry = entries[i];
154
+ const fullPath = path.join(dir, entry.name);
155
+ if (entry.isDirectory() && !entry.name.startsWith(".")) {
156
+ results.push(...(await searchFiles(fullPath, pattern, projectRoot)));
157
+ }
158
+ else if (entry.isFile()) {
159
+ // Simple pattern matching
160
+ if (matchesPattern(fullPath, pattern, projectRoot)) {
161
+ results.push(fullPath);
162
+ }
163
+ }
164
+ }
165
+ }
166
+ catch (_error) {
167
+ // Ignore permission errors
168
+ }
169
+ return results;
170
+ }
171
+ /**
172
+ * Simple pattern matching (placeholder for proper glob)
173
+ */
174
+ function matchesPattern(filePath, pattern, projectRoot) {
175
+ const _fileName = path.basename(filePath);
176
+ const _ext = path.extname(filePath);
177
+ const _dir = path.dirname(filePath);
178
+ // Convert glob pattern to regex
179
+ // Handle **/ and * patterns correctly
180
+ let regexPattern = pattern;
181
+ // Replace **/ with (?:.*/)? to match optional directory path
182
+ regexPattern = regexPattern.replace(/\*\*\//g, "(?:.*/)?");
183
+ // Replace remaining * with [^/]* (filename pattern)
184
+ regexPattern = regexPattern.replace(/\*/g, "[^/]*");
185
+ const relativePath = path.relative(projectRoot, filePath).replace(/\\/g, "/");
186
+ const regex = new RegExp(`^${regexPattern}$`);
187
+ return regex.test(relativePath);
188
+ }
189
+ /**
190
+ * Find legacy config file
191
+ */
192
+ async function findLegacyConfig(projectRoot) {
193
+ const configPaths = [
194
+ "evalai.config.json",
195
+ "evalai.config.js",
196
+ "evalai.config.ts",
197
+ ".evalgaterc",
198
+ ".evalgaterc.json",
199
+ ];
200
+ for (const configPath of configPaths) {
201
+ const fullPath = path.join(projectRoot, configPath);
202
+ try {
203
+ await fs.access(fullPath);
204
+ return fullPath;
205
+ }
206
+ catch (_error) {
207
+ // File doesn't exist, continue
208
+ }
209
+ }
210
+ return undefined;
211
+ }
212
+ /**
213
+ * Check if project can run in spec mode
214
+ */
215
+ function canRunSpecMode(config) {
216
+ return config.hasSpecRuntime && config.specFiles.length > 0;
217
+ }
218
+ /**
219
+ * Check if project can run in legacy mode
220
+ */
221
+ function canRunLegacyMode(config) {
222
+ return config.hasLegacyRuntime && !!config.legacyConfig;
223
+ }
224
+ /**
225
+ * Get recommended execution mode for project
226
+ */
227
+ function getRecommendedExecutionMode(config) {
228
+ if (config.mode !== "auto") {
229
+ return config.mode;
230
+ }
231
+ if (canRunSpecMode(config) && canRunLegacyMode(config)) {
232
+ return "spec"; // Prefer spec for mixed projects
233
+ }
234
+ if (canRunSpecMode(config)) {
235
+ return "spec";
236
+ }
237
+ if (canRunLegacyMode(config)) {
238
+ return "legacy";
239
+ }
240
+ return "auto";
241
+ }
242
+ /**
243
+ * Validate execution mode compatibility
244
+ */
245
+ function validateExecutionMode(config) {
246
+ const warnings = [];
247
+ const errors = [];
248
+ // Check for mixed project
249
+ if (config.hasSpecRuntime && config.hasLegacyRuntime) {
250
+ warnings.push("Project contains both spec files and legacy config. " +
251
+ "Consider migrating legacy tests to spec format for consistency.");
252
+ }
253
+ // Check for no runtime
254
+ if (!config.hasSpecRuntime && !config.hasLegacyRuntime) {
255
+ warnings.push("No tests found. This appears to be an empty project. " +
256
+ "Use 'evalgate init' to create a new project.");
257
+ }
258
+ // Check for spec mode without spec files
259
+ if (config.mode === "spec" && !canRunSpecMode(config)) {
260
+ errors.push("Spec mode requested but no spec files found. " +
261
+ "Create spec files with defineEval() or use legacy mode.");
262
+ }
263
+ // Check for legacy mode without config
264
+ if (config.mode === "legacy" && !canRunLegacyMode(config)) {
265
+ errors.push("Legacy mode requested but no evalgate.config.json (or evalai.config.json) found. " +
266
+ "Create a config file or use spec mode.");
267
+ }
268
+ return {
269
+ valid: errors.length === 0,
270
+ warnings,
271
+ errors,
272
+ };
273
+ }
274
+ /**
275
+ * Print execution mode information
276
+ */
277
+ function printExecutionModeInfo(config) {
278
+ console.log(`🔧 EvalGate Execution Mode: ${config.mode.toUpperCase()}`);
279
+ console.log(`📁 Project root: ${config.projectRoot}`);
280
+ console.log(``);
281
+ if (config.hasSpecRuntime) {
282
+ console.log(`✅ Spec runtime available`);
283
+ console.log(` Found ${config.specFiles.length} spec file(s):`);
284
+ config.specFiles.slice(0, 5).forEach((file) => {
285
+ console.log(` - ${path.relative(config.projectRoot, file)}`);
286
+ });
287
+ if (config.specFiles.length > 5) {
288
+ console.log(` ... and ${config.specFiles.length - 5} more`);
289
+ }
290
+ }
291
+ else {
292
+ console.log(`❌ No spec runtime found`);
293
+ }
294
+ console.log(``);
295
+ if (config.hasLegacyRuntime) {
296
+ console.log(`✅ Legacy runtime available`);
297
+ if (config.legacyConfig) {
298
+ console.log(` Config: ${path.relative(config.projectRoot, config.legacyConfig)}`);
299
+ }
300
+ }
301
+ else {
302
+ console.log(`❌ No legacy runtime found`);
303
+ }
304
+ console.log(``);
305
+ const validation = validateExecutionMode(config);
306
+ if (validation.warnings.length > 0) {
307
+ console.log(`⚠️ Warnings:`);
308
+ validation.warnings.forEach((warning) => {
309
+ console.log(` ${warning}`);
310
+ });
311
+ console.log(``);
312
+ }
313
+ if (validation.errors.length > 0) {
314
+ console.log(`❌ Errors:`);
315
+ validation.errors.forEach((error) => {
316
+ console.log(` ${error}`);
317
+ });
318
+ console.log(``);
319
+ }
320
+ const recommended = getRecommendedExecutionMode(config);
321
+ console.log(`💡 Recommended mode: ${recommended.toUpperCase()}`);
322
+ if (config.mode === "auto") {
323
+ console.log(`🔄 Auto mode will use: ${recommended.toUpperCase()}`);
324
+ }
325
+ }
326
+ /**
327
+ * Environment variable helpers
328
+ */
329
+ exports.ENV_VARS = {
330
+ EXECUTION_MODE: "EVALGATE_RUNTIME",
331
+ POSSIBLE_VALUES: ["legacy", "spec", "auto"],
332
+ DEFAULT: "auto",
333
+ };
334
+ /**
335
+ * Check if environment variable is set
336
+ */
337
+ function hasExecutionModeEnv() {
338
+ return !!process.env.EVALGATE_RUNTIME;
339
+ }
340
+ /**
341
+ * Get current environment variable value
342
+ */
343
+ function getExecutionModeEnv() {
344
+ return process.env.EVALGATE_RUNTIME;
345
+ }
346
+ /**
347
+ * Set execution mode environment variable
348
+ */
349
+ function setExecutionModeEnv(mode) {
350
+ process.env.EVALGATE_RUNTIME = mode;
351
+ }
352
+ /**
353
+ * Clear execution mode environment variable
354
+ */
355
+ function clearExecutionModeEnv() {
356
+ delete process.env.EVALGATE_RUNTIME;
357
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * EvalGate Local Executor - Layer 1 Foundation
3
+ *
4
+ * Local execution engine that runs specifications without database coupling.
5
+ * Implements the execution interface for the new programming model.
6
+ */
7
+ import type { LocalExecutor } from "./types";
8
+ /**
9
+ * Create a new local executor
10
+ */
11
+ export declare function createLocalExecutor(): LocalExecutor;
12
+ /**
13
+ * Default local executor instance
14
+ * For convenience in simple use cases
15
+ */
16
+ export declare const defaultLocalExecutor: LocalExecutor;
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ /**
3
+ * EvalGate Local Executor - Layer 1 Foundation
4
+ *
5
+ * Local execution engine that runs specifications without database coupling.
6
+ * Implements the execution interface for the new programming model.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.defaultLocalExecutor = void 0;
10
+ exports.createLocalExecutor = createLocalExecutor;
11
+ const types_1 = require("./types");
12
+ /**
13
+ * Local executor implementation
14
+ * Runs specifications in the current process without external dependencies
15
+ */
16
+ class LocalExecutorImpl {
17
+ constructor() {
18
+ this.type = "local";
19
+ this.capabilities = {
20
+ type: "local",
21
+ parallel: true,
22
+ maxParallel: 4, // Conservative default
23
+ supportedModels: ["*"], // Supports any model via executor function
24
+ costTracking: false, // No built-in cost tracking for local execution
25
+ streaming: false, // No streaming for local execution
26
+ };
27
+ }
28
+ /**
29
+ * Execute a single specification with safe error boundaries
30
+ */
31
+ async executeSpec(spec, input) {
32
+ const startTime = Date.now();
33
+ let classification = "passed";
34
+ try {
35
+ // Create execution context
36
+ const context = {
37
+ input,
38
+ metadata: spec.metadata,
39
+ options: {
40
+ model: spec.config?.model,
41
+ budget: spec.config?.budget,
42
+ timeout: spec.config?.timeout,
43
+ },
44
+ };
45
+ // Execute specification with timeout
46
+ const timeout = spec.config?.timeout || 30000; // 30 second default
47
+ const result = await this.executeWithTimeout(spec.executor, context, timeout);
48
+ // Add execution duration
49
+ result.durationMs = Date.now() - startTime;
50
+ // Determine classification
51
+ classification = result.pass ? "passed" : "failed";
52
+ return {
53
+ ...result,
54
+ classification,
55
+ };
56
+ }
57
+ catch (error) {
58
+ const duration = Date.now() - startTime;
59
+ let errorEnvelope;
60
+ if (error instanceof Error && error.name === "TimeoutError") {
61
+ classification = "timeout";
62
+ errorEnvelope = {
63
+ classification: "timeout_error",
64
+ code: "TIMEOUT",
65
+ message: `Specification execution timed out after ${duration}ms`,
66
+ stack: error.stack,
67
+ testId: spec.id,
68
+ filePath: spec.filePath,
69
+ position: spec.position,
70
+ timestamp: new Date().toISOString(),
71
+ };
72
+ }
73
+ else {
74
+ classification = "error";
75
+ // Create EvalExecutionError wrapper
76
+ const execError = new types_1.EvalExecutionError(error instanceof Error ? error.message : String(error), {
77
+ testId: spec.id,
78
+ filePath: spec.filePath,
79
+ position: spec.position,
80
+ code: "EXECUTION_ERROR",
81
+ originalError: error instanceof Error ? error : undefined,
82
+ });
83
+ errorEnvelope = execError.toEnvelope();
84
+ }
85
+ return {
86
+ pass: false,
87
+ score: 0,
88
+ error: error instanceof Error ? error.message : String(error),
89
+ durationMs: duration,
90
+ classification,
91
+ errorEnvelope,
92
+ };
93
+ }
94
+ }
95
+ /**
96
+ * Execute multiple specifications
97
+ */
98
+ async executeSpecs(specs, inputs) {
99
+ if (specs.length !== inputs.length) {
100
+ throw new types_1.SpecExecutionError("Number of specs must match number of inputs", {
101
+ specCount: specs.length,
102
+ inputCount: inputs.length,
103
+ });
104
+ }
105
+ // For now, execute sequentially
106
+ // In Layer 3, we'll add parallel execution with worker pools
107
+ const results = [];
108
+ for (let i = 0; i < specs.length; i++) {
109
+ const result = await this.executeSpec(specs[i], inputs[i]);
110
+ results.push(result);
111
+ }
112
+ return results;
113
+ }
114
+ /**
115
+ * Get executor capabilities
116
+ */
117
+ getCapabilities() {
118
+ return this.capabilities;
119
+ }
120
+ /**
121
+ * Execute with timeout protection
122
+ */
123
+ async executeWithTimeout(fn, context, timeoutMs) {
124
+ return new Promise((resolve, reject) => {
125
+ const timer = setTimeout(() => {
126
+ const error = new Error(`Execution timed out after ${timeoutMs}ms`);
127
+ error.name = "TimeoutError";
128
+ reject(error);
129
+ }, timeoutMs);
130
+ fn(context)
131
+ .then((result) => {
132
+ clearTimeout(timer);
133
+ resolve(result);
134
+ })
135
+ .catch((error) => {
136
+ clearTimeout(timer);
137
+ reject(error);
138
+ });
139
+ });
140
+ }
141
+ }
142
+ /**
143
+ * Create a new local executor
144
+ */
145
+ function createLocalExecutor() {
146
+ return new LocalExecutorImpl();
147
+ }
148
+ /**
149
+ * Default local executor instance
150
+ * For convenience in simple use cases
151
+ */
152
+ exports.defaultLocalExecutor = createLocalExecutor();
@@ -0,0 +1,78 @@
1
+ /**
2
+ * EvalGate Runtime Registry - Layer 1 Foundation
3
+ *
4
+ * Scoped registry with proper lifecycle management.
5
+ * Prevents cross-run contamination and memory leaks.
6
+ */
7
+ import type { EvalRuntime } from "./types";
8
+ /**
9
+ * Runtime interface with lifecycle management
10
+ * Ensures proper cleanup and prevents resource leaks
11
+ */
12
+ export interface RuntimeHandle {
13
+ /** Runtime instance */
14
+ runtime: EvalRuntime;
15
+ /** defineEval function bound to this runtime */
16
+ defineEval: typeof import("./eval").defineEval;
17
+ /** Dispose runtime and clean up resources */
18
+ dispose(): void;
19
+ /** Create runtime snapshot for persistence */
20
+ snapshot(): RuntimeSnapshot;
21
+ /** Load runtime from snapshot */
22
+ load(snapshot: RuntimeSnapshot): void;
23
+ }
24
+ /**
25
+ * Runtime snapshot for persistence and recovery
26
+ */
27
+ export interface RuntimeSnapshot {
28
+ /** Runtime metadata */
29
+ runtimeId: string;
30
+ namespace: string;
31
+ createdAt: string;
32
+ /** Serialized specifications */
33
+ specs: SerializedSpec[];
34
+ /** Snapshot version for compatibility */
35
+ version: string;
36
+ }
37
+ /**
38
+ * Serialized specification for snapshot
39
+ */
40
+ export interface SerializedSpec {
41
+ id: string;
42
+ name: string;
43
+ filePath: string;
44
+ position: {
45
+ line: number;
46
+ column: number;
47
+ };
48
+ description?: string;
49
+ tags?: string[];
50
+ metadata?: Record<string, unknown>;
51
+ config?: {
52
+ timeout?: number;
53
+ retries?: number;
54
+ budget?: string;
55
+ model?: string | "auto";
56
+ };
57
+ /** Serialized executor function (placeholder) */
58
+ executorSerialized: boolean;
59
+ }
60
+ /**
61
+ * Create a new scoped runtime with lifecycle management
62
+ * Returns a handle for proper resource management
63
+ */
64
+ export declare function createEvalRuntime(projectRoot?: string): RuntimeHandle;
65
+ /**
66
+ * Helper function for safe runtime execution with automatic cleanup
67
+ * Ensures runtime is disposed even if an exception is thrown
68
+ */
69
+ export declare function withRuntime<T>(projectRoot: string, fn: (handle: RuntimeHandle) => Promise<T>): Promise<T>;
70
+ export declare function getActiveRuntime(): EvalRuntime;
71
+ /**
72
+ * Set the active runtime (for backward compatibility)
73
+ */
74
+ export declare function setActiveRuntime(runtime: EvalRuntime): void;
75
+ /**
76
+ * Dispose the active runtime (for backward compatibility)
77
+ */
78
+ export declare function disposeActiveRuntime(): void;