@agentv/core 2.14.2 → 2.14.3

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/dist/index.js CHANGED
@@ -234,7 +234,7 @@ async function resolveFileReference2(ref, evalFileDir) {
234
234
  const rawPath = extractFilePath(ref);
235
235
  const absolutePattern = path.resolve(evalFileDir, rawPath);
236
236
  if (isGlobPattern(rawPath)) {
237
- const matches = await fg(absolutePattern, {
237
+ const matches = await fg(absolutePattern.replaceAll("\\", "/"), {
238
238
  onlyFiles: true,
239
239
  absolute: true
240
240
  });
@@ -5049,7 +5049,7 @@ import { arch, platform } from "node:os";
5049
5049
  import path13 from "node:path";
5050
5050
  import { fileURLToPath as fileURLToPath2 } from "node:url";
5051
5051
  function resolvePlatformCliPath() {
5052
- const os5 = platform();
5052
+ const os3 = platform();
5053
5053
  const cpu = arch();
5054
5054
  const platformMap = {
5055
5055
  linux: "linux",
@@ -5060,13 +5060,13 @@ function resolvePlatformCliPath() {
5060
5060
  x64: "x64",
5061
5061
  arm64: "arm64"
5062
5062
  };
5063
- const osPart = platformMap[os5];
5063
+ const osPart = platformMap[os3];
5064
5064
  const archPart = archMap[cpu];
5065
5065
  if (!osPart || !archPart) {
5066
5066
  return void 0;
5067
5067
  }
5068
5068
  const packageName = `@github/copilot-${osPart}-${archPart}`;
5069
- const binaryName = os5 === "win32" ? "copilot.exe" : "copilot";
5069
+ const binaryName = os3 === "win32" ? "copilot.exe" : "copilot";
5070
5070
  try {
5071
5071
  const resolved = import.meta.resolve(`${packageName}/package.json`);
5072
5072
  const packageJsonPath = resolved.startsWith("file:") ? fileURLToPath2(resolved) : resolved;
@@ -6868,12 +6868,12 @@ var ProviderRegistry = class {
6868
6868
  // src/evaluation/providers/vscode-provider.ts
6869
6869
  import { exec as exec2 } from "node:child_process";
6870
6870
  import { constants as constants3, access as access3, stat as stat4 } from "node:fs/promises";
6871
- import path27 from "node:path";
6871
+ import path28 from "node:path";
6872
6872
  import { promisify as promisify3 } from "node:util";
6873
6873
 
6874
6874
  // src/evaluation/providers/vscode/dispatch/agentDispatch.ts
6875
6875
  import { stat as stat3, writeFile as writeFile4 } from "node:fs/promises";
6876
- import path25 from "node:path";
6876
+ import path26 from "node:path";
6877
6877
 
6878
6878
  // src/evaluation/providers/vscode/utils/fs.ts
6879
6879
  import { constants as constants2 } from "node:fs";
@@ -7141,17 +7141,46 @@ async function waitForBatchResponses(responseFilesFinal, pollInterval = 1e3, sil
7141
7141
  // src/evaluation/providers/vscode/dispatch/vscodeProcess.ts
7142
7142
  import { exec, spawn as spawn3 } from "node:child_process";
7143
7143
  import { mkdir as mkdir7, writeFile as writeFile2 } from "node:fs/promises";
7144
- import path22 from "node:path";
7144
+ import path23 from "node:path";
7145
7145
  import { promisify as promisify2 } from "node:util";
7146
7146
 
7147
7147
  // src/evaluation/providers/vscode/dispatch/constants.ts
7148
+ import path22 from "node:path";
7149
+
7150
+ // src/paths.ts
7148
7151
  import os2 from "node:os";
7149
7152
  import path21 from "node:path";
7153
+ var logged = false;
7154
+ function getAgentvHome() {
7155
+ const envHome = process.env.AGENTV_HOME;
7156
+ if (envHome) {
7157
+ if (!logged) {
7158
+ logged = true;
7159
+ console.warn(`Using AGENTV_HOME: ${envHome}`);
7160
+ }
7161
+ return envHome;
7162
+ }
7163
+ return path21.join(os2.homedir(), ".agentv");
7164
+ }
7165
+ function getWorkspacesRoot() {
7166
+ return path21.join(getAgentvHome(), "workspaces");
7167
+ }
7168
+ function getGitCacheRoot() {
7169
+ return path21.join(getAgentvHome(), "git-cache");
7170
+ }
7171
+ function getSubagentsRoot() {
7172
+ return path21.join(getAgentvHome(), "subagents");
7173
+ }
7174
+ function getTraceStateRoot() {
7175
+ return path21.join(getAgentvHome(), "trace-state");
7176
+ }
7177
+
7178
+ // src/evaluation/providers/vscode/dispatch/constants.ts
7150
7179
  var DEFAULT_LOCK_NAME = "subagent.lock";
7151
7180
  var DEFAULT_ALIVE_FILENAME = ".alive";
7152
7181
  function getDefaultSubagentRoot(vscodeCmd = "code") {
7153
7182
  const folder = vscodeCmd === "code-insiders" ? "vscode-insiders-agents" : "vscode-agents";
7154
- return path21.join(os2.homedir(), ".agentv", "subagents", folder);
7183
+ return path22.join(getSubagentsRoot(), folder);
7155
7184
  }
7156
7185
  var DEFAULT_SUBAGENT_ROOT = getDefaultSubagentRoot();
7157
7186
 
@@ -7165,12 +7194,19 @@ description: 'Wake-up Signal'
7165
7194
  model: Grok Code Fast 1 (copilot)
7166
7195
  ---`;
7167
7196
  function spawnVsCode(vscodeCmd, args, options) {
7168
- const child = spawn3(vscodeCmd, args, {
7197
+ const useShell = options?.shell ?? true;
7198
+ const command = useShell ? shellQuote(vscodeCmd) : vscodeCmd;
7199
+ const child = spawn3(command, args, {
7169
7200
  windowsHide: true,
7170
- shell: options?.shell ?? true,
7201
+ shell: useShell,
7171
7202
  detached: false
7172
7203
  });
7173
- child.on("error", () => {
7204
+ child.on("error", (error) => {
7205
+ const label = options?.label ?? "spawn";
7206
+ const renderedArgs = args.map((value) => JSON.stringify(value)).join(" ");
7207
+ console.error(
7208
+ `[vscode] ${label} failed: command=${JSON.stringify(vscodeCmd)} args=${renderedArgs} error=${error.message}`
7209
+ );
7174
7210
  });
7175
7211
  return child;
7176
7212
  }
@@ -7207,16 +7243,20 @@ async function checkWorkspaceOpened(workspaceName, vscodeCmd) {
7207
7243
  async function ensureWorkspaceFocused(workspacePath, workspaceName, subagentDir, vscodeCmd, pollInterval = 1, timeout = 60) {
7208
7244
  const alreadyOpen = await checkWorkspaceOpened(workspaceName, vscodeCmd);
7209
7245
  if (alreadyOpen) {
7210
- spawnVsCode(shellQuote(vscodeCmd), [workspacePath]);
7246
+ const child = spawnVsCode(vscodeCmd, [workspacePath], { label: "focus-existing-workspace" });
7247
+ await raceSpawnError(child);
7211
7248
  return true;
7212
7249
  }
7213
- const aliveFile = path22.join(subagentDir, DEFAULT_ALIVE_FILENAME);
7250
+ const aliveFile = path23.join(subagentDir, DEFAULT_ALIVE_FILENAME);
7214
7251
  await removeIfExists(aliveFile);
7215
- const githubAgentsDir = path22.join(subagentDir, ".github", "agents");
7252
+ const githubAgentsDir = path23.join(subagentDir, ".github", "agents");
7216
7253
  await mkdir7(githubAgentsDir, { recursive: true });
7217
- const wakeupDst = path22.join(githubAgentsDir, "wakeup.md");
7254
+ const wakeupDst = path23.join(githubAgentsDir, "wakeup.md");
7218
7255
  await writeFile2(wakeupDst, DEFAULT_WAKEUP_CONTENT, "utf8");
7219
- spawnVsCode(shellQuote(vscodeCmd), [workspacePath]);
7256
+ const workspaceChild = spawnVsCode(vscodeCmd, [workspacePath], {
7257
+ label: "open-workspace"
7258
+ });
7259
+ await raceSpawnError(workspaceChild);
7220
7260
  await sleep2(100);
7221
7261
  const wakeupChatId = "wakeup";
7222
7262
  const chatArgs = [
@@ -7224,9 +7264,10 @@ async function ensureWorkspaceFocused(workspacePath, workspaceName, subagentDir,
7224
7264
  "chat",
7225
7265
  "-m",
7226
7266
  wakeupChatId,
7227
- `create a file named .alive in the ${path22.basename(subagentDir)} folder`
7267
+ `create a file named .alive in the ${path23.basename(subagentDir)} folder`
7228
7268
  ];
7229
- spawnVsCode(shellQuote(vscodeCmd), chatArgs);
7269
+ const wakeupChild = spawnVsCode(vscodeCmd, chatArgs, { label: "send-wakeup-chat" });
7270
+ await raceSpawnError(wakeupChild);
7230
7271
  const start = Date.now();
7231
7272
  while (!await pathExists(aliveFile)) {
7232
7273
  if (Date.now() - start > timeout * 1e3) {
@@ -7238,10 +7279,10 @@ async function ensureWorkspaceFocused(workspacePath, workspaceName, subagentDir,
7238
7279
  return true;
7239
7280
  }
7240
7281
  async function launchVsCodeWithChat(subagentDir, chatId, attachmentPaths, requestInstructions, timestamp, vscodeCmd) {
7241
- const workspacePath = path22.join(subagentDir, `${path22.basename(subagentDir)}.code-workspace`);
7242
- const messagesDir = path22.join(subagentDir, "messages");
7282
+ const workspacePath = path23.join(subagentDir, `${path23.basename(subagentDir)}.code-workspace`);
7283
+ const messagesDir = path23.join(subagentDir, "messages");
7243
7284
  await mkdir7(messagesDir, { recursive: true });
7244
- const reqFile = path22.join(messagesDir, `${timestamp}_req.md`);
7285
+ const reqFile = path23.join(messagesDir, `${timestamp}_req.md`);
7245
7286
  await writeFile2(reqFile, requestInstructions, { encoding: "utf8" });
7246
7287
  const reqUri = pathToFileUri2(reqFile);
7247
7288
  const chatArgs = ["-r", "chat", "-m", chatId];
@@ -7249,25 +7290,25 @@ async function launchVsCodeWithChat(subagentDir, chatId, attachmentPaths, reques
7249
7290
  chatArgs.push("-a", attachment);
7250
7291
  }
7251
7292
  chatArgs.push("-a", reqFile);
7252
- chatArgs.push(`Follow instructions in [${path22.basename(reqFile)}](${reqUri})`);
7293
+ chatArgs.push(`Follow instructions in [${path23.basename(reqFile)}](${reqUri})`);
7253
7294
  const workspaceReady = await ensureWorkspaceFocused(
7254
7295
  workspacePath,
7255
- path22.basename(subagentDir),
7296
+ path23.basename(subagentDir),
7256
7297
  subagentDir,
7257
7298
  vscodeCmd
7258
7299
  );
7259
7300
  if (!workspaceReady) {
7260
7301
  throw new Error(
7261
- `VS Code workspace '${path22.basename(subagentDir)}' failed to become ready within the timeout. Check that '${vscodeCmd}' can open workspaces.`
7302
+ `VS Code workspace '${path23.basename(subagentDir)}' failed to become ready within the timeout. Check that '${vscodeCmd}' can open workspaces.`
7262
7303
  );
7263
7304
  }
7264
7305
  await sleep2(500);
7265
- const child = spawnVsCode(shellQuote(vscodeCmd), chatArgs);
7306
+ const child = spawnVsCode(vscodeCmd, chatArgs, { label: "send-chat" });
7266
7307
  await raceSpawnError(child);
7267
7308
  }
7268
7309
  async function launchVsCodeWithBatchChat(subagentDir, chatId, attachmentPaths, chatInstruction, vscodeCmd) {
7269
- const workspacePath = path22.join(subagentDir, `${path22.basename(subagentDir)}.code-workspace`);
7270
- const messagesDir = path22.join(subagentDir, "messages");
7310
+ const workspacePath = path23.join(subagentDir, `${path23.basename(subagentDir)}.code-workspace`);
7311
+ const messagesDir = path23.join(subagentDir, "messages");
7271
7312
  await mkdir7(messagesDir, { recursive: true });
7272
7313
  const chatArgs = ["-r", "chat", "-m", chatId];
7273
7314
  for (const attachment of attachmentPaths) {
@@ -7276,26 +7317,26 @@ async function launchVsCodeWithBatchChat(subagentDir, chatId, attachmentPaths, c
7276
7317
  chatArgs.push(chatInstruction);
7277
7318
  const workspaceReady = await ensureWorkspaceFocused(
7278
7319
  workspacePath,
7279
- path22.basename(subagentDir),
7320
+ path23.basename(subagentDir),
7280
7321
  subagentDir,
7281
7322
  vscodeCmd
7282
7323
  );
7283
7324
  if (!workspaceReady) {
7284
7325
  throw new Error(
7285
- `VS Code workspace '${path22.basename(subagentDir)}' failed to become ready within the timeout. Check that '${vscodeCmd}' can open workspaces.`
7326
+ `VS Code workspace '${path23.basename(subagentDir)}' failed to become ready within the timeout. Check that '${vscodeCmd}' can open workspaces.`
7286
7327
  );
7287
7328
  }
7288
7329
  await sleep2(500);
7289
- const child = spawnVsCode(shellQuote(vscodeCmd), chatArgs);
7330
+ const child = spawnVsCode(vscodeCmd, chatArgs, { label: "send-batch-chat" });
7290
7331
  await raceSpawnError(child);
7291
7332
  }
7292
7333
 
7293
7334
  // src/evaluation/providers/vscode/dispatch/workspaceManager.ts
7294
7335
  import { copyFile, mkdir as mkdir8, readFile as readFile9, readdir as readdir2, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
7295
- import path24 from "node:path";
7336
+ import path25 from "node:path";
7296
7337
 
7297
7338
  // src/evaluation/providers/vscode/utils/workspace.ts
7298
- import path23 from "node:path";
7339
+ import path24 from "node:path";
7299
7340
  import JSON5 from "json5";
7300
7341
  function transformWorkspacePaths(workspaceContent, templateDir) {
7301
7342
  let workspace;
@@ -7312,10 +7353,10 @@ function transformWorkspacePaths(workspaceContent, templateDir) {
7312
7353
  }
7313
7354
  const transformedFolders = workspace.folders.map((folder) => {
7314
7355
  const folderPath = folder.path;
7315
- if (path23.isAbsolute(folderPath)) {
7356
+ if (path24.isAbsolute(folderPath)) {
7316
7357
  return folder;
7317
7358
  }
7318
- const absolutePath = path23.resolve(templateDir, folderPath);
7359
+ const absolutePath = path24.resolve(templateDir, folderPath);
7319
7360
  return {
7320
7361
  ...folder,
7321
7362
  path: absolutePath
@@ -7337,19 +7378,19 @@ function transformWorkspacePaths(workspaceContent, templateDir) {
7337
7378
  if (locationMap && typeof locationMap === "object") {
7338
7379
  const transformedMap = {};
7339
7380
  for (const [locationPath, value] of Object.entries(locationMap)) {
7340
- const isAbsolute = path23.isAbsolute(locationPath);
7381
+ const isAbsolute = path24.isAbsolute(locationPath);
7341
7382
  if (isAbsolute) {
7342
7383
  transformedMap[locationPath] = value;
7343
7384
  } else {
7344
7385
  const firstGlobIndex = locationPath.search(/[*]/);
7345
7386
  if (firstGlobIndex === -1) {
7346
- const resolvedPath = path23.resolve(templateDir, locationPath).replace(/\\/g, "/");
7387
+ const resolvedPath = path24.resolve(templateDir, locationPath).replace(/\\/g, "/");
7347
7388
  transformedMap[resolvedPath] = value;
7348
7389
  } else {
7349
7390
  const basePathEnd = locationPath.lastIndexOf("/", firstGlobIndex);
7350
7391
  const basePath = basePathEnd !== -1 ? locationPath.substring(0, basePathEnd) : ".";
7351
7392
  const patternPath = locationPath.substring(basePathEnd !== -1 ? basePathEnd : 0);
7352
- const resolvedPath = (path23.resolve(templateDir, basePath) + patternPath).replace(
7393
+ const resolvedPath = (path24.resolve(templateDir, basePath) + patternPath).replace(
7353
7394
  /\\/g,
7354
7395
  "/"
7355
7396
  );
@@ -7390,7 +7431,7 @@ async function findUnlockedSubagent(subagentRoot) {
7390
7431
  number: Number.parseInt(entry.name.split("-")[1] ?? "", 10)
7391
7432
  })).filter((entry) => Number.isInteger(entry.number)).sort((a, b) => a.number - b.number);
7392
7433
  for (const subagent of subagents) {
7393
- const lockFile = path24.join(subagent.absolutePath, DEFAULT_LOCK_NAME);
7434
+ const lockFile = path25.join(subagent.absolutePath, DEFAULT_LOCK_NAME);
7394
7435
  if (!await pathExists(lockFile)) {
7395
7436
  return subagent.absolutePath;
7396
7437
  }
@@ -7400,7 +7441,7 @@ async function findUnlockedSubagent(subagentRoot) {
7400
7441
  async function copyAgentConfig(subagentDir, workspaceTemplate, cwd) {
7401
7442
  let workspaceContent;
7402
7443
  if (workspaceTemplate) {
7403
- const workspaceSrc = path24.resolve(workspaceTemplate);
7444
+ const workspaceSrc = path25.resolve(workspaceTemplate);
7404
7445
  if (!await pathExists(workspaceSrc)) {
7405
7446
  throw new Error(`workspace template not found: ${workspaceSrc}`);
7406
7447
  }
@@ -7413,13 +7454,13 @@ async function copyAgentConfig(subagentDir, workspaceTemplate, cwd) {
7413
7454
  } else {
7414
7455
  workspaceContent = DEFAULT_WORKSPACE_TEMPLATE;
7415
7456
  }
7416
- const workspaceName = `${path24.basename(subagentDir)}.code-workspace`;
7417
- const workspaceDst = path24.join(subagentDir, workspaceName);
7418
- const templateDir = workspaceTemplate ? path24.dirname(path24.resolve(workspaceTemplate)) : subagentDir;
7457
+ const workspaceName = `${path25.basename(subagentDir)}.code-workspace`;
7458
+ const workspaceDst = path25.join(subagentDir, workspaceName);
7459
+ const templateDir = workspaceTemplate ? path25.dirname(path25.resolve(workspaceTemplate)) : subagentDir;
7419
7460
  const workspaceJson = JSON.stringify(workspaceContent, null, 2);
7420
7461
  let transformedContent = transformWorkspacePaths(workspaceJson, templateDir);
7421
7462
  if (cwd) {
7422
- const absCwd = path24.resolve(cwd);
7463
+ const absCwd = path25.resolve(cwd);
7423
7464
  const parsed = JSON.parse(transformedContent);
7424
7465
  const alreadyPresent = parsed.folders.some((f) => f.path === absCwd);
7425
7466
  if (!alreadyPresent) {
@@ -7428,35 +7469,35 @@ async function copyAgentConfig(subagentDir, workspaceTemplate, cwd) {
7428
7469
  }
7429
7470
  }
7430
7471
  await writeFile3(workspaceDst, transformedContent, "utf8");
7431
- const messagesDir = path24.join(subagentDir, "messages");
7472
+ const messagesDir = path25.join(subagentDir, "messages");
7432
7473
  await mkdir8(messagesDir, { recursive: true });
7433
7474
  return { workspace: workspaceDst, messagesDir };
7434
7475
  }
7435
7476
  async function createSubagentLock(subagentDir) {
7436
- const messagesDir = path24.join(subagentDir, "messages");
7477
+ const messagesDir = path25.join(subagentDir, "messages");
7437
7478
  if (await pathExists(messagesDir)) {
7438
7479
  const files = await readdir2(messagesDir);
7439
7480
  await Promise.all(
7440
7481
  files.map(async (file) => {
7441
- const target = path24.join(messagesDir, file);
7482
+ const target = path25.join(messagesDir, file);
7442
7483
  await removeIfExists(target);
7443
7484
  })
7444
7485
  );
7445
7486
  }
7446
- const githubAgentsDir = path24.join(subagentDir, ".github", "agents");
7487
+ const githubAgentsDir = path25.join(subagentDir, ".github", "agents");
7447
7488
  if (await pathExists(githubAgentsDir)) {
7448
7489
  const agentFiles = await readdir2(githubAgentsDir);
7449
7490
  const preservedFiles = /* @__PURE__ */ new Set(["wakeup.md", "subagent.md"]);
7450
7491
  await Promise.all(
7451
- agentFiles.filter((file) => file.endsWith(".md") && !preservedFiles.has(file)).map((file) => removeIfExists(path24.join(githubAgentsDir, file)))
7492
+ agentFiles.filter((file) => file.endsWith(".md") && !preservedFiles.has(file)).map((file) => removeIfExists(path25.join(githubAgentsDir, file)))
7452
7493
  );
7453
7494
  }
7454
- const lockFile = path24.join(subagentDir, DEFAULT_LOCK_NAME);
7495
+ const lockFile = path25.join(subagentDir, DEFAULT_LOCK_NAME);
7455
7496
  await writeFile3(lockFile, "", { encoding: "utf8" });
7456
7497
  return lockFile;
7457
7498
  }
7458
7499
  async function removeSubagentLock(subagentDir) {
7459
- const lockFile = path24.join(subagentDir, DEFAULT_LOCK_NAME);
7500
+ const lockFile = path25.join(subagentDir, DEFAULT_LOCK_NAME);
7460
7501
  await removeIfExists(lockFile);
7461
7502
  }
7462
7503
  async function prepareSubagentDirectory(subagentDir, promptFile, chatId, workspaceTemplate, dryRun, cwd) {
@@ -7476,9 +7517,9 @@ async function prepareSubagentDirectory(subagentDir, promptFile, chatId, workspa
7476
7517
  return 1;
7477
7518
  }
7478
7519
  if (promptFile) {
7479
- const githubAgentsDir = path24.join(subagentDir, ".github", "agents");
7520
+ const githubAgentsDir = path25.join(subagentDir, ".github", "agents");
7480
7521
  await mkdir8(githubAgentsDir, { recursive: true });
7481
- const agentFile = path24.join(githubAgentsDir, `${chatId}.md`);
7522
+ const agentFile = path25.join(githubAgentsDir, `${chatId}.md`);
7482
7523
  try {
7483
7524
  await copyFile(promptFile, agentFile);
7484
7525
  } catch (error) {
@@ -7497,7 +7538,7 @@ async function resolvePromptFile(promptFile) {
7497
7538
  if (!promptFile) {
7498
7539
  return void 0;
7499
7540
  }
7500
- const resolvedPrompt = path25.resolve(promptFile);
7541
+ const resolvedPrompt = path26.resolve(promptFile);
7501
7542
  if (!await pathExists(resolvedPrompt)) {
7502
7543
  throw new Error(`Prompt file not found: ${resolvedPrompt}`);
7503
7544
  }
@@ -7513,7 +7554,7 @@ async function resolveAttachments(extraAttachments) {
7513
7554
  }
7514
7555
  const resolved = [];
7515
7556
  for (const attachment of extraAttachments) {
7516
- const resolvedPath = path25.resolve(attachment);
7557
+ const resolvedPath = path26.resolve(attachment);
7517
7558
  if (!await pathExists(resolvedPath)) {
7518
7559
  throw new Error(`Attachment not found: ${resolvedPath}`);
7519
7560
  }
@@ -7555,7 +7596,7 @@ async function dispatchAgentSession(options) {
7555
7596
  error: "No unlocked subagents available. Provision additional subagents with: subagent code provision --subagents <desired_total>"
7556
7597
  };
7557
7598
  }
7558
- const subagentName = path25.basename(subagentDir);
7599
+ const subagentName = path26.basename(subagentDir);
7559
7600
  const chatId = Math.random().toString(16).slice(2, 10);
7560
7601
  const preparationResult = await prepareSubagentDirectory(
7561
7602
  subagentDir,
@@ -7583,9 +7624,9 @@ async function dispatchAgentSession(options) {
7583
7624
  };
7584
7625
  }
7585
7626
  const timestamp = generateTimestamp();
7586
- const messagesDir = path25.join(subagentDir, "messages");
7587
- const responseFileTmp = path25.join(messagesDir, `${timestamp}_res.tmp.md`);
7588
- const responseFileFinal = path25.join(messagesDir, `${timestamp}_res.md`);
7627
+ const messagesDir = path26.join(subagentDir, "messages");
7628
+ const responseFileTmp = path26.join(messagesDir, `${timestamp}_res.tmp.md`);
7629
+ const responseFileFinal = path26.join(messagesDir, `${timestamp}_res.md`);
7589
7630
  const requestInstructions = createRequestPrompt(
7590
7631
  userQuery,
7591
7632
  responseFileTmp,
@@ -7690,7 +7731,7 @@ async function dispatchBatchAgent(options) {
7690
7731
  error: "No unlocked subagents available. Provision additional subagents with: subagent code provision --subagents <desired_total>"
7691
7732
  };
7692
7733
  }
7693
- subagentName = path25.basename(subagentDir);
7734
+ subagentName = path26.basename(subagentDir);
7694
7735
  const chatId = Math.random().toString(16).slice(2, 10);
7695
7736
  const preparationResult = await prepareSubagentDirectory(
7696
7737
  subagentDir,
@@ -7721,17 +7762,17 @@ async function dispatchBatchAgent(options) {
7721
7762
  };
7722
7763
  }
7723
7764
  const timestamp = generateTimestamp();
7724
- const messagesDir = path25.join(subagentDir, "messages");
7765
+ const messagesDir = path26.join(subagentDir, "messages");
7725
7766
  requestFiles = userQueries.map(
7726
- (_, index) => path25.join(messagesDir, `${timestamp}_${index}_req.md`)
7767
+ (_, index) => path26.join(messagesDir, `${timestamp}_${index}_req.md`)
7727
7768
  );
7728
7769
  const responseTmpFiles = userQueries.map(
7729
- (_, index) => path25.join(messagesDir, `${timestamp}_${index}_res.tmp.md`)
7770
+ (_, index) => path26.join(messagesDir, `${timestamp}_${index}_res.tmp.md`)
7730
7771
  );
7731
7772
  responseFilesFinal = userQueries.map(
7732
- (_, index) => path25.join(messagesDir, `${timestamp}_${index}_res.md`)
7773
+ (_, index) => path26.join(messagesDir, `${timestamp}_${index}_res.md`)
7733
7774
  );
7734
- const orchestratorFile = path25.join(messagesDir, `${timestamp}_orchestrator.md`);
7775
+ const orchestratorFile = path26.join(messagesDir, `${timestamp}_orchestrator.md`);
7735
7776
  if (!dryRun) {
7736
7777
  await Promise.all(
7737
7778
  userQueries.map((query, index) => {
@@ -7817,7 +7858,7 @@ async function dispatchBatchAgent(options) {
7817
7858
 
7818
7859
  // src/evaluation/providers/vscode/dispatch/provision.ts
7819
7860
  import { writeFile as writeFile5 } from "node:fs/promises";
7820
- import path26 from "node:path";
7861
+ import path27 from "node:path";
7821
7862
  var DEFAULT_WORKSPACE_TEMPLATE2 = {
7822
7863
  folders: [
7823
7864
  {
@@ -7848,7 +7889,7 @@ async function provisionSubagents(options) {
7848
7889
  if (!Number.isInteger(subagents) || subagents < 1) {
7849
7890
  throw new Error("subagents must be a positive integer");
7850
7891
  }
7851
- const targetPath = path26.resolve(targetRoot);
7892
+ const targetPath = path27.resolve(targetRoot);
7852
7893
  if (!dryRun) {
7853
7894
  await ensureDir(targetPath);
7854
7895
  }
@@ -7868,7 +7909,7 @@ async function provisionSubagents(options) {
7868
7909
  continue;
7869
7910
  }
7870
7911
  highestNumber = Math.max(highestNumber, parsed);
7871
- const lockFile = path26.join(entry.absolutePath, lockName);
7912
+ const lockFile = path27.join(entry.absolutePath, lockName);
7872
7913
  const locked = await pathExists(lockFile);
7873
7914
  if (locked) {
7874
7915
  lockedSubagents.add(entry.absolutePath);
@@ -7885,10 +7926,10 @@ async function provisionSubagents(options) {
7885
7926
  break;
7886
7927
  }
7887
7928
  const subagentDir = subagent.absolutePath;
7888
- const githubAgentsDir = path26.join(subagentDir, ".github", "agents");
7889
- const lockFile = path26.join(subagentDir, lockName);
7890
- const workspaceDst = path26.join(subagentDir, `${path26.basename(subagentDir)}.code-workspace`);
7891
- const wakeupDst = path26.join(githubAgentsDir, "wakeup.md");
7929
+ const githubAgentsDir = path27.join(subagentDir, ".github", "agents");
7930
+ const lockFile = path27.join(subagentDir, lockName);
7931
+ const workspaceDst = path27.join(subagentDir, `${path27.basename(subagentDir)}.code-workspace`);
7932
+ const wakeupDst = path27.join(githubAgentsDir, "wakeup.md");
7892
7933
  const isLocked = await pathExists(lockFile);
7893
7934
  if (isLocked && !force) {
7894
7935
  continue;
@@ -7926,10 +7967,10 @@ async function provisionSubagents(options) {
7926
7967
  let nextIndex = highestNumber;
7927
7968
  while (subagentsProvisioned < subagents) {
7928
7969
  nextIndex += 1;
7929
- const subagentDir = path26.join(targetPath, `subagent-${nextIndex}`);
7930
- const githubAgentsDir = path26.join(subagentDir, ".github", "agents");
7931
- const workspaceDst = path26.join(subagentDir, `${path26.basename(subagentDir)}.code-workspace`);
7932
- const wakeupDst = path26.join(githubAgentsDir, "wakeup.md");
7970
+ const subagentDir = path27.join(targetPath, `subagent-${nextIndex}`);
7971
+ const githubAgentsDir = path27.join(subagentDir, ".github", "agents");
7972
+ const workspaceDst = path27.join(subagentDir, `${path27.basename(subagentDir)}.code-workspace`);
7973
+ const wakeupDst = path27.join(githubAgentsDir, "wakeup.md");
7933
7974
  if (!dryRun) {
7934
7975
  await ensureDir(subagentDir);
7935
7976
  await ensureDir(githubAgentsDir);
@@ -8123,7 +8164,7 @@ var VSCodeProvider = class {
8123
8164
  async function locateVSCodeExecutable(candidate) {
8124
8165
  const includesPathSeparator = candidate.includes("/") || candidate.includes("\\");
8125
8166
  if (includesPathSeparator) {
8126
- const resolved = path27.isAbsolute(candidate) ? candidate : path27.resolve(candidate);
8167
+ const resolved = path28.isAbsolute(candidate) ? candidate : path28.resolve(candidate);
8127
8168
  try {
8128
8169
  await access3(resolved, constants3.F_OK);
8129
8170
  return resolved;
@@ -8152,7 +8193,7 @@ async function resolveWorkspaceTemplateFile(template) {
8152
8193
  return void 0;
8153
8194
  }
8154
8195
  try {
8155
- const stats = await stat4(path27.resolve(template));
8196
+ const stats = await stat4(path28.resolve(template));
8156
8197
  return stats.isFile() ? template : void 0;
8157
8198
  } catch {
8158
8199
  return template;
@@ -8178,7 +8219,7 @@ function buildMandatoryPrereadBlock2(guidelineFiles, attachmentFiles) {
8178
8219
  return "";
8179
8220
  }
8180
8221
  const buildList = (files) => files.map((absolutePath) => {
8181
- const fileName = path27.basename(absolutePath);
8222
+ const fileName = path28.basename(absolutePath);
8182
8223
  const fileUri = pathToFileUri3(absolutePath);
8183
8224
  return `* [${fileName}](${fileUri})`;
8184
8225
  });
@@ -8203,8 +8244,8 @@ function collectGuidelineFiles2(attachments, guidelinePatterns) {
8203
8244
  }
8204
8245
  const unique = /* @__PURE__ */ new Map();
8205
8246
  for (const attachment of attachments) {
8206
- const absolutePath = path27.resolve(attachment);
8207
- const normalized = absolutePath.split(path27.sep).join("/");
8247
+ const absolutePath = path28.resolve(attachment);
8248
+ const normalized = absolutePath.split(path28.sep).join("/");
8208
8249
  if (isGuidelineFile(normalized, guidelinePatterns)) {
8209
8250
  if (!unique.has(absolutePath)) {
8210
8251
  unique.set(absolutePath, absolutePath);
@@ -8219,7 +8260,7 @@ function collectAttachmentFiles(attachments) {
8219
8260
  }
8220
8261
  const unique = /* @__PURE__ */ new Map();
8221
8262
  for (const attachment of attachments) {
8222
- const absolutePath = path27.resolve(attachment);
8263
+ const absolutePath = path28.resolve(attachment);
8223
8264
  if (!unique.has(absolutePath)) {
8224
8265
  unique.set(absolutePath, absolutePath);
8225
8266
  }
@@ -8227,7 +8268,7 @@ function collectAttachmentFiles(attachments) {
8227
8268
  return Array.from(unique.values());
8228
8269
  }
8229
8270
  function pathToFileUri3(filePath) {
8230
- const absolutePath = path27.isAbsolute(filePath) ? filePath : path27.resolve(filePath);
8271
+ const absolutePath = path28.isAbsolute(filePath) ? filePath : path28.resolve(filePath);
8231
8272
  const normalizedPath = absolutePath.replace(/\\/g, "/");
8232
8273
  if (/^[a-zA-Z]:\//.test(normalizedPath)) {
8233
8274
  return `file:///${normalizedPath}`;
@@ -8240,7 +8281,7 @@ function normalizeAttachments(attachments) {
8240
8281
  }
8241
8282
  const deduped = /* @__PURE__ */ new Set();
8242
8283
  for (const attachment of attachments) {
8243
- deduped.add(path27.resolve(attachment));
8284
+ deduped.add(path28.resolve(attachment));
8244
8285
  }
8245
8286
  return Array.from(deduped);
8246
8287
  }
@@ -8249,7 +8290,7 @@ function mergeAttachments(all) {
8249
8290
  for (const list of all) {
8250
8291
  if (!list) continue;
8251
8292
  for (const inputFile of list) {
8252
- deduped.add(path27.resolve(inputFile));
8293
+ deduped.add(path28.resolve(inputFile));
8253
8294
  }
8254
8295
  }
8255
8296
  return deduped.size > 0 ? Array.from(deduped) : void 0;
@@ -8298,7 +8339,7 @@ total unlocked subagents available: ${result.created.length + result.skippedExis
8298
8339
  // src/evaluation/providers/targets-file.ts
8299
8340
  import { constants as constants4 } from "node:fs";
8300
8341
  import { access as access4, readFile as readFile10 } from "node:fs/promises";
8301
- import path28 from "node:path";
8342
+ import path29 from "node:path";
8302
8343
  import { parse as parse3 } from "yaml";
8303
8344
  function isRecord(value) {
8304
8345
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -8335,7 +8376,7 @@ async function fileExists3(filePath) {
8335
8376
  }
8336
8377
  }
8337
8378
  async function readTargetDefinitions(filePath) {
8338
- const absolutePath = path28.resolve(filePath);
8379
+ const absolutePath = path29.resolve(filePath);
8339
8380
  if (!await fileExists3(absolutePath)) {
8340
8381
  throw new Error(`targets.yaml not found at ${absolutePath}`);
8341
8382
  }
@@ -8355,16 +8396,16 @@ function listTargetNames(definitions) {
8355
8396
  }
8356
8397
 
8357
8398
  // src/evaluation/providers/provider-discovery.ts
8358
- import path29 from "node:path";
8399
+ import path30 from "node:path";
8359
8400
  import fg2 from "fast-glob";
8360
8401
  async function discoverProviders(registry, baseDir) {
8361
8402
  const patterns = ["*.ts", "*.js", "*.mts", "*.mjs"];
8362
8403
  const candidateDirs = [];
8363
- let dir = path29.resolve(baseDir);
8364
- const root = path29.parse(dir).root;
8404
+ let dir = path30.resolve(baseDir);
8405
+ const root = path30.parse(dir).root;
8365
8406
  while (dir !== root) {
8366
- candidateDirs.push(path29.join(dir, ".agentv", "providers"));
8367
- dir = path29.dirname(dir);
8407
+ candidateDirs.push(path30.join(dir, ".agentv", "providers"));
8408
+ dir = path30.dirname(dir);
8368
8409
  }
8369
8410
  let files = [];
8370
8411
  for (const providersDir of candidateDirs) {
@@ -8380,7 +8421,7 @@ async function discoverProviders(registry, baseDir) {
8380
8421
  }
8381
8422
  const discoveredKinds = [];
8382
8423
  for (const filePath of files) {
8383
- const basename = path29.basename(filePath);
8424
+ const basename = path30.basename(filePath);
8384
8425
  const kindName = basename.replace(/\.(ts|js|mts|mjs)$/, "");
8385
8426
  if (registry.has(kindName)) {
8386
8427
  continue;
@@ -8589,13 +8630,13 @@ async function execFileWithStdinNode(argv, stdinPayload, options) {
8589
8630
  async function execShellWithStdin(command, stdinPayload, options = {}) {
8590
8631
  const { mkdir: mkdir14, readFile: readFile12, rm: rm6, writeFile: writeFile9 } = await import("node:fs/promises");
8591
8632
  const { tmpdir: tmpdir3 } = await import("node:os");
8592
- const path40 = await import("node:path");
8633
+ const path41 = await import("node:path");
8593
8634
  const { randomUUID: randomUUID8 } = await import("node:crypto");
8594
- const dir = path40.join(tmpdir3(), `agentv-exec-${randomUUID8()}`);
8635
+ const dir = path41.join(tmpdir3(), `agentv-exec-${randomUUID8()}`);
8595
8636
  await mkdir14(dir, { recursive: true });
8596
- const stdinPath = path40.join(dir, "stdin.txt");
8597
- const stdoutPath = path40.join(dir, "stdout.txt");
8598
- const stderrPath = path40.join(dir, "stderr.txt");
8637
+ const stdinPath = path41.join(dir, "stdin.txt");
8638
+ const stdoutPath = path41.join(dir, "stdout.txt");
8639
+ const stderrPath = path41.join(dir, "stderr.txt");
8599
8640
  await writeFile9(stdinPath, stdinPayload, "utf8");
8600
8641
  const wrappedCommand = process.platform === "win32" ? `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}` : `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}`;
8601
8642
  const { spawn: spawn4 } = await import("node:child_process");
@@ -8947,7 +8988,7 @@ var CodeEvaluator = class {
8947
8988
  outputPath,
8948
8989
  guidelineFiles: context.evalCase.guideline_paths,
8949
8990
  inputFiles: context.evalCase.file_paths.filter(
8950
- (path40) => !context.evalCase.guideline_paths.includes(path40)
8991
+ (path41) => !context.evalCase.guideline_paths.includes(path41)
8951
8992
  ),
8952
8993
  input: context.evalCase.input,
8953
8994
  trace: context.trace ?? null,
@@ -10145,115 +10186,115 @@ var FieldAccuracyEvaluator = class {
10145
10186
  * Evaluate a single field against the expected value.
10146
10187
  */
10147
10188
  evaluateField(fieldConfig, candidateData, expectedData) {
10148
- const { path: path40, match, required = true, weight = 1 } = fieldConfig;
10149
- const candidateValue = resolvePath(candidateData, path40);
10150
- const expectedValue = resolvePath(expectedData, path40);
10189
+ const { path: path41, match, required = true, weight = 1 } = fieldConfig;
10190
+ const candidateValue = resolvePath(candidateData, path41);
10191
+ const expectedValue = resolvePath(expectedData, path41);
10151
10192
  if (expectedValue === void 0) {
10152
10193
  return {
10153
- path: path40,
10194
+ path: path41,
10154
10195
  score: 1,
10155
10196
  // No expected value means no comparison needed
10156
10197
  weight,
10157
10198
  hit: true,
10158
- message: `${path40}: no expected value`
10199
+ message: `${path41}: no expected value`
10159
10200
  };
10160
10201
  }
10161
10202
  if (candidateValue === void 0) {
10162
10203
  if (required) {
10163
10204
  return {
10164
- path: path40,
10205
+ path: path41,
10165
10206
  score: 0,
10166
10207
  weight,
10167
10208
  hit: false,
10168
- message: `${path40} (required, missing)`
10209
+ message: `${path41} (required, missing)`
10169
10210
  };
10170
10211
  }
10171
10212
  return {
10172
- path: path40,
10213
+ path: path41,
10173
10214
  score: 1,
10174
10215
  // Don't penalize missing optional fields
10175
10216
  weight: 0,
10176
10217
  // Zero weight means it won't affect the score
10177
10218
  hit: true,
10178
- message: `${path40}: optional field missing`
10219
+ message: `${path41}: optional field missing`
10179
10220
  };
10180
10221
  }
10181
10222
  switch (match) {
10182
10223
  case "exact":
10183
- return this.compareExact(path40, candidateValue, expectedValue, weight);
10224
+ return this.compareExact(path41, candidateValue, expectedValue, weight);
10184
10225
  case "numeric_tolerance":
10185
10226
  return this.compareNumericTolerance(
10186
- path40,
10227
+ path41,
10187
10228
  candidateValue,
10188
10229
  expectedValue,
10189
10230
  fieldConfig,
10190
10231
  weight
10191
10232
  );
10192
10233
  case "date":
10193
- return this.compareDate(path40, candidateValue, expectedValue, fieldConfig, weight);
10234
+ return this.compareDate(path41, candidateValue, expectedValue, fieldConfig, weight);
10194
10235
  default:
10195
10236
  return {
10196
- path: path40,
10237
+ path: path41,
10197
10238
  score: 0,
10198
10239
  weight,
10199
10240
  hit: false,
10200
- message: `${path40}: unknown match type "${match}"`
10241
+ message: `${path41}: unknown match type "${match}"`
10201
10242
  };
10202
10243
  }
10203
10244
  }
10204
10245
  /**
10205
10246
  * Exact equality comparison.
10206
10247
  */
10207
- compareExact(path40, candidateValue, expectedValue, weight) {
10248
+ compareExact(path41, candidateValue, expectedValue, weight) {
10208
10249
  if (deepEqual(candidateValue, expectedValue)) {
10209
10250
  return {
10210
- path: path40,
10251
+ path: path41,
10211
10252
  score: 1,
10212
10253
  weight,
10213
10254
  hit: true,
10214
- message: path40
10255
+ message: path41
10215
10256
  };
10216
10257
  }
10217
10258
  if (typeof candidateValue !== typeof expectedValue) {
10218
10259
  return {
10219
- path: path40,
10260
+ path: path41,
10220
10261
  score: 0,
10221
10262
  weight,
10222
10263
  hit: false,
10223
- message: `${path40} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
10264
+ message: `${path41} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
10224
10265
  };
10225
10266
  }
10226
10267
  return {
10227
- path: path40,
10268
+ path: path41,
10228
10269
  score: 0,
10229
10270
  weight,
10230
10271
  hit: false,
10231
- message: `${path40} (value mismatch)`
10272
+ message: `${path41} (value mismatch)`
10232
10273
  };
10233
10274
  }
10234
10275
  /**
10235
10276
  * Numeric comparison with absolute or relative tolerance.
10236
10277
  */
10237
- compareNumericTolerance(path40, candidateValue, expectedValue, fieldConfig, weight) {
10278
+ compareNumericTolerance(path41, candidateValue, expectedValue, fieldConfig, weight) {
10238
10279
  const { tolerance = 0, relative = false } = fieldConfig;
10239
10280
  const candidateNum = toNumber2(candidateValue);
10240
10281
  const expectedNum = toNumber2(expectedValue);
10241
10282
  if (candidateNum === null || expectedNum === null) {
10242
10283
  return {
10243
- path: path40,
10284
+ path: path41,
10244
10285
  score: 0,
10245
10286
  weight,
10246
10287
  hit: false,
10247
- message: `${path40} (non-numeric value)`
10288
+ message: `${path41} (non-numeric value)`
10248
10289
  };
10249
10290
  }
10250
10291
  if (!Number.isFinite(candidateNum) || !Number.isFinite(expectedNum)) {
10251
10292
  return {
10252
- path: path40,
10293
+ path: path41,
10253
10294
  score: 0,
10254
10295
  weight,
10255
10296
  hit: false,
10256
- message: `${path40} (invalid numeric value)`
10297
+ message: `${path41} (invalid numeric value)`
10257
10298
  };
10258
10299
  }
10259
10300
  const diff = Math.abs(candidateNum - expectedNum);
@@ -10266,61 +10307,61 @@ var FieldAccuracyEvaluator = class {
10266
10307
  }
10267
10308
  if (withinTolerance) {
10268
10309
  return {
10269
- path: path40,
10310
+ path: path41,
10270
10311
  score: 1,
10271
10312
  weight,
10272
10313
  hit: true,
10273
- message: `${path40} (within tolerance: diff=${diff.toFixed(2)})`
10314
+ message: `${path41} (within tolerance: diff=${diff.toFixed(2)})`
10274
10315
  };
10275
10316
  }
10276
10317
  return {
10277
- path: path40,
10318
+ path: path41,
10278
10319
  score: 0,
10279
10320
  weight,
10280
10321
  hit: false,
10281
- message: `${path40} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
10322
+ message: `${path41} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
10282
10323
  };
10283
10324
  }
10284
10325
  /**
10285
10326
  * Date comparison with format normalization.
10286
10327
  */
10287
- compareDate(path40, candidateValue, expectedValue, fieldConfig, weight) {
10328
+ compareDate(path41, candidateValue, expectedValue, fieldConfig, weight) {
10288
10329
  const formats = fieldConfig.formats ?? DEFAULT_DATE_FORMATS;
10289
10330
  const candidateDate = parseDate(String(candidateValue), formats);
10290
10331
  const expectedDate = parseDate(String(expectedValue), formats);
10291
10332
  if (candidateDate === null) {
10292
10333
  return {
10293
- path: path40,
10334
+ path: path41,
10294
10335
  score: 0,
10295
10336
  weight,
10296
10337
  hit: false,
10297
- message: `${path40} (unparseable candidate date)`
10338
+ message: `${path41} (unparseable candidate date)`
10298
10339
  };
10299
10340
  }
10300
10341
  if (expectedDate === null) {
10301
10342
  return {
10302
- path: path40,
10343
+ path: path41,
10303
10344
  score: 0,
10304
10345
  weight,
10305
10346
  hit: false,
10306
- message: `${path40} (unparseable expected date)`
10347
+ message: `${path41} (unparseable expected date)`
10307
10348
  };
10308
10349
  }
10309
10350
  if (candidateDate.getFullYear() === expectedDate.getFullYear() && candidateDate.getMonth() === expectedDate.getMonth() && candidateDate.getDate() === expectedDate.getDate()) {
10310
10351
  return {
10311
- path: path40,
10352
+ path: path41,
10312
10353
  score: 1,
10313
10354
  weight,
10314
10355
  hit: true,
10315
- message: path40
10356
+ message: path41
10316
10357
  };
10317
10358
  }
10318
10359
  return {
10319
- path: path40,
10360
+ path: path41,
10320
10361
  score: 0,
10321
10362
  weight,
10322
10363
  hit: false,
10323
- message: `${path40} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
10364
+ message: `${path41} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
10324
10365
  };
10325
10366
  }
10326
10367
  /**
@@ -10361,11 +10402,11 @@ var FieldAccuracyEvaluator = class {
10361
10402
  };
10362
10403
  }
10363
10404
  };
10364
- function resolvePath(obj, path40) {
10365
- if (!path40 || !obj) {
10405
+ function resolvePath(obj, path41) {
10406
+ if (!path41 || !obj) {
10366
10407
  return void 0;
10367
10408
  }
10368
- const parts = path40.split(/\.|\[|\]/).filter((p) => p.length > 0);
10409
+ const parts = path41.split(/\.|\[|\]/).filter((p) => p.length > 0);
10369
10410
  let current = obj;
10370
10411
  for (const part of parts) {
10371
10412
  if (current === null || current === void 0) {
@@ -10497,7 +10538,7 @@ var LatencyEvaluator = class {
10497
10538
 
10498
10539
  // src/evaluation/evaluators/agent-judge.ts
10499
10540
  import fs2 from "node:fs/promises";
10500
- import path30 from "node:path";
10541
+ import path31 from "node:path";
10501
10542
  import { generateText as generateText4, stepCountIs, tool } from "ai";
10502
10543
  import { z as z4 } from "zod";
10503
10544
  var DEFAULT_MAX_STEPS = 10;
@@ -10846,8 +10887,8 @@ ${outputSchema}`;
10846
10887
  }
10847
10888
  };
10848
10889
  function resolveSandboxed(basePath, relativePath) {
10849
- const resolved = path30.resolve(basePath, relativePath);
10850
- if (!resolved.startsWith(basePath + path30.sep) && resolved !== basePath) {
10890
+ const resolved = path31.resolve(basePath, relativePath);
10891
+ if (!resolved.startsWith(basePath + path31.sep) && resolved !== basePath) {
10851
10892
  throw new Error(`Path '${relativePath}' is outside the workspace`);
10852
10893
  }
10853
10894
  return resolved;
@@ -10930,11 +10971,11 @@ async function searchDirectory(dirPath, workspacePath, regex, matches) {
10930
10971
  for (const entry of entries) {
10931
10972
  if (matches.length >= MAX_SEARCH_MATCHES) return;
10932
10973
  if (SEARCH_SKIP_DIRS.has(entry.name)) continue;
10933
- const fullPath = path30.join(dirPath, entry.name);
10974
+ const fullPath = path31.join(dirPath, entry.name);
10934
10975
  if (entry.isDirectory()) {
10935
10976
  await searchDirectory(fullPath, workspacePath, regex, matches);
10936
10977
  } else if (entry.isFile()) {
10937
- const ext = path30.extname(entry.name).toLowerCase();
10978
+ const ext = path31.extname(entry.name).toLowerCase();
10938
10979
  if (BINARY_EXTENSIONS.has(ext)) continue;
10939
10980
  try {
10940
10981
  const stat8 = await fs2.stat(fullPath);
@@ -10946,7 +10987,7 @@ async function searchDirectory(dirPath, workspacePath, regex, matches) {
10946
10987
  regex.lastIndex = 0;
10947
10988
  if (regex.test(lines[i])) {
10948
10989
  matches.push({
10949
- file: path30.relative(workspacePath, fullPath),
10990
+ file: path31.relative(workspacePath, fullPath),
10950
10991
  line: i + 1,
10951
10992
  text: lines[i].substring(0, 200)
10952
10993
  });
@@ -11183,8 +11224,8 @@ var TokenUsageEvaluator = class {
11183
11224
  };
11184
11225
 
11185
11226
  // src/evaluation/evaluators/tool-trajectory.ts
11186
- function getNestedValue(obj, path40) {
11187
- const parts = path40.split(".");
11227
+ function getNestedValue(obj, path41) {
11228
+ const parts = path41.split(".");
11188
11229
  let current = obj;
11189
11230
  for (const part of parts) {
11190
11231
  if (current === null || current === void 0 || typeof current !== "object") {
@@ -11747,7 +11788,7 @@ function runEqualsAssertion(output, value) {
11747
11788
  // src/evaluation/orchestrator.ts
11748
11789
  import { createHash as createHash2, randomUUID as randomUUID7 } from "node:crypto";
11749
11790
  import { mkdir as mkdir12, stat as stat7 } from "node:fs/promises";
11750
- import path37 from "node:path";
11791
+ import path38 from "node:path";
11751
11792
  import micromatch4 from "micromatch";
11752
11793
 
11753
11794
  // ../../node_modules/.bun/yocto-queue@1.2.2/node_modules/yocto-queue/index.js
@@ -11938,7 +11979,7 @@ var DeterministicAssertionEvaluator = class {
11938
11979
  import { readFileSync } from "node:fs";
11939
11980
 
11940
11981
  // src/evaluation/evaluators/prompt-resolution.ts
11941
- import path31 from "node:path";
11982
+ import path32 from "node:path";
11942
11983
  async function resolveCustomPrompt(promptConfig, context, timeoutMs) {
11943
11984
  if (promptConfig.resolvedPromptScript && promptConfig.resolvedPromptScript.length > 0) {
11944
11985
  if (!context) {
@@ -11987,7 +12028,7 @@ async function executePromptTemplate(script, context, config, timeoutMs) {
11987
12028
  };
11988
12029
  const inputJson = JSON.stringify(toSnakeCaseDeep(payload), null, 2);
11989
12030
  const scriptPath = script[script.length - 1];
11990
- const cwd = path31.dirname(scriptPath);
12031
+ const cwd = path32.dirname(scriptPath);
11991
12032
  try {
11992
12033
  const stdout = await executeScript(script, inputJson, timeoutMs, cwd);
11993
12034
  const prompt = stdout.trim();
@@ -12280,16 +12321,16 @@ function createBuiltinRegistry() {
12280
12321
  }
12281
12322
 
12282
12323
  // src/evaluation/registry/assertion-discovery.ts
12283
- import path32 from "node:path";
12324
+ import path33 from "node:path";
12284
12325
  import fg3 from "fast-glob";
12285
12326
  async function discoverAssertions(registry, baseDir) {
12286
12327
  const patterns = ["*.ts", "*.js", "*.mts", "*.mjs"];
12287
12328
  const candidateDirs = [];
12288
- let dir = path32.resolve(baseDir);
12289
- const root = path32.parse(dir).root;
12329
+ let dir = path33.resolve(baseDir);
12330
+ const root = path33.parse(dir).root;
12290
12331
  while (dir !== root) {
12291
- candidateDirs.push(path32.join(dir, ".agentv", "assertions"));
12292
- dir = path32.dirname(dir);
12332
+ candidateDirs.push(path33.join(dir, ".agentv", "assertions"));
12333
+ dir = path33.dirname(dir);
12293
12334
  }
12294
12335
  let files = [];
12295
12336
  for (const assertionsDir of candidateDirs) {
@@ -12305,7 +12346,7 @@ async function discoverAssertions(registry, baseDir) {
12305
12346
  }
12306
12347
  const discoveredTypes = [];
12307
12348
  for (const filePath of files) {
12308
- const basename = path32.basename(filePath);
12349
+ const basename = path33.basename(filePath);
12309
12350
  const typeName = basename.replace(/\.(ts|js|mts|mjs)$/, "");
12310
12351
  if (registry.has(typeName)) {
12311
12352
  continue;
@@ -12465,7 +12506,7 @@ function getTCritical(df) {
12465
12506
  // src/evaluation/workspace/file-changes.ts
12466
12507
  import { exec as execCallback } from "node:child_process";
12467
12508
  import { readdirSync as readdirSync2, statSync } from "node:fs";
12468
- import path33 from "node:path";
12509
+ import path34 from "node:path";
12469
12510
  import { promisify as promisify4 } from "node:util";
12470
12511
  var execAsync4 = promisify4(execCallback);
12471
12512
  function gitExecOpts(workspacePath) {
@@ -12499,10 +12540,10 @@ async function stageNestedRepoChanges(workspacePath) {
12499
12540
  }
12500
12541
  for (const entry of entries) {
12501
12542
  if (entry === ".git" || entry === "node_modules") continue;
12502
- const childPath = path33.join(workspacePath, entry);
12543
+ const childPath = path34.join(workspacePath, entry);
12503
12544
  try {
12504
12545
  if (!statSync(childPath).isDirectory()) continue;
12505
- if (!statSync(path33.join(childPath, ".git")).isDirectory()) continue;
12546
+ if (!statSync(path34.join(childPath, ".git")).isDirectory()) continue;
12506
12547
  } catch {
12507
12548
  continue;
12508
12549
  }
@@ -12513,9 +12554,7 @@ async function stageNestedRepoChanges(workspacePath) {
12513
12554
 
12514
12555
  // src/evaluation/workspace/manager.ts
12515
12556
  import { cp, mkdir as mkdir10, readdir as readdir3, rm as rm4, stat as stat5 } from "node:fs/promises";
12516
- import os3 from "node:os";
12517
- import path34 from "node:path";
12518
- var DEFAULT_WORKSPACE_ROOT = path34.join(os3.homedir(), ".agentv", "workspaces");
12557
+ import path35 from "node:path";
12519
12558
  var TemplateNotFoundError = class extends Error {
12520
12559
  constructor(templatePath) {
12521
12560
  super(`Workspace template not found: ${templatePath}`);
@@ -12544,15 +12583,15 @@ async function isDirectory(filePath) {
12544
12583
  }
12545
12584
  }
12546
12585
  function getWorkspacePath(evalRunId, caseId, workspaceRoot) {
12547
- const root = workspaceRoot ?? DEFAULT_WORKSPACE_ROOT;
12548
- return path34.join(root, evalRunId, caseId);
12586
+ const root = workspaceRoot ?? getWorkspacesRoot();
12587
+ return path35.join(root, evalRunId, caseId);
12549
12588
  }
12550
12589
  async function copyDirectoryRecursive(src, dest) {
12551
12590
  await mkdir10(dest, { recursive: true });
12552
12591
  const entries = await readdir3(src, { withFileTypes: true });
12553
12592
  for (const entry of entries) {
12554
- const srcPath = path34.join(src, entry.name);
12555
- const destPath = path34.join(dest, entry.name);
12593
+ const srcPath = path35.join(src, entry.name);
12594
+ const destPath = path35.join(dest, entry.name);
12556
12595
  if (entry.name === ".git") {
12557
12596
  continue;
12558
12597
  }
@@ -12564,7 +12603,7 @@ async function copyDirectoryRecursive(src, dest) {
12564
12603
  }
12565
12604
  }
12566
12605
  async function createTempWorkspace(templatePath, evalRunId, caseId, workspaceRoot) {
12567
- const resolvedTemplatePath = path34.resolve(templatePath);
12606
+ const resolvedTemplatePath = path35.resolve(templatePath);
12568
12607
  if (!await fileExists(resolvedTemplatePath)) {
12569
12608
  throw new TemplateNotFoundError(resolvedTemplatePath);
12570
12609
  }
@@ -12612,8 +12651,8 @@ async function cleanupWorkspace(workspacePath) {
12612
12651
  }
12613
12652
  }
12614
12653
  async function cleanupEvalWorkspaces(evalRunId, workspaceRoot) {
12615
- const root = workspaceRoot ?? DEFAULT_WORKSPACE_ROOT;
12616
- const evalDir = path34.join(root, evalRunId);
12654
+ const root = workspaceRoot ?? getWorkspacesRoot();
12655
+ const evalDir = path35.join(root, evalRunId);
12617
12656
  if (await fileExists(evalDir)) {
12618
12657
  await rm4(evalDir, { recursive: true, force: true });
12619
12658
  }
@@ -12624,11 +12663,9 @@ import { execFile } from "node:child_process";
12624
12663
  import { createHash } from "node:crypto";
12625
12664
  import { existsSync as existsSync2 } from "node:fs";
12626
12665
  import { mkdir as mkdir11, rm as rm5, unlink, writeFile as writeFile7 } from "node:fs/promises";
12627
- import os4 from "node:os";
12628
- import path35 from "node:path";
12666
+ import path36 from "node:path";
12629
12667
  import { promisify as promisify5 } from "node:util";
12630
12668
  var execFileAsync = promisify5(execFile);
12631
- var DEFAULT_CACHE_DIR = path35.join(os4.homedir(), ".agentv", "git-cache");
12632
12669
  var DEFAULT_TIMEOUT_MS2 = 3e5;
12633
12670
  var LOCK_TIMEOUT_MS = 6e4;
12634
12671
  function gitEnv() {
@@ -12686,8 +12723,35 @@ async function releaseLock(lockPath) {
12686
12723
  }
12687
12724
  var RepoManager = class {
12688
12725
  cacheDir;
12689
- constructor(cacheDir) {
12690
- this.cacheDir = cacheDir ?? DEFAULT_CACHE_DIR;
12726
+ verbose;
12727
+ constructor(cacheDir, verbose = false) {
12728
+ this.cacheDir = cacheDir ?? getGitCacheRoot();
12729
+ this.verbose = verbose;
12730
+ }
12731
+ async runGit(args, opts) {
12732
+ const startedAt = Date.now();
12733
+ if (this.verbose) {
12734
+ console.log(
12735
+ `[repo] git start cwd=${opts?.cwd ?? process.cwd()} args=${args.join(" ")}`
12736
+ );
12737
+ }
12738
+ try {
12739
+ const output = await git(args, opts);
12740
+ if (this.verbose) {
12741
+ console.log(
12742
+ `[repo] git ok durationMs=${Date.now() - startedAt} args=${args.join(" ")}`
12743
+ );
12744
+ }
12745
+ return output;
12746
+ } catch (error) {
12747
+ if (this.verbose) {
12748
+ const message = error instanceof Error ? error.message : String(error);
12749
+ console.log(
12750
+ `[repo] git fail durationMs=${Date.now() - startedAt} args=${args.join(" ")} error=${message}`
12751
+ );
12752
+ }
12753
+ throw error;
12754
+ }
12691
12755
  }
12692
12756
  /**
12693
12757
  * Ensure a bare mirror cache exists for the given source.
@@ -12696,11 +12760,19 @@ var RepoManager = class {
12696
12760
  */
12697
12761
  async ensureCache(source, depth, resolve) {
12698
12762
  const key = cacheKey(source);
12699
- const cachePath = path35.join(this.cacheDir, key);
12763
+ const cachePath = path36.join(this.cacheDir, key);
12700
12764
  const lockPath = `${cachePath}.lock`;
12701
- const cacheExists = existsSync2(path35.join(cachePath, "HEAD"));
12765
+ const cacheExists = existsSync2(path36.join(cachePath, "HEAD"));
12766
+ if (this.verbose) {
12767
+ console.log(
12768
+ `[repo] ensureCache source=${getSourceUrl(source)} resolve=${resolve ?? "remote"} cache=${cachePath}`
12769
+ );
12770
+ }
12702
12771
  if (resolve === "local") {
12703
12772
  if (cacheExists) {
12773
+ if (this.verbose) {
12774
+ console.log(`[repo] using existing local cache ${cachePath}`);
12775
+ }
12704
12776
  return cachePath;
12705
12777
  }
12706
12778
  const url = getSourceUrl(source);
@@ -12709,15 +12781,27 @@ var RepoManager = class {
12709
12781
  );
12710
12782
  }
12711
12783
  await mkdir11(this.cacheDir, { recursive: true });
12784
+ const lockStartedAt = Date.now();
12712
12785
  await acquireLock(lockPath);
12786
+ if (this.verbose) {
12787
+ console.log(
12788
+ `[repo] lock acquired path=${lockPath} waitedMs=${Date.now() - lockStartedAt}`
12789
+ );
12790
+ }
12713
12791
  try {
12714
12792
  if (cacheExists) {
12793
+ if (this.verbose) {
12794
+ console.log(`[repo] refreshing existing cache ${cachePath}`);
12795
+ }
12715
12796
  const fetchArgs = ["fetch", "--prune"];
12716
12797
  if (depth) {
12717
12798
  fetchArgs.push("--depth", String(depth));
12718
12799
  }
12719
- await git(fetchArgs, { cwd: cachePath });
12800
+ await this.runGit(fetchArgs, { cwd: cachePath });
12720
12801
  } else {
12802
+ if (this.verbose) {
12803
+ console.log(`[repo] creating new cache ${cachePath}`);
12804
+ }
12721
12805
  const cloneArgs = ["clone", "--mirror", "--bare"];
12722
12806
  if (depth) {
12723
12807
  cloneArgs.push("--depth", String(depth));
@@ -12725,10 +12809,13 @@ var RepoManager = class {
12725
12809
  const sourceUrl = getSourceUrl(source);
12726
12810
  const cloneUrl = depth && source.type === "local" ? `file://${sourceUrl}` : sourceUrl;
12727
12811
  cloneArgs.push(cloneUrl, cachePath);
12728
- await git(cloneArgs);
12812
+ await this.runGit(cloneArgs);
12729
12813
  }
12730
12814
  } finally {
12731
12815
  await releaseLock(lockPath);
12816
+ if (this.verbose) {
12817
+ console.log(`[repo] lock released path=${lockPath}`);
12818
+ }
12732
12819
  }
12733
12820
  return cachePath;
12734
12821
  }
@@ -12737,7 +12824,13 @@ var RepoManager = class {
12737
12824
  * Handles checkout, ref resolution, ancestor walking, shallow clone, sparse checkout.
12738
12825
  */
12739
12826
  async materialize(repo, workspacePath) {
12740
- const targetDir = path35.join(workspacePath, repo.path);
12827
+ const targetDir = path36.join(workspacePath, repo.path);
12828
+ const startedAt = Date.now();
12829
+ if (this.verbose) {
12830
+ console.log(
12831
+ `[repo] materialize start path=${repo.path} source=${getSourceUrl(repo.source)} workspace=${workspacePath}`
12832
+ );
12833
+ }
12741
12834
  const cachePath = await this.ensureCache(
12742
12835
  repo.source,
12743
12836
  repo.clone?.depth,
@@ -12753,10 +12846,10 @@ var RepoManager = class {
12753
12846
  cloneArgs.push("--no-checkout");
12754
12847
  const cloneUrl = repo.clone?.depth || repo.clone?.filter ? `file://${cachePath}` : cachePath;
12755
12848
  cloneArgs.push(cloneUrl, targetDir);
12756
- await git(cloneArgs);
12849
+ await this.runGit(cloneArgs);
12757
12850
  if (repo.clone?.sparse?.length) {
12758
- await git(["sparse-checkout", "init", "--cone"], { cwd: targetDir });
12759
- await git(["sparse-checkout", "set", ...repo.clone.sparse], { cwd: targetDir });
12851
+ await this.runGit(["sparse-checkout", "init", "--cone"], { cwd: targetDir });
12852
+ await this.runGit(["sparse-checkout", "set", ...repo.clone.sparse], { cwd: targetDir });
12760
12853
  }
12761
12854
  const ref = repo.checkout?.ref ?? "HEAD";
12762
12855
  const resolve = repo.checkout?.resolve ?? "remote";
@@ -12764,7 +12857,7 @@ var RepoManager = class {
12764
12857
  if (resolve === "remote" && repo.source.type === "git") {
12765
12858
  const url = getSourceUrl(repo.source);
12766
12859
  try {
12767
- const lsOutput = await git(["ls-remote", url, ref]);
12860
+ const lsOutput = await this.runGit(["ls-remote", url, ref]);
12768
12861
  const match = lsOutput.split(" ")[0];
12769
12862
  if (!match) {
12770
12863
  throw new Error(`Ref '${ref}' not found on remote ${url}`);
@@ -12777,17 +12870,26 @@ var RepoManager = class {
12777
12870
  } else {
12778
12871
  resolvedSha = ref;
12779
12872
  }
12780
- await git(["checkout", resolvedSha], { cwd: targetDir });
12873
+ if (this.verbose) {
12874
+ console.log(
12875
+ `[repo] checkout path=${repo.path} ref=${ref} resolved=${resolvedSha} resolve=${resolve}`
12876
+ );
12877
+ }
12878
+ await this.runGit(["checkout", resolvedSha], { cwd: targetDir });
12781
12879
  const ancestor = repo.checkout?.ancestor ?? 0;
12782
12880
  if (ancestor > 0) {
12783
12881
  try {
12784
- const ancestorSha = await git(["rev-parse", `HEAD~${ancestor}`], { cwd: targetDir });
12785
- await git(["checkout", ancestorSha], { cwd: targetDir });
12882
+ const ancestorSha = await this.runGit(["rev-parse", `HEAD~${ancestor}`], {
12883
+ cwd: targetDir
12884
+ });
12885
+ await this.runGit(["checkout", ancestorSha], { cwd: targetDir });
12786
12886
  } catch {
12787
12887
  if (repo.clone?.depth) {
12788
- await git(["fetch", "--deepen", String(ancestor)], { cwd: targetDir });
12789
- const ancestorSha = await git(["rev-parse", `HEAD~${ancestor}`], { cwd: targetDir });
12790
- await git(["checkout", ancestorSha], { cwd: targetDir });
12888
+ await this.runGit(["fetch", "--deepen", String(ancestor)], { cwd: targetDir });
12889
+ const ancestorSha = await this.runGit(["rev-parse", `HEAD~${ancestor}`], {
12890
+ cwd: targetDir
12891
+ });
12892
+ await this.runGit(["checkout", ancestorSha], { cwd: targetDir });
12791
12893
  } else {
12792
12894
  throw new Error(
12793
12895
  `Cannot resolve ancestor ${ancestor} of ref '${ref}'. If using shallow clone, increase clone.depth to at least ${ancestor + 1}.`
@@ -12795,27 +12897,38 @@ var RepoManager = class {
12795
12897
  }
12796
12898
  }
12797
12899
  }
12900
+ if (this.verbose) {
12901
+ console.log(
12902
+ `[repo] materialize done path=${repo.path} target=${targetDir} durationMs=${Date.now() - startedAt}`
12903
+ );
12904
+ }
12798
12905
  }
12799
12906
  /** Materialize all repos into the workspace. */
12800
12907
  async materializeAll(repos, workspacePath) {
12908
+ if (this.verbose) {
12909
+ console.log(`[repo] materializeAll count=${repos.length} workspace=${workspacePath}`);
12910
+ }
12801
12911
  for (const repo of repos) {
12802
12912
  await this.materialize(repo, workspacePath);
12803
12913
  }
12914
+ if (this.verbose) {
12915
+ console.log("[repo] materializeAll complete");
12916
+ }
12804
12917
  }
12805
12918
  /** Reset repos in workspace to their checkout state. */
12806
12919
  async reset(repos, workspacePath, strategy) {
12807
12920
  if (strategy === "recreate") {
12808
12921
  for (const repo of repos) {
12809
- const targetDir = path35.join(workspacePath, repo.path);
12922
+ const targetDir = path36.join(workspacePath, repo.path);
12810
12923
  await rm5(targetDir, { recursive: true, force: true });
12811
12924
  }
12812
12925
  await this.materializeAll(repos, workspacePath);
12813
12926
  return;
12814
12927
  }
12815
12928
  for (const repo of repos) {
12816
- const targetDir = path35.join(workspacePath, repo.path);
12817
- await git(["reset", "--hard", "HEAD"], { cwd: targetDir });
12818
- await git(["clean", "-fd"], { cwd: targetDir });
12929
+ const targetDir = path36.join(workspacePath, repo.path);
12930
+ await this.runGit(["reset", "--hard", "HEAD"], { cwd: targetDir });
12931
+ await this.runGit(["clean", "-fd"], { cwd: targetDir });
12819
12932
  }
12820
12933
  }
12821
12934
  /**
@@ -12825,12 +12938,12 @@ var RepoManager = class {
12825
12938
  async seedCache(localPath, remoteUrl, opts) {
12826
12939
  const source = { type: "git", url: remoteUrl };
12827
12940
  const key = cacheKey(source);
12828
- const cachePath = path35.join(this.cacheDir, key);
12941
+ const cachePath = path36.join(this.cacheDir, key);
12829
12942
  const lockPath = `${cachePath}.lock`;
12830
12943
  await mkdir11(this.cacheDir, { recursive: true });
12831
12944
  await acquireLock(lockPath);
12832
12945
  try {
12833
- if (existsSync2(path35.join(cachePath, "HEAD"))) {
12946
+ if (existsSync2(path36.join(cachePath, "HEAD"))) {
12834
12947
  if (!opts?.force) {
12835
12948
  throw new Error(
12836
12949
  `Cache already exists for ${remoteUrl} at ${cachePath}. Use force to overwrite.`
@@ -12853,16 +12966,16 @@ var RepoManager = class {
12853
12966
 
12854
12967
  // src/evaluation/workspace/resolve.ts
12855
12968
  import { readdir as readdir4, stat as stat6 } from "node:fs/promises";
12856
- import path36 from "node:path";
12969
+ import path37 from "node:path";
12857
12970
  async function resolveWorkspaceTemplate(templatePath) {
12858
12971
  if (!templatePath) {
12859
12972
  return void 0;
12860
12973
  }
12861
- const resolved = path36.resolve(templatePath);
12974
+ const resolved = path37.resolve(templatePath);
12862
12975
  const stats = await stat6(resolved);
12863
12976
  if (stats.isFile()) {
12864
12977
  return {
12865
- dir: path36.dirname(resolved),
12978
+ dir: path37.dirname(resolved),
12866
12979
  workspaceFile: resolved
12867
12980
  };
12868
12981
  }
@@ -12874,14 +12987,14 @@ async function resolveWorkspaceTemplate(templatePath) {
12874
12987
  if (workspaceFiles.length === 1) {
12875
12988
  return {
12876
12989
  dir: resolved,
12877
- workspaceFile: path36.join(resolved, workspaceFiles[0])
12990
+ workspaceFile: path37.join(resolved, workspaceFiles[0])
12878
12991
  };
12879
12992
  }
12880
12993
  if (workspaceFiles.length > 1) {
12881
12994
  const conventionFile = workspaceFiles.find((f) => f === "template.code-workspace");
12882
12995
  return {
12883
12996
  dir: resolved,
12884
- workspaceFile: conventionFile ? path36.join(resolved, conventionFile) : void 0
12997
+ workspaceFile: conventionFile ? path37.join(resolved, conventionFile) : void 0
12885
12998
  };
12886
12999
  }
12887
13000
  return { dir: resolved };
@@ -13037,7 +13150,7 @@ async function runEvaluation(options) {
13037
13150
  ];
13038
13151
  const evaluatorRegistry = buildEvaluatorRegistry(evaluators, resolveJudgeProvider);
13039
13152
  const typeRegistry = createBuiltinRegistry();
13040
- const discoveryBaseDir = evalFilePath ? path37.dirname(path37.resolve(evalFilePath)) : process.cwd();
13153
+ const discoveryBaseDir = evalFilePath ? path38.dirname(path38.resolve(evalFilePath)) : process.cwd();
13041
13154
  const evalDir = discoveryBaseDir;
13042
13155
  await discoverAssertions(typeRegistry, discoveryBaseDir);
13043
13156
  const providerRegistry = createBuiltinProviderRegistry();
@@ -13093,10 +13206,18 @@ async function runEvaluation(options) {
13093
13206
  const resolvedTemplate = await resolveWorkspaceTemplate(rawTemplate);
13094
13207
  const workspaceTemplate = resolvedTemplate?.dir;
13095
13208
  let suiteWorkspaceFile = resolvedTemplate?.workspaceFile;
13209
+ const setupLog = (message) => {
13210
+ if (verbose) {
13211
+ console.log(`[setup] ${message}`);
13212
+ }
13213
+ };
13096
13214
  const isPerTestIsolation = suiteWorkspace?.isolation === "per_test";
13097
13215
  const hasSharedWorkspace = !!(workspaceTemplate || suiteWorkspace?.before_all || suiteWorkspace?.repos?.length && !isPerTestIsolation);
13098
13216
  const requestedWorkers = options.maxConcurrency ?? target.workers ?? 1;
13099
13217
  const workers = hasSharedWorkspace ? 1 : requestedWorkers;
13218
+ setupLog(
13219
+ `sharedWorkspace=${hasSharedWorkspace} perTestIsolation=${isPerTestIsolation} requestedWorkers=${requestedWorkers} effectiveWorkers=${workers}`
13220
+ );
13100
13221
  if (hasSharedWorkspace && requestedWorkers > 1) {
13101
13222
  console.warn(
13102
13223
  `Warning: Shared workspace requires sequential execution. Overriding workers from ${requestedWorkers} to 1.`
@@ -13107,14 +13228,16 @@ async function runEvaluation(options) {
13107
13228
  let sharedBaselineCommit;
13108
13229
  let beforeAllOutput;
13109
13230
  if (workspaceTemplate) {
13231
+ setupLog(`creating shared workspace from template: ${workspaceTemplate}`);
13110
13232
  try {
13111
13233
  sharedWorkspacePath = await createTempWorkspace(workspaceTemplate, evalRunId, "shared");
13234
+ setupLog(`shared workspace created at: ${sharedWorkspacePath}`);
13112
13235
  } catch (error) {
13113
13236
  const message = error instanceof Error ? error.message : String(error);
13114
13237
  throw new Error(`Failed to create shared workspace: ${message}`);
13115
13238
  }
13116
13239
  if (suiteWorkspaceFile && sharedWorkspacePath) {
13117
- const copiedWorkspaceFile = path37.join(sharedWorkspacePath, path37.basename(suiteWorkspaceFile));
13240
+ const copiedWorkspaceFile = path38.join(sharedWorkspacePath, path38.basename(suiteWorkspaceFile));
13118
13241
  try {
13119
13242
  await stat7(copiedWorkspaceFile);
13120
13243
  suiteWorkspaceFile = copiedWorkspaceFile;
@@ -13124,11 +13247,14 @@ async function runEvaluation(options) {
13124
13247
  } else if (suiteWorkspace?.before_all || suiteWorkspace?.repos?.length && !isPerTestIsolation) {
13125
13248
  sharedWorkspacePath = getWorkspacePath(evalRunId, "shared");
13126
13249
  await mkdir12(sharedWorkspacePath, { recursive: true });
13250
+ setupLog(`created empty shared workspace at: ${sharedWorkspacePath}`);
13127
13251
  }
13128
- const repoManager = suiteWorkspace?.repos?.length ? new RepoManager() : void 0;
13252
+ const repoManager = suiteWorkspace?.repos?.length ? new RepoManager(void 0, verbose) : void 0;
13129
13253
  if (repoManager && sharedWorkspacePath && suiteWorkspace?.repos && !isPerTestIsolation) {
13254
+ setupLog(`materializing ${suiteWorkspace.repos.length} shared repo(s) into ${sharedWorkspacePath}`);
13130
13255
  try {
13131
13256
  await repoManager.materializeAll(suiteWorkspace.repos, sharedWorkspacePath);
13257
+ setupLog("shared repo materialization complete");
13132
13258
  } catch (error) {
13133
13259
  const message = error instanceof Error ? error.message : String(error);
13134
13260
  if (sharedWorkspacePath) {
@@ -13139,6 +13265,10 @@ async function runEvaluation(options) {
13139
13265
  }
13140
13266
  }
13141
13267
  if (sharedWorkspacePath && suiteWorkspace?.before_all) {
13268
+ const beforeAllCommand = (suiteWorkspace.before_all.command ?? suiteWorkspace.before_all.script ?? []).join(" ");
13269
+ setupLog(
13270
+ `running shared before_all in cwd=${suiteWorkspace.before_all.cwd ?? evalDir} command=${beforeAllCommand}`
13271
+ );
13142
13272
  const scriptContext = {
13143
13273
  workspacePath: sharedWorkspacePath,
13144
13274
  testId: "__before_all__",
@@ -13147,6 +13277,7 @@ async function runEvaluation(options) {
13147
13277
  };
13148
13278
  try {
13149
13279
  beforeAllOutput = await executeWorkspaceScript(suiteWorkspace.before_all, scriptContext);
13280
+ setupLog("shared before_all completed");
13150
13281
  } catch (error) {
13151
13282
  const message = error instanceof Error ? error.message : String(error);
13152
13283
  if (sharedWorkspacePath) {
@@ -13159,7 +13290,9 @@ async function runEvaluation(options) {
13159
13290
  if (sharedWorkspacePath) {
13160
13291
  try {
13161
13292
  sharedBaselineCommit = await initializeBaseline(sharedWorkspacePath);
13293
+ setupLog(`shared baseline initialized: ${sharedBaselineCommit}`);
13162
13294
  } catch {
13295
+ setupLog("shared baseline initialization skipped (non-fatal)");
13163
13296
  }
13164
13297
  }
13165
13298
  let nextWorkerId = 1;
@@ -13563,6 +13696,7 @@ async function runEvalCase(options) {
13563
13696
  repoManager,
13564
13697
  evalDir
13565
13698
  } = options;
13699
+ const setupDebug = process.env.AGENTV_SETUP_DEBUG === "1";
13566
13700
  const formattingMode = usesFileReferencePrompt(provider) ? "agent" : "lm";
13567
13701
  const promptInputs = await buildPromptInputs(evalCase, formattingMode);
13568
13702
  const typeRegistry = providedTypeRegistry ?? createBuiltinRegistry();
@@ -13600,7 +13734,7 @@ async function runEvalCase(options) {
13600
13734
  );
13601
13735
  }
13602
13736
  if (caseWorkspaceFile && workspacePath) {
13603
- const copiedFile = path37.join(workspacePath, path37.basename(caseWorkspaceFile));
13737
+ const copiedFile = path38.join(workspacePath, path38.basename(caseWorkspaceFile));
13604
13738
  try {
13605
13739
  await stat7(copiedFile);
13606
13740
  caseWorkspaceFile = copiedFile;
@@ -13613,9 +13747,17 @@ async function runEvalCase(options) {
13613
13747
  await mkdir12(workspacePath, { recursive: true });
13614
13748
  }
13615
13749
  if (evalCase.workspace?.repos?.length && workspacePath) {
13616
- const perCaseRepoManager = new RepoManager();
13750
+ const perCaseRepoManager = new RepoManager(void 0, setupDebug);
13617
13751
  try {
13752
+ if (setupDebug) {
13753
+ console.log(
13754
+ `[setup] test=${evalCase.id} materializing ${evalCase.workspace.repos.length} per-test repo(s) into ${workspacePath}`
13755
+ );
13756
+ }
13618
13757
  await perCaseRepoManager.materializeAll(evalCase.workspace.repos, workspacePath);
13758
+ if (setupDebug) {
13759
+ console.log(`[setup] test=${evalCase.id} per-test repo materialization complete`);
13760
+ }
13619
13761
  } catch (error) {
13620
13762
  const message = error instanceof Error ? error.message : String(error);
13621
13763
  return buildErrorResult(
@@ -13631,6 +13773,12 @@ async function runEvalCase(options) {
13631
13773
  }
13632
13774
  }
13633
13775
  if (workspacePath && evalCase.workspace?.before_all) {
13776
+ const beforeAllCommand = (evalCase.workspace.before_all.command ?? evalCase.workspace.before_all.script ?? []).join(" ");
13777
+ if (setupDebug) {
13778
+ console.log(
13779
+ `[setup] test=${evalCase.id} running before_all in cwd=${evalCase.workspace.before_all.cwd ?? evalDir} command=${beforeAllCommand}`
13780
+ );
13781
+ }
13634
13782
  const scriptContext = {
13635
13783
  workspacePath,
13636
13784
  testId: evalCase.id,
@@ -13644,6 +13792,9 @@ async function runEvalCase(options) {
13644
13792
  evalCase.workspace.before_all,
13645
13793
  scriptContext
13646
13794
  );
13795
+ if (setupDebug) {
13796
+ console.log(`[setup] test=${evalCase.id} before_all completed`);
13797
+ }
13647
13798
  } catch (error) {
13648
13799
  const message = error instanceof Error ? error.message : String(error);
13649
13800
  if (forceCleanup && workspacePath) {
@@ -14193,7 +14344,7 @@ async function runEvaluatorList(options) {
14193
14344
  fileChanges,
14194
14345
  workspacePath
14195
14346
  };
14196
- const evalFileDir = evalCase.guideline_paths[0] ? path37.dirname(evalCase.guideline_paths[0]) : process.cwd();
14347
+ const evalFileDir = evalCase.guideline_paths[0] ? path38.dirname(evalCase.guideline_paths[0]) : process.cwd();
14197
14348
  const dispatchContext = {
14198
14349
  judgeProvider,
14199
14350
  targetResolver,
@@ -14496,7 +14647,7 @@ function computeWeightedMean(entries) {
14496
14647
 
14497
14648
  // src/evaluation/evaluate.ts
14498
14649
  import { existsSync as existsSync3 } from "node:fs";
14499
- import path38 from "node:path";
14650
+ import path39 from "node:path";
14500
14651
  async function evaluate(config) {
14501
14652
  const startTime = Date.now();
14502
14653
  if (config.tests && config.specFile) {
@@ -14518,13 +14669,13 @@ async function evaluate(config) {
14518
14669
  let evalCases;
14519
14670
  let testFilePath;
14520
14671
  if (config.specFile) {
14521
- testFilePath = path38.resolve(config.specFile);
14672
+ testFilePath = path39.resolve(config.specFile);
14522
14673
  evalCases = await loadTests(testFilePath, repoRoot, {
14523
14674
  verbose: config.verbose,
14524
14675
  filter: config.filter
14525
14676
  });
14526
14677
  } else {
14527
- testFilePath = path38.join(process.cwd(), "__programmatic__.yaml");
14678
+ testFilePath = path39.join(process.cwd(), "__programmatic__.yaml");
14528
14679
  evalCases = (config.tests ?? []).map((test) => {
14529
14680
  const input = typeof test.input === "string" ? [{ role: "user", content: test.input }] : test.input;
14530
14681
  const question = typeof test.input === "string" ? test.input : test.input.find((m) => m.role === "user")?.content ?? "";
@@ -14610,10 +14761,10 @@ function computeSummary(results, durationMs) {
14610
14761
  var TARGET_FILE_CANDIDATES = [".agentv/targets.yaml", ".agentv/targets.yml"];
14611
14762
  async function discoverDefaultTarget(repoRoot) {
14612
14763
  const cwd = process.cwd();
14613
- const chain = buildDirectoryChain(path38.join(cwd, "_placeholder"), repoRoot);
14764
+ const chain = buildDirectoryChain(path39.join(cwd, "_placeholder"), repoRoot);
14614
14765
  for (const dir of chain) {
14615
14766
  for (const candidate of TARGET_FILE_CANDIDATES) {
14616
- const targetsPath = path38.join(dir, candidate);
14767
+ const targetsPath = path39.join(dir, candidate);
14617
14768
  if (!existsSync3(targetsPath)) continue;
14618
14769
  try {
14619
14770
  const definitions = await readTargetDefinitions(targetsPath);
@@ -14628,10 +14779,10 @@ async function discoverDefaultTarget(repoRoot) {
14628
14779
  async function loadEnvHierarchy(repoRoot) {
14629
14780
  const { readFileSync: readFileSync2 } = await import("node:fs");
14630
14781
  const cwd = process.cwd();
14631
- const chain = buildDirectoryChain(path38.join(cwd, "_placeholder"), repoRoot);
14782
+ const chain = buildDirectoryChain(path39.join(cwd, "_placeholder"), repoRoot);
14632
14783
  const envFiles = [];
14633
14784
  for (const dir of chain) {
14634
- const envPath = path38.join(dir, ".env");
14785
+ const envPath = path39.join(dir, ".env");
14635
14786
  if (existsSync3(envPath)) envFiles.push(envPath);
14636
14787
  }
14637
14788
  for (let i = envFiles.length - 1; i >= 0; i--) {
@@ -14813,7 +14964,7 @@ function buildPrompt(criteria, question, referenceAnswer) {
14813
14964
 
14814
14965
  // src/evaluation/cache/response-cache.ts
14815
14966
  import { mkdir as mkdir13, readFile as readFile11, writeFile as writeFile8 } from "node:fs/promises";
14816
- import path39 from "node:path";
14967
+ import path40 from "node:path";
14817
14968
  var DEFAULT_CACHE_PATH = ".agentv/cache";
14818
14969
  var ResponseCache = class {
14819
14970
  cachePath;
@@ -14831,13 +14982,13 @@ var ResponseCache = class {
14831
14982
  }
14832
14983
  async set(key, value) {
14833
14984
  const filePath = this.keyToPath(key);
14834
- const dir = path39.dirname(filePath);
14985
+ const dir = path40.dirname(filePath);
14835
14986
  await mkdir13(dir, { recursive: true });
14836
14987
  await writeFile8(filePath, JSON.stringify(value, null, 2), "utf8");
14837
14988
  }
14838
14989
  keyToPath(key) {
14839
14990
  const prefix = key.slice(0, 2);
14840
- return path39.join(this.cachePath, prefix, `${key}.json`);
14991
+ return path40.join(this.cachePath, prefix, `${key}.json`);
14841
14992
  }
14842
14993
  };
14843
14994
  function shouldEnableCache(params) {
@@ -15364,8 +15515,13 @@ export {
15364
15515
  findGitRoot,
15365
15516
  freeformEvaluationSchema,
15366
15517
  generateRubrics,
15518
+ getAgentvHome,
15519
+ getGitCacheRoot,
15367
15520
  getHitCount,
15521
+ getSubagentsRoot,
15522
+ getTraceStateRoot,
15368
15523
  getWorkspacePath,
15524
+ getWorkspacesRoot,
15369
15525
  initializeBaseline,
15370
15526
  isEvaluatorKind,
15371
15527
  isGuidelineFile,