@wix/evalforge-evaluator 0.163.0 → 0.165.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/build/index.mjs CHANGED
@@ -423,9 +423,13 @@ import {
423
423
 
424
424
  // src/run-scenario/environment.ts
425
425
  import { mkdirSync, existsSync, rmSync, readFileSync, writeFileSync } from "fs";
426
+ import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
426
427
  import { tmpdir } from "os";
427
- import path from "path";
428
- import { fetchGitHubFolder } from "@wix/evalforge-github-client";
428
+ import path, { sep as sep2 } from "path";
429
+ import {
430
+ fetchGitHubFolder,
431
+ fetchGitHubFile
432
+ } from "@wix/evalforge-github-client";
429
433
 
430
434
  // src/run-scenario/utils/write-files.ts
431
435
  import { mkdir, writeFile } from "fs/promises";
@@ -446,16 +450,34 @@ async function writeFilesToDirectory(targetDir, files) {
446
450
 
447
451
  // src/run-scenario/environment.ts
448
452
  async function fetchAndWriteTemplateFiles(template, workDir) {
449
- if (!template.source) {
453
+ let sourceFiles = [];
454
+ if (template.source) {
455
+ sourceFiles = await fetchGitHubFolder(template.source, {
456
+ userAgent: "EvalForge-Evaluator"
457
+ });
458
+ } else if (template.sourceFiles?.length) {
459
+ sourceFiles = template.sourceFiles;
460
+ } else {
450
461
  console.warn(
451
462
  `Template "${template.name}" has no source configured, creating empty directory`
452
463
  );
453
- return;
454
464
  }
455
- const files = await fetchGitHubFolder(template.source, {
456
- userAgent: "EvalForge-Evaluator"
457
- });
458
- await writeFilesToDirectory(workDir, files);
465
+ await writeFilesToDirectory(workDir, sourceFiles);
466
+ await Promise.all(
467
+ (template.extraFiles ?? []).map(async (ef) => {
468
+ const content = ef.gitSource ? await fetchGitHubFile(ef.gitSource, {
469
+ userAgent: "EvalForge-Evaluator"
470
+ }) : ef.content ?? "";
471
+ const dest = path.resolve(workDir, ef.path);
472
+ if (!dest.startsWith(workDir + sep2)) {
473
+ throw new Error(
474
+ `Extra file path escapes working directory: "${ef.path}"`
475
+ );
476
+ }
477
+ await mkdir2(path.dirname(dest), { recursive: true });
478
+ await writeFile2(dest, content, "utf8");
479
+ })
480
+ );
459
481
  }
460
482
  function writeWixEnvFile(workDir) {
461
483
  const configPath = path.join(workDir, "wix.config.json");
@@ -618,7 +640,7 @@ import {
618
640
  } from "@wix/evalforge-types";
619
641
 
620
642
  // src/run-scenario/agents/claude-code/write-skills.ts
621
- import { mkdir as mkdir2 } from "fs/promises";
643
+ import { mkdir as mkdir3 } from "fs/promises";
622
644
  import { join } from "path";
623
645
  import { fetchGitHubFolder as fetchGitHubFolder2 } from "@wix/evalforge-github-client";
624
646
  async function writeSkillsToFilesystem(cwd, skills, fetchFn = fetchGitHubFolder2) {
@@ -629,7 +651,7 @@ async function writeSkillsToFilesystem(cwd, skills, fetchFn = fetchGitHubFolder2
629
651
  async function writeSkillToFilesystem(cwd, skill, fetchFn = fetchGitHubFolder2) {
630
652
  const skillName = skill.name;
631
653
  const skillDir = join(cwd, ".claude", "skills", skillName);
632
- await mkdir2(skillDir, { recursive: true });
654
+ await mkdir3(skillDir, { recursive: true });
633
655
  const version = skill.latestVersion;
634
656
  if (version?.files && version.files.length > 0) {
635
657
  await writeFilesToDirectory(skillDir, version.files);
@@ -671,7 +693,7 @@ function resolveTimeoutMs(maxTurns, maxDurationMs) {
671
693
  import { randomUUID } from "crypto";
672
694
 
673
695
  // src/run-scenario/agents/claude-code/write-mcp.ts
674
- import { writeFile as writeFile2 } from "fs/promises";
696
+ import { writeFile as writeFile3 } from "fs/promises";
675
697
  import { join as join3 } from "path";
676
698
  import { MCP_SERVERS_JSON_KEY } from "@wix/evalforge-types";
677
699
 
@@ -739,15 +761,15 @@ async function writeMcpToFilesystem(cwd, mcps) {
739
761
  2
740
762
  );
741
763
  const filePath = join3(cwd, ".mcp.json");
742
- await writeFile2(filePath, content, "utf8");
764
+ await writeFile3(filePath, content, "utf8");
743
765
  console.log(`[MCP] Written to ${filePath}`);
744
766
  }
745
767
 
746
768
  // src/run-scenario/agents/claude-code/write-sub-agents.ts
747
- import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
769
+ import { mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
748
770
  import { join as join4 } from "path";
749
771
  import {
750
- fetchGitHubFile
772
+ fetchGitHubFile as fetchGitHubFile2
751
773
  } from "@wix/evalforge-github-client";
752
774
  var AGENTS_DIR = ".claude/agents";
753
775
  function toAgentFilename(name, index, nameCount) {
@@ -783,23 +805,23 @@ async function resolveSubAgentContent(agent, fetchFn) {
783
805
  }
784
806
  return agent.subAgentMd;
785
807
  }
786
- async function writeSubAgentsToFilesystem(cwd, subAgents, fetchFn = fetchGitHubFile) {
808
+ async function writeSubAgentsToFilesystem(cwd, subAgents, fetchFn = fetchGitHubFile2) {
787
809
  if (subAgents.length === 0) return;
788
810
  const agentsDir = join4(cwd, AGENTS_DIR);
789
- await mkdir3(agentsDir, { recursive: true });
811
+ await mkdir4(agentsDir, { recursive: true });
790
812
  const nameCount = /* @__PURE__ */ new Map();
791
813
  for (const [i, agent] of subAgents.entries()) {
792
814
  const filename = toAgentFilename(agent.name, i, nameCount);
793
815
  const filePath = join4(agentsDir, `${filename}.md`);
794
816
  const content = await resolveSubAgentContent(agent, fetchFn);
795
- await writeFile3(filePath, content, "utf8");
817
+ await writeFile4(filePath, content, "utf8");
796
818
  }
797
819
  console.log(`[SubAgents] Written to ${agentsDir}`);
798
820
  }
799
821
 
800
822
  // src/run-scenario/agents/claude-code/write-rules.ts
801
- import { mkdir as mkdir4, writeFile as writeFile4, readFile as readFile2 } from "fs/promises";
802
- import { join as join5, resolve as resolve2, sep as sep2 } from "path";
823
+ import { mkdir as mkdir5, writeFile as writeFile5, readFile as readFile2 } from "fs/promises";
824
+ import { join as join5, resolve as resolve2, sep as sep3 } from "path";
803
825
  var CURSOR_RULES_DIR = ".cursor/rules";
804
826
  function toRuleFilename(name, index, nameCount) {
805
827
  const base = (name || "").toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/^-+|-+$/g, "") || `rule-${index}`;
@@ -816,7 +838,7 @@ async function appendToFile(filePath, content) {
816
838
  const merged = existing ? `${existing.trimEnd()}
817
839
 
818
840
  ${content}` : content;
819
- await writeFile4(filePath, merged, "utf8");
841
+ await writeFile5(filePath, merged, "utf8");
820
842
  }
821
843
  function validateGenericDirectory(dir, cwd) {
822
844
  const trimmed = dir.trim();
@@ -832,9 +854,9 @@ function validateGenericDirectory(dir, cwd) {
832
854
  `Generic rule directory may not contain "..", got: "${dir}"`
833
855
  );
834
856
  }
835
- const normalizedCwd = cwd.endsWith(sep2) ? cwd.slice(0, -1) : cwd;
857
+ const normalizedCwd = cwd.endsWith(sep3) ? cwd.slice(0, -1) : cwd;
836
858
  const resolved = resolve2(normalizedCwd, trimmed);
837
- if (!resolved.startsWith(normalizedCwd + sep2)) {
859
+ if (!resolved.startsWith(normalizedCwd + sep3)) {
838
860
  throw new Error(
839
861
  `Generic rule directory escapes the working directory: "${dir}"`
840
862
  );
@@ -857,12 +879,12 @@ async function writeRulesToFilesystem(cwd, rules) {
857
879
  }
858
880
  case "cursor-rule": {
859
881
  if (!hasCursorRules) {
860
- await mkdir4(join5(cwd, CURSOR_RULES_DIR), { recursive: true });
882
+ await mkdir5(join5(cwd, CURSOR_RULES_DIR), { recursive: true });
861
883
  hasCursorRules = true;
862
884
  }
863
885
  const filename = toRuleFilename(rule.name, i, nameCount);
864
886
  const filePath = join5(cwd, CURSOR_RULES_DIR, `${filename}.md`);
865
- await writeFile4(filePath, rule.content, "utf8");
887
+ await writeFile5(filePath, rule.content, "utf8");
866
888
  break;
867
889
  }
868
890
  case "generic": {
@@ -871,9 +893,9 @@ async function writeRulesToFilesystem(cwd, rules) {
871
893
  cwd
872
894
  );
873
895
  const dirPath = join5(cwd, directory);
874
- await mkdir4(dirPath, { recursive: true });
896
+ await mkdir5(dirPath, { recursive: true });
875
897
  const filename = toRuleFilename(rule.name, i, nameCount);
876
- await writeFile4(join5(dirPath, `${filename}.md`), rule.content, "utf8");
898
+ await writeFile5(join5(dirPath, `${filename}.md`), rule.content, "utf8");
877
899
  break;
878
900
  }
879
901
  default: {
@@ -1182,10 +1204,10 @@ function createTraceEventFromAnyMessage(message, context, stepNumber, isComplete
1182
1204
  };
1183
1205
  }
1184
1206
  async function prepareClaudeCodeEnvironment(cwd, skills, options) {
1185
- const { mkdir: mkdirAsync, writeFile: writeFile7 } = await import("fs/promises");
1207
+ const { mkdir: mkdirAsync, writeFile: writeFile8 } = await import("fs/promises");
1186
1208
  const claudeDir = `${cwd}/.claude`;
1187
1209
  await mkdirAsync(claudeDir, { recursive: true });
1188
- await writeFile7(`${claudeDir}/settings.json`, "{}", {
1210
+ await writeFile8(`${claudeDir}/settings.json`, "{}", {
1189
1211
  flag: "wx"
1190
1212
  }).catch(() => {
1191
1213
  });
@@ -2186,7 +2208,7 @@ function tryParseJson(text) {
2186
2208
  }
2187
2209
 
2188
2210
  // src/run-scenario/agents/opencode/write-skills.ts
2189
- import { mkdir as mkdir5 } from "fs/promises";
2211
+ import { mkdir as mkdir6 } from "fs/promises";
2190
2212
  import { join as join6 } from "path";
2191
2213
  import { fetchGitHubFolder as fetchGitHubFolder3 } from "@wix/evalforge-github-client";
2192
2214
  async function writeSkillsToFilesystem2(cwd, skills, fetchFn = fetchGitHubFolder3) {
@@ -2197,7 +2219,7 @@ async function writeSkillsToFilesystem2(cwd, skills, fetchFn = fetchGitHubFolder
2197
2219
  async function writeSkillToFilesystem2(cwd, skill, fetchFn) {
2198
2220
  const skillName = skill.name;
2199
2221
  const skillDir = join6(cwd, ".opencode", "skills", skillName);
2200
- await mkdir5(skillDir, { recursive: true });
2222
+ await mkdir6(skillDir, { recursive: true });
2201
2223
  const version = skill.latestVersion;
2202
2224
  if (version?.files && version.files.length > 0) {
2203
2225
  await writeFilesToDirectory(skillDir, version.files);
@@ -2228,10 +2250,10 @@ async function writeSkillToFilesystem2(cwd, skill, fetchFn) {
2228
2250
  }
2229
2251
 
2230
2252
  // src/run-scenario/agents/opencode/write-sub-agents.ts
2231
- import { mkdir as mkdir6, writeFile as writeFile5 } from "fs/promises";
2253
+ import { mkdir as mkdir7, writeFile as writeFile6 } from "fs/promises";
2232
2254
  import { join as join7 } from "path";
2233
2255
  import {
2234
- fetchGitHubFile as fetchGitHubFile2
2256
+ fetchGitHubFile as fetchGitHubFile3
2235
2257
  } from "@wix/evalforge-github-client";
2236
2258
  var AGENTS_DIR2 = ".opencode/agents";
2237
2259
  function toAgentFilename2(name, index, nameCount) {
@@ -2267,16 +2289,16 @@ async function resolveSubAgentContent2(agent, fetchFn) {
2267
2289
  }
2268
2290
  return agent.subAgentMd;
2269
2291
  }
2270
- async function writeSubAgentsToFilesystem2(cwd, subAgents, fetchFn = fetchGitHubFile2) {
2292
+ async function writeSubAgentsToFilesystem2(cwd, subAgents, fetchFn = fetchGitHubFile3) {
2271
2293
  if (subAgents.length === 0) return;
2272
2294
  const agentsDir = join7(cwd, AGENTS_DIR2);
2273
- await mkdir6(agentsDir, { recursive: true });
2295
+ await mkdir7(agentsDir, { recursive: true });
2274
2296
  const nameCount = /* @__PURE__ */ new Map();
2275
2297
  for (const [i, agent] of subAgents.entries()) {
2276
2298
  const filename = toAgentFilename2(agent.name, i, nameCount);
2277
2299
  const filePath = join7(agentsDir, `${filename}.md`);
2278
2300
  const content = await resolveSubAgentContent2(agent, fetchFn);
2279
- await writeFile5(filePath, content, "utf8");
2301
+ await writeFile6(filePath, content, "utf8");
2280
2302
  }
2281
2303
  console.log(`[SubAgents] Written to ${agentsDir}`);
2282
2304
  }
@@ -2742,7 +2764,7 @@ function buildConversation2(timestampedEvents) {
2742
2764
  }
2743
2765
 
2744
2766
  // src/run-scenario/agents/opencode/execute.ts
2745
- import { writeFile as writeFile6, mkdir as mkdir7 } from "fs/promises";
2767
+ import { writeFile as writeFile7, mkdir as mkdir8 } from "fs/promises";
2746
2768
  import { join as join8 } from "path";
2747
2769
  var KILL_GRACE_PERIOD_MS = 5e3;
2748
2770
  var IDLE_TIMEOUT_MS = 12e4;
@@ -2769,7 +2791,7 @@ function extractToolAction(toolName, args) {
2769
2791
  }
2770
2792
  async function writePromptImages(cwd, images) {
2771
2793
  const imagesDir = join8(cwd, "prompt-images");
2772
- await mkdir7(imagesDir, { recursive: true });
2794
+ await mkdir8(imagesDir, { recursive: true });
2773
2795
  const filePaths = [];
2774
2796
  for (let i = 0; i < images.length; i++) {
2775
2797
  const img = images[i];
@@ -2777,7 +2799,7 @@ async function writePromptImages(cwd, images) {
2777
2799
  const filename = `image-${i}.${ext}`;
2778
2800
  const filepath = join8(imagesDir, filename);
2779
2801
  const buffer = Buffer.from(img.base64, "base64");
2780
- await writeFile6(filepath, buffer);
2802
+ await writeFile7(filepath, buffer);
2781
2803
  filePaths.push(filepath);
2782
2804
  }
2783
2805
  return filePaths;
@@ -2869,8 +2891,8 @@ async function prepareOpenCodeEnvironment(cwd, skills, options) {
2869
2891
  }
2870
2892
  async function writeSystemPromptRule(cwd, systemPrompt) {
2871
2893
  const rulesDir = join8(cwd, ".opencode", "rules");
2872
- await mkdir7(rulesDir, { recursive: true });
2873
- await writeFile6(
2894
+ await mkdir8(rulesDir, { recursive: true });
2895
+ await writeFile7(
2874
2896
  join8(rulesDir, "evalforge-system-prompt.md"),
2875
2897
  systemPrompt,
2876
2898
  "utf-8"