@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,112 @@
1
+ "use strict";
2
+ /**
3
+ * CI context capture and idempotency key for --onFail import.
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.captureCiContext = captureCiContext;
40
+ exports.computeIdempotencyKey = computeIdempotencyKey;
41
+ const node_crypto_1 = require("node:crypto");
42
+ const fs = __importStar(require("node:fs"));
43
+ function readPrFromEventPath() {
44
+ const path = process.env.GITHUB_EVENT_PATH;
45
+ if (!path)
46
+ return undefined;
47
+ try {
48
+ const raw = fs.readFileSync(path, "utf8");
49
+ const event = JSON.parse(raw);
50
+ return event.pull_request?.number;
51
+ }
52
+ catch {
53
+ return undefined;
54
+ }
55
+ }
56
+ function readPrFromRef() {
57
+ const ref = process.env.GITHUB_REF;
58
+ if (!ref)
59
+ return undefined;
60
+ const m = ref.match(/^refs\/pull\/(\d+)\/merge$/);
61
+ return m ? parseInt(m[1], 10) : undefined;
62
+ }
63
+ function captureCiContext() {
64
+ const repo = process.env.GITHUB_REPOSITORY;
65
+ const sha = process.env.GITHUB_SHA;
66
+ const ref = process.env.GITHUB_REF;
67
+ const runId = process.env.GITHUB_RUN_ID;
68
+ const _workflow = process.env.GITHUB_WORKFLOW;
69
+ const _job = process.env.GITHUB_JOB;
70
+ const actor = process.env.GITHUB_ACTOR;
71
+ if (!repo && !sha)
72
+ return undefined;
73
+ let provider = "unknown";
74
+ if (process.env.GITHUB_ACTIONS)
75
+ provider = "github";
76
+ else if (process.env.GITLAB_CI)
77
+ provider = "gitlab";
78
+ else if (process.env.CIRCLECI)
79
+ provider = "circle";
80
+ let runUrl;
81
+ if (repo && runId) {
82
+ runUrl = `https://github.com/${repo}/actions/runs/${runId}`;
83
+ }
84
+ let pr;
85
+ if (process.env.GITHUB_EVENT_NAME === "pull_request") {
86
+ pr = readPrFromEventPath() ?? readPrFromRef();
87
+ }
88
+ return {
89
+ provider,
90
+ repo,
91
+ sha,
92
+ branch: ref?.startsWith("refs/heads/")
93
+ ? ref.slice("refs/heads/".length)
94
+ : ref,
95
+ runUrl,
96
+ actor,
97
+ pr,
98
+ };
99
+ }
100
+ function computeIdempotencyKey(evaluationId, ci) {
101
+ const repo = ci.repo ?? process.env.GITHUB_REPOSITORY;
102
+ const workflow = process.env.GITHUB_WORKFLOW ?? "";
103
+ const job = process.env.GITHUB_JOB ?? "";
104
+ const sha = ci.sha ?? process.env.GITHUB_SHA ?? "";
105
+ if (!repo || !sha)
106
+ return undefined;
107
+ const input = `${repo}.${workflow}.${job}.${sha}.${evaluationId}`;
108
+ return hashSha256(input);
109
+ }
110
+ function hashSha256(input) {
111
+ return (0, node_crypto_1.createHash)("sha256").update(input, "utf8").digest("hex");
112
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * UX-401: One-command CI loop (evalgate ci)
3
+ *
4
+ * Provides a single command teams put in .github/workflows/* and never think about again.
5
+ */
6
+ import type { DiffResult } from "./diff";
7
+ import type { RunResult } from "./run";
8
+ /**
9
+ * CI command options
10
+ */
11
+ export interface CIOptions {
12
+ /** Base reference for diff comparison */
13
+ base?: string;
14
+ /** Run only impacted specs */
15
+ impactedOnly?: boolean;
16
+ /** Output format */
17
+ format?: "human" | "json" | "github";
18
+ /** Write run results */
19
+ writeResults?: boolean;
20
+ }
21
+ /**
22
+ * CI execution result
23
+ */
24
+ export interface CIResult {
25
+ /** Success status */
26
+ success: boolean;
27
+ /** Exit code */
28
+ exitCode: number;
29
+ /** Execution narrative */
30
+ narrative: string;
31
+ /** Run result (if executed) */
32
+ runResult?: RunResult;
33
+ /** Diff result (if executed) */
34
+ diffResult?: DiffResult;
35
+ /** Error message (if failed) */
36
+ error?: string;
37
+ }
38
+ /**
39
+ * Run CI command
40
+ */
41
+ export declare function runCI(options: CIOptions, projectRoot?: string): Promise<CIResult>;
42
+ /**
43
+ * CLI entry point
44
+ */
45
+ export declare function runCICLI(options: CIOptions): Promise<void>;
package/dist/cli/ci.js ADDED
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ /**
3
+ * UX-401: One-command CI loop (evalgate ci)
4
+ *
5
+ * Provides a single command teams put in .github/workflows/* and never think about again.
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.runCI = runCI;
42
+ exports.runCICLI = runCICLI;
43
+ const fs = __importStar(require("node:fs/promises"));
44
+ const diff_1 = require("./diff");
45
+ const discover_1 = require("./discover");
46
+ const impact_analysis_1 = require("./impact-analysis");
47
+ const run_1 = require("./run");
48
+ const workspace_1 = require("./workspace");
49
+ /**
50
+ * Run CI command
51
+ */
52
+ async function runCI(options, projectRoot = process.cwd()) {
53
+ const workspace = (0, workspace_1.resolveEvalWorkspace)(projectRoot);
54
+ const narrative = [];
55
+ try {
56
+ // 1. Ensure .evalgate workspace exists
57
+ await fs.mkdir(workspace.evalDir, { recursive: true });
58
+ narrative.push("✅ workspace ok");
59
+ // 2. Ensure manifest exists (build if missing)
60
+ let manifestExists = true;
61
+ try {
62
+ await fs.access(workspace.manifestPath);
63
+ }
64
+ catch {
65
+ manifestExists = false;
66
+ }
67
+ if (!manifestExists) {
68
+ console.log("📋 Building evaluation manifest...");
69
+ await (0, discover_1.discoverSpecs)({ manifest: true });
70
+ narrative.push("→ manifest built");
71
+ }
72
+ else {
73
+ narrative.push("→ manifest ok");
74
+ }
75
+ // 3. Run impact analysis if --impacted-only
76
+ let impactedSpecCount;
77
+ if (options.impactedOnly) {
78
+ const impactResult = await (0, impact_analysis_1.runImpactAnalysis)({
79
+ baseBranch: options.base || "main",
80
+ }, projectRoot);
81
+ impactedSpecCount = impactResult.metadata.impactedCount;
82
+ narrative.push(`→ impacted specs ${impactedSpecCount}`);
83
+ }
84
+ else {
85
+ narrative.push("→ running all specs");
86
+ }
87
+ // 4. Run evaluations
88
+ const runResult = await (0, run_1.runEvaluations)({
89
+ impactedOnly: options.impactedOnly,
90
+ baseBranch: options.base,
91
+ writeResults: options.writeResults ?? true, // Always write results for CI
92
+ }, projectRoot);
93
+ narrative.push(`→ runId ${runResult.runId}`);
94
+ // 5. Run diff if --base provided
95
+ let diffResult;
96
+ if (options.base) {
97
+ diffResult = await (0, diff_1.runDiff)({
98
+ base: options.base,
99
+ head: "last",
100
+ });
101
+ if (diffResult.summary.regressions > 0) {
102
+ narrative.push(`→ diff ${diffResult.summary.regressions} regressions`);
103
+ return {
104
+ success: false,
105
+ exitCode: 1,
106
+ narrative: narrative.join(" "),
107
+ runResult,
108
+ diffResult,
109
+ };
110
+ }
111
+ else {
112
+ narrative.push("→ diff clean");
113
+ }
114
+ }
115
+ else {
116
+ narrative.push("→ no diff");
117
+ }
118
+ // 6. Check for run failures
119
+ if (runResult.summary.failed > 0) {
120
+ return {
121
+ success: false,
122
+ exitCode: 1,
123
+ narrative: narrative.join(" "),
124
+ runResult,
125
+ diffResult,
126
+ };
127
+ }
128
+ return {
129
+ success: true,
130
+ exitCode: 0,
131
+ narrative: narrative.join(" "),
132
+ runResult,
133
+ diffResult,
134
+ };
135
+ }
136
+ catch (error) {
137
+ const errorMessage = error instanceof Error ? error.message : String(error);
138
+ // Print next step for debugging
139
+ printNextStep(errorMessage, options, workspace);
140
+ return {
141
+ success: false,
142
+ exitCode: 2, // Config/infra issue
143
+ narrative: narrative.join(" "),
144
+ error: errorMessage,
145
+ };
146
+ }
147
+ }
148
+ /**
149
+ * Print copy/paste debug flow
150
+ */
151
+ function printNextStep(error, options, workspace) {
152
+ console.log("\n🔧 Next step for debugging:");
153
+ if (error.includes("No evaluation manifest found")) {
154
+ console.log(" evalgate discover --manifest");
155
+ }
156
+ else if (error.includes("Base run report not found in CI environment")) {
157
+ console.log(` Download base artifact and run: evalgate diff --base .evalgate/base-run.json --head ${workspace.lastRunPath}`);
158
+ }
159
+ else if (options.base && error.includes("Base run report not found")) {
160
+ console.log(` evalgate explain --report ${workspace.lastRunPath}`);
161
+ }
162
+ else {
163
+ console.log(` evalgate explain --report ${workspace.lastRunPath}`);
164
+ }
165
+ console.log(` Artifacts: ${workspace.runsDir}/`);
166
+ }
167
+ /**
168
+ * CLI entry point
169
+ */
170
+ async function runCICLI(options) {
171
+ const result = await runCI(options);
172
+ // Print narrative
173
+ console.log(`🤖 ${result.narrative}`);
174
+ // Print detailed results if not clean
175
+ if (!result.success && result.runResult) {
176
+ console.log("\n📊 Run Results:");
177
+ console.log(` ✅ Passed: ${result.runResult.summary.passed}`);
178
+ console.log(` ❌ Failed: ${result.runResult.summary.failed}`);
179
+ console.log(` 📊 Pass Rate: ${(result.runResult.summary.passRate * 100).toFixed(1)}%`);
180
+ }
181
+ if (!result.success && result.diffResult) {
182
+ console.log("\n🔄 Diff Results:");
183
+ console.log(` 📉 Regressions: ${result.diffResult.summary.regressions}`);
184
+ console.log(` 📈 Improvements: ${result.diffResult.summary.improvements}`);
185
+ console.log(` 📊 Pass Rate Delta: ${(result.diffResult.summary.passRateDelta * 100).toFixed(1)}%`);
186
+ }
187
+ if (result.error) {
188
+ console.log(`\n❌ Error: ${result.error}`);
189
+ }
190
+ // Exit with appropriate code
191
+ process.exit(result.exitCode);
192
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * EvalGate config loader
3
+ * Discovery: evalgate.config.json → evalgate.config.js → evalgate.config.cjs → package.json evalgate
4
+ */
5
+ import { type ProfileName } from "./profiles";
6
+ export interface EvalAIConfig {
7
+ evaluationId?: string;
8
+ baseUrl?: string;
9
+ minScore?: number;
10
+ minN?: number;
11
+ maxDrop?: number;
12
+ warnDrop?: number;
13
+ allowWeakEvidence?: boolean;
14
+ baseline?: "published" | "previous" | "production" | "auto";
15
+ profile?: ProfileName;
16
+ /** Monorepo: package path → config. Key = path relative to config dir (e.g. "apps/web", "packages/api"). */
17
+ packages?: Record<string, Partial<EvalAIConfig>>;
18
+ }
19
+ /**
20
+ * Find config file path in directory, walking up to root
21
+ */
22
+ export declare function findConfigPath(cwd?: string): string | null;
23
+ /**
24
+ * Load config from file system
25
+ */
26
+ export declare function loadConfig(cwd?: string): EvalAIConfig | null;
27
+ /**
28
+ * Merge config with CLI args. Priority: args > profile > config > defaults.
29
+ */
30
+ export declare function mergeConfigWithArgs(config: EvalAIConfig | null, args: Partial<Record<string, string | number | boolean>>): Partial<EvalAIConfig>;
@@ -0,0 +1,230 @@
1
+ "use strict";
2
+ /**
3
+ * EvalGate config loader
4
+ * Discovery: evalgate.config.json → evalgate.config.js → evalgate.config.cjs → package.json evalgate
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.findConfigPath = findConfigPath;
41
+ exports.loadConfig = loadConfig;
42
+ exports.mergeConfigWithArgs = mergeConfigWithArgs;
43
+ const fs = __importStar(require("node:fs"));
44
+ const path = __importStar(require("node:path"));
45
+ const profiles_1 = require("./profiles");
46
+ const CONFIG_FILES = [
47
+ "evalgate.config.json",
48
+ "evalgate.config.js",
49
+ "evalgate.config.cjs",
50
+ "evalai.config.json",
51
+ "evalai.config.js",
52
+ "evalai.config.cjs",
53
+ ];
54
+ /**
55
+ * Find config file path in directory, walking up to root
56
+ */
57
+ function findConfigPath(cwd = process.cwd()) {
58
+ let dir = path.resolve(cwd);
59
+ const root = path.parse(dir).root;
60
+ while (dir !== root) {
61
+ for (const file of CONFIG_FILES) {
62
+ const filePath = path.join(dir, file);
63
+ if (fs.existsSync(filePath)) {
64
+ return filePath;
65
+ }
66
+ }
67
+ // Check package.json for evalgate or evalai field
68
+ const pkgPath = path.join(dir, "package.json");
69
+ if (fs.existsSync(pkgPath)) {
70
+ try {
71
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
72
+ if (pkg.evalgate != null || pkg.evalai != null) {
73
+ return pkgPath;
74
+ }
75
+ }
76
+ catch {
77
+ // ignore
78
+ }
79
+ }
80
+ dir = path.dirname(dir);
81
+ }
82
+ return null;
83
+ }
84
+ /**
85
+ * Load config from file system
86
+ */
87
+ function loadConfig(cwd = process.cwd()) {
88
+ const configPath = findConfigPath(cwd);
89
+ if (!configPath)
90
+ return null;
91
+ try {
92
+ let config = null;
93
+ if (configPath.endsWith("package.json")) {
94
+ const pkg = JSON.parse(fs.readFileSync(configPath, "utf-8"));
95
+ config = (pkg.evalgate ?? pkg.evalai);
96
+ }
97
+ else {
98
+ const content = fs.readFileSync(configPath, "utf-8");
99
+ if (configPath.endsWith(".json")) {
100
+ config = JSON.parse(content);
101
+ }
102
+ else if (configPath.endsWith(".js") || configPath.endsWith(".cjs")) {
103
+ try {
104
+ config = JSON.parse(content);
105
+ }
106
+ catch {
107
+ return null;
108
+ }
109
+ }
110
+ }
111
+ if (!config)
112
+ return null;
113
+ if (config.packages && Object.keys(config.packages).length > 0) {
114
+ const configDir = path.dirname(configPath);
115
+ const rel = path.relative(configDir, path.resolve(cwd));
116
+ const relNorm = rel.split(path.sep).join("/");
117
+ const pkgConfig = config.packages[relNorm];
118
+ if (pkgConfig) {
119
+ return { ...config, ...pkgConfig, packages: config.packages };
120
+ }
121
+ for (const key of Object.keys(config.packages)) {
122
+ if (relNorm === key || relNorm.startsWith(`${key}/`)) {
123
+ return {
124
+ ...config,
125
+ ...config.packages[key],
126
+ packages: config.packages,
127
+ };
128
+ }
129
+ }
130
+ }
131
+ return config;
132
+ }
133
+ catch {
134
+ return null;
135
+ }
136
+ }
137
+ /**
138
+ * Merge config with CLI args. Priority: args > profile > config > defaults.
139
+ */
140
+ function mergeConfigWithArgs(config, args) {
141
+ const merged = {};
142
+ if (config) {
143
+ if (config.evaluationId)
144
+ merged.evaluationId = config.evaluationId;
145
+ if (config.baseUrl)
146
+ merged.baseUrl = config.baseUrl;
147
+ if (config.minScore != null)
148
+ merged.minScore = config.minScore;
149
+ if (config.minN != null)
150
+ merged.minN = config.minN;
151
+ if (config.maxDrop != null)
152
+ merged.maxDrop = config.maxDrop;
153
+ if (config.warnDrop != null)
154
+ merged.warnDrop = config.warnDrop;
155
+ if (config.allowWeakEvidence != null)
156
+ merged.allowWeakEvidence = config.allowWeakEvidence;
157
+ if (config.baseline)
158
+ merged.baseline = config.baseline;
159
+ if (config.profile)
160
+ merged.profile = config.profile;
161
+ }
162
+ // Profile defaults (from --profile or config.profile). Apply before args override.
163
+ const profileName = (args.profile ?? merged.profile);
164
+ if (profileName && profileName in profiles_1.PROFILES) {
165
+ const profile = profiles_1.PROFILES[profileName];
166
+ if (merged.minScore === undefined && args.minScore === undefined)
167
+ merged.minScore = profile.minScore;
168
+ if (merged.maxDrop === undefined && args.maxDrop === undefined)
169
+ merged.maxDrop = profile.maxDrop;
170
+ if (merged.warnDrop === undefined &&
171
+ args.warnDrop === undefined &&
172
+ "warnDrop" in profile)
173
+ merged.warnDrop = profile.warnDrop;
174
+ if (merged.minN === undefined && args.minN === undefined)
175
+ merged.minN = profile.minN;
176
+ if (merged.allowWeakEvidence === undefined &&
177
+ args.allowWeakEvidence === undefined)
178
+ merged.allowWeakEvidence = profile.allowWeakEvidence;
179
+ }
180
+ // Args override
181
+ if (args.evaluationId !== undefined && args.evaluationId !== "") {
182
+ merged.evaluationId = String(args.evaluationId);
183
+ }
184
+ if (args.baseUrl !== undefined && args.baseUrl !== "") {
185
+ merged.baseUrl = String(args.baseUrl);
186
+ }
187
+ if (args.minScore !== undefined) {
188
+ merged.minScore =
189
+ typeof args.minScore === "number"
190
+ ? args.minScore
191
+ : parseInt(String(args.minScore), 10);
192
+ }
193
+ if (args.maxDrop !== undefined) {
194
+ merged.maxDrop =
195
+ typeof args.maxDrop === "number"
196
+ ? args.maxDrop
197
+ : parseInt(String(args.maxDrop), 10);
198
+ }
199
+ if (args.warnDrop !== undefined) {
200
+ merged.warnDrop =
201
+ typeof args.warnDrop === "number"
202
+ ? args.warnDrop
203
+ : parseInt(String(args.warnDrop), 10);
204
+ }
205
+ if (args.minN !== undefined) {
206
+ merged.minN =
207
+ typeof args.minN === "number"
208
+ ? args.minN
209
+ : parseInt(String(args.minN), 10);
210
+ }
211
+ if (args.allowWeakEvidence !== undefined) {
212
+ merged.allowWeakEvidence =
213
+ args.allowWeakEvidence === true ||
214
+ args.allowWeakEvidence === "true" ||
215
+ args.allowWeakEvidence === "1";
216
+ }
217
+ if (args.baseline !== undefined && args.baseline !== "") {
218
+ const b = String(args.baseline);
219
+ if (b === "auto" || b === "previous" || b === "production") {
220
+ merged.baseline = b;
221
+ }
222
+ else {
223
+ merged.baseline = "published";
224
+ }
225
+ }
226
+ if (args.profile !== undefined && args.profile !== "") {
227
+ merged.profile = String(args.profile);
228
+ }
229
+ return merged;
230
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Standardized exit codes for evalgate check.
3
+ */
4
+ export declare const EXIT: {
5
+ readonly PASS: 0;
6
+ readonly SCORE_BELOW: 1;
7
+ readonly REGRESSION: 2;
8
+ readonly POLICY_VIOLATION: 3;
9
+ readonly API_ERROR: 4;
10
+ readonly BAD_ARGS: 5;
11
+ readonly LOW_N: 6;
12
+ readonly WEAK_EVIDENCE: 7;
13
+ /** Near-regression: score dropped within warn band (warnDrop ≤ drop < maxDrop) */
14
+ readonly WARN_REGRESSION: 8;
15
+ };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EXIT = void 0;
4
+ /**
5
+ * Standardized exit codes for evalgate check.
6
+ */
7
+ exports.EXIT = {
8
+ PASS: 0,
9
+ SCORE_BELOW: 1,
10
+ REGRESSION: 2,
11
+ POLICY_VIOLATION: 3,
12
+ API_ERROR: 4,
13
+ BAD_ARGS: 5,
14
+ LOW_N: 6,
15
+ WEAK_EVIDENCE: 7,
16
+ /** Near-regression: score dropped within warn band (warnDrop ≤ drop < maxDrop) */
17
+ WARN_REGRESSION: 8,
18
+ };