@agentv/core 2.5.3 → 2.5.4

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.cjs CHANGED
@@ -3377,16 +3377,16 @@ async function runClaudeCodeWithTempFiles(options, stdoutFile, stderrFile, exitF
3377
3377
  let lastStdoutSize = 0;
3378
3378
  const readFileIfExists = async (filePath) => {
3379
3379
  try {
3380
- const { readFile: readFile9 } = await import("fs/promises");
3381
- return await readFile9(filePath, "utf8");
3380
+ const { readFile: readFile11 } = await import("fs/promises");
3381
+ return await readFile11(filePath, "utf8");
3382
3382
  } catch {
3383
3383
  return "";
3384
3384
  }
3385
3385
  };
3386
3386
  const fileExists4 = async (filePath) => {
3387
3387
  try {
3388
- const { access: access5 } = await import("fs/promises");
3389
- await access5(filePath);
3388
+ const { access: access6 } = await import("fs/promises");
3389
+ await access6(filePath);
3390
3390
  return true;
3391
3391
  } catch {
3392
3392
  return false;
@@ -6239,8 +6239,8 @@ function resolveCliConfig(target, env, evalFilePath) {
6239
6239
  const parseResult = CliTargetInputSchema.safeParse(target, { errorMap: cliErrorMap });
6240
6240
  if (!parseResult.success) {
6241
6241
  const firstError = parseResult.error.errors[0];
6242
- const path18 = firstError?.path.join(".") || "";
6243
- const prefix = path18 ? `${target.name} ${path18}: ` : `${target.name}: `;
6242
+ const path28 = firstError?.path.join(".") || "";
6243
+ const prefix = path28 ? `${target.name} ${path28}: ` : `${target.name}: `;
6244
6244
  throw new Error(`${prefix}${firstError?.message}`);
6245
6245
  }
6246
6246
  const normalized = normalizeCliTargetInput(parseResult.data, env, evalFilePath);
@@ -6427,9 +6427,1037 @@ function resolveOptionalNumberArray(source, description) {
6427
6427
  return resolved.length > 0 ? resolved : void 0;
6428
6428
  }
6429
6429
 
6430
- // src/evaluation/providers/vscode.ts
6430
+ // src/evaluation/providers/vscode-provider.ts
6431
+ var import_node_path25 = __toESM(require("path"), 1);
6432
+
6433
+ // src/evaluation/providers/vscode/dispatch/agentDispatch.ts
6434
+ var import_promises17 = require("fs/promises");
6435
+ var import_node_path23 = __toESM(require("path"), 1);
6436
+
6437
+ // src/evaluation/providers/vscode/utils/fs.ts
6438
+ var import_node_fs6 = require("fs");
6439
+ var import_promises13 = require("fs/promises");
6431
6440
  var import_node_path15 = __toESM(require("path"), 1);
6432
- var import_subagent = require("subagent");
6441
+ async function pathExists(target) {
6442
+ try {
6443
+ await (0, import_promises13.access)(target, import_node_fs6.constants.F_OK);
6444
+ return true;
6445
+ } catch {
6446
+ return false;
6447
+ }
6448
+ }
6449
+ async function ensureDir(target) {
6450
+ await (0, import_promises13.mkdir)(target, { recursive: true });
6451
+ }
6452
+ async function readDirEntries(target) {
6453
+ const entries = await (0, import_promises13.readdir)(target, { withFileTypes: true });
6454
+ return entries.map((entry) => ({
6455
+ name: entry.name,
6456
+ absolutePath: import_node_path15.default.join(target, entry.name),
6457
+ isDirectory: entry.isDirectory()
6458
+ }));
6459
+ }
6460
+ async function removeIfExists(target) {
6461
+ try {
6462
+ await (0, import_promises13.rm)(target, { force: true, recursive: false });
6463
+ } catch (error) {
6464
+ if (error.code !== "ENOENT") {
6465
+ throw error;
6466
+ }
6467
+ }
6468
+ }
6469
+
6470
+ // src/evaluation/providers/vscode/utils/path.ts
6471
+ var import_node_path16 = __toESM(require("path"), 1);
6472
+ function pathToFileUri2(filePath) {
6473
+ const absolutePath = import_node_path16.default.isAbsolute(filePath) ? filePath : import_node_path16.default.resolve(filePath);
6474
+ const normalizedPath = absolutePath.replace(/\\/g, "/");
6475
+ if (/^[a-zA-Z]:\//.test(normalizedPath)) {
6476
+ return `file:///${normalizedPath}`;
6477
+ }
6478
+ return `file://${normalizedPath}`;
6479
+ }
6480
+
6481
+ // src/evaluation/providers/vscode/dispatch/promptBuilder.ts
6482
+ var import_node_path17 = __toESM(require("path"), 1);
6483
+
6484
+ // src/evaluation/providers/vscode/utils/template.ts
6485
+ function renderTemplate2(content, variables) {
6486
+ if (!content) {
6487
+ return content;
6488
+ }
6489
+ const variableLookup = /* @__PURE__ */ new Map();
6490
+ for (const [key, value] of Object.entries(variables)) {
6491
+ variableLookup.set(key.toLowerCase(), value);
6492
+ }
6493
+ const referencedVariables = /* @__PURE__ */ new Set();
6494
+ const result = content.replace(/\{\{([a-zA-Z_]+)\}\}/gi, (match, variableName) => {
6495
+ const lowerCaseKey = variableName.toLowerCase();
6496
+ referencedVariables.add(lowerCaseKey);
6497
+ if (!variableLookup.has(lowerCaseKey)) {
6498
+ throw new Error(
6499
+ `Template variable '${variableName}' is not provided in the variables object`
6500
+ );
6501
+ }
6502
+ return variableLookup.get(lowerCaseKey);
6503
+ });
6504
+ return result;
6505
+ }
6506
+
6507
+ // src/evaluation/providers/vscode/dispatch/templates.ts
6508
+ var DEFAULT_REQUEST_TEMPLATE = `[[ ## task ## ]]
6509
+
6510
+ {{userQuery}}
6511
+
6512
+ [[ ## system_instructions ## ]]
6513
+
6514
+ **IMPORTANT**: Follow these exact steps:
6515
+ 1. Create and write your complete response to: {{responseFileTmp}}
6516
+ 2. When completely finished, run these PowerShell commands to signal completion:
6517
+ \`\`\`
6518
+ Move-Item -LiteralPath '{{responseFileTmp}}' -Destination '{{responseFileFinal}}'
6519
+ if (Test-Path subagent.lock) { del subagent.lock }
6520
+ \`\`\`
6521
+
6522
+ Do not proceed to step 2 until your response is completely written to the temporary file.
6523
+ `;
6524
+ var DEFAULT_BATCH_REQUEST_TEMPLATE = `[[ ## task ## ]]
6525
+
6526
+ {{userQuery}}
6527
+
6528
+ [[ ## system_instructions ## ]]
6529
+
6530
+ **IMPORTANT**: Follow these exact steps:
6531
+ 1. Create and write your complete response to: {{responseFileTmp}}
6532
+ 2. When completely finished and the response is stable, rename it to: {{responseFileFinal}}
6533
+ 3. Do not unlock the workspace from this request; batch orchestration will handle unlocking after all responses are ready.
6534
+ `;
6535
+ var DEFAULT_BATCH_ORCHESTRATOR_TEMPLATE = `MANDATORY: Run #runSubagent tool in your Available Actions for each request file to process them in isolated contexts.
6536
+ DO NOT read the request files yourself - only pass the file paths to each subagent:
6537
+
6538
+ {{requestFiles}}
6539
+
6540
+ After ALL queries complete, verify all responses exist and unlock:
6541
+
6542
+ \`\`\`powershell
6543
+ $responses = @({{responseList}})
6544
+ $missing = $responses | Where-Object { -not (Test-Path "messages/$_") }
6545
+ if ($missing.Count -eq 0) { del subagent.lock }
6546
+ \`\`\`
6547
+ `;
6548
+
6549
+ // src/evaluation/providers/vscode/dispatch/promptBuilder.ts
6550
+ function loadDefaultRequestTemplate() {
6551
+ return DEFAULT_REQUEST_TEMPLATE;
6552
+ }
6553
+ function loadDefaultBatchRequestTemplate() {
6554
+ return DEFAULT_BATCH_REQUEST_TEMPLATE;
6555
+ }
6556
+ function loadDefaultBatchOrchestratorTemplate() {
6557
+ return DEFAULT_BATCH_ORCHESTRATOR_TEMPLATE;
6558
+ }
6559
+ function createRequestPrompt(userQuery, responseFileTmp, responseFileFinal, templateContent) {
6560
+ return renderTemplate2(templateContent, {
6561
+ userQuery,
6562
+ responseFileTmp,
6563
+ responseFileFinal
6564
+ });
6565
+ }
6566
+ function createBatchRequestPrompt(userQuery, responseFileTmp, responseFileFinal, templateContent) {
6567
+ return renderTemplate2(templateContent, {
6568
+ userQuery,
6569
+ responseFileTmp,
6570
+ responseFileFinal
6571
+ });
6572
+ }
6573
+ function createBatchOrchestratorPrompt(requestFiles, responseFiles, templateContent) {
6574
+ const requestLines = requestFiles.map((file, index) => `${index + 1}. messages/${import_node_path17.default.basename(file)}`).join("\n");
6575
+ const responseList = responseFiles.map((file) => `"${import_node_path17.default.basename(file)}"`).join(", ");
6576
+ return renderTemplate2(templateContent, {
6577
+ requestFiles: requestLines,
6578
+ responseList
6579
+ });
6580
+ }
6581
+
6582
+ // src/evaluation/providers/vscode/dispatch/responseWaiter.ts
6583
+ var import_promises14 = require("fs/promises");
6584
+ var import_node_path18 = __toESM(require("path"), 1);
6585
+
6586
+ // src/evaluation/providers/vscode/utils/time.ts
6587
+ function sleep2(ms) {
6588
+ return new Promise((resolve) => {
6589
+ setTimeout(resolve, ms);
6590
+ });
6591
+ }
6592
+
6593
+ // src/evaluation/providers/vscode/dispatch/responseWaiter.ts
6594
+ async function waitForResponseOutput(responseFileFinal, pollInterval = 1e3, silent = false) {
6595
+ if (!silent) {
6596
+ console.error(`waiting for agent to finish: ${responseFileFinal}`);
6597
+ }
6598
+ try {
6599
+ while (!await pathExists(responseFileFinal)) {
6600
+ await sleep2(pollInterval);
6601
+ }
6602
+ } catch (error) {
6603
+ if (error.code === "ENOENT") {
6604
+ return false;
6605
+ }
6606
+ throw error;
6607
+ }
6608
+ let attempts = 0;
6609
+ const maxAttempts = 10;
6610
+ while (attempts < maxAttempts) {
6611
+ try {
6612
+ const content = await (0, import_promises14.readFile)(responseFileFinal, { encoding: "utf8" });
6613
+ if (!silent) {
6614
+ process.stdout.write(`${content}
6615
+ `);
6616
+ }
6617
+ return true;
6618
+ } catch (error) {
6619
+ attempts += 1;
6620
+ if (error.code !== "EBUSY" || attempts >= maxAttempts) {
6621
+ if (!silent) {
6622
+ console.error(`error: failed to read agent response: ${error.message}`);
6623
+ }
6624
+ return false;
6625
+ }
6626
+ await sleep2(pollInterval);
6627
+ }
6628
+ }
6629
+ return false;
6630
+ }
6631
+ async function waitForBatchResponses(responseFilesFinal, pollInterval = 1e3, silent = false) {
6632
+ if (!silent) {
6633
+ const fileList = responseFilesFinal.map((file) => import_node_path18.default.basename(file)).join(", ");
6634
+ console.error(`waiting for ${responseFilesFinal.length} batch response(s): ${fileList}`);
6635
+ }
6636
+ try {
6637
+ const pending = new Set(responseFilesFinal);
6638
+ while (pending.size > 0) {
6639
+ for (const file of [...pending]) {
6640
+ if (await pathExists(file)) {
6641
+ pending.delete(file);
6642
+ }
6643
+ }
6644
+ if (pending.size > 0) {
6645
+ await sleep2(pollInterval);
6646
+ }
6647
+ }
6648
+ } catch (error) {
6649
+ if (error.code === "ENOENT") {
6650
+ return false;
6651
+ }
6652
+ throw error;
6653
+ }
6654
+ for (const file of responseFilesFinal) {
6655
+ let attempts = 0;
6656
+ const maxAttempts = 10;
6657
+ while (attempts < maxAttempts) {
6658
+ try {
6659
+ const content = await (0, import_promises14.readFile)(file, { encoding: "utf8" });
6660
+ if (!silent) {
6661
+ process.stdout.write(`${content}
6662
+ `);
6663
+ }
6664
+ break;
6665
+ } catch (error) {
6666
+ attempts += 1;
6667
+ if (error.code !== "EBUSY" || attempts >= maxAttempts) {
6668
+ if (!silent) {
6669
+ console.error(`error: failed to read agent response: ${error.message}`);
6670
+ }
6671
+ return false;
6672
+ }
6673
+ await sleep2(pollInterval);
6674
+ }
6675
+ }
6676
+ }
6677
+ return true;
6678
+ }
6679
+
6680
+ // src/evaluation/providers/vscode/dispatch/vscodeProcess.ts
6681
+ var import_node_child_process5 = require("child_process");
6682
+ var import_promises15 = require("fs/promises");
6683
+ var import_node_path20 = __toESM(require("path"), 1);
6684
+ var import_node_util3 = require("util");
6685
+
6686
+ // src/evaluation/providers/vscode/dispatch/constants.ts
6687
+ var import_node_os5 = __toESM(require("os"), 1);
6688
+ var import_node_path19 = __toESM(require("path"), 1);
6689
+ var DEFAULT_LOCK_NAME = "subagent.lock";
6690
+ var DEFAULT_ALIVE_FILENAME = ".alive";
6691
+ function getDefaultSubagentRoot(vscodeCmd = "code") {
6692
+ const folder = vscodeCmd === "code-insiders" ? "vscode-insiders-agents" : "vscode-agents";
6693
+ return import_node_path19.default.join(import_node_os5.default.homedir(), ".agentv", "subagents", folder);
6694
+ }
6695
+ var DEFAULT_SUBAGENT_ROOT = getDefaultSubagentRoot();
6696
+
6697
+ // src/evaluation/providers/vscode/dispatch/vscodeProcess.ts
6698
+ var execAsync3 = (0, import_node_util3.promisify)(import_node_child_process5.exec);
6699
+ var DEFAULT_WAKEUP_CONTENT = `---
6700
+ description: 'Wake-up Signal'
6701
+ model: Grok Code Fast 1 (copilot)
6702
+ ---`;
6703
+ async function checkWorkspaceOpened(workspaceName, vscodeCmd) {
6704
+ try {
6705
+ const { stdout } = await execAsync3(`${vscodeCmd} --status`, {
6706
+ timeout: 1e4,
6707
+ windowsHide: true
6708
+ });
6709
+ return stdout.includes(workspaceName);
6710
+ } catch {
6711
+ return false;
6712
+ }
6713
+ }
6714
+ async function ensureWorkspaceFocused(workspacePath, workspaceName, subagentDir, vscodeCmd, pollInterval = 1, timeout = 60) {
6715
+ const alreadyOpen = await checkWorkspaceOpened(workspaceName, vscodeCmd);
6716
+ if (alreadyOpen) {
6717
+ (0, import_node_child_process5.spawn)(vscodeCmd, [workspacePath], { windowsHide: true, shell: true, detached: false });
6718
+ return true;
6719
+ }
6720
+ const aliveFile = import_node_path20.default.join(subagentDir, DEFAULT_ALIVE_FILENAME);
6721
+ await removeIfExists(aliveFile);
6722
+ const githubAgentsDir = import_node_path20.default.join(subagentDir, ".github", "agents");
6723
+ await (0, import_promises15.mkdir)(githubAgentsDir, { recursive: true });
6724
+ const wakeupDst = import_node_path20.default.join(githubAgentsDir, "wakeup.md");
6725
+ await (0, import_promises15.writeFile)(wakeupDst, DEFAULT_WAKEUP_CONTENT, "utf8");
6726
+ (0, import_node_child_process5.spawn)(vscodeCmd, [workspacePath], { windowsHide: true, shell: true, detached: false });
6727
+ await sleep2(100);
6728
+ const wakeupChatId = "wakeup";
6729
+ const chatArgs = [
6730
+ "-r",
6731
+ "chat",
6732
+ "-m",
6733
+ wakeupChatId,
6734
+ `create a file named .alive in the ${import_node_path20.default.basename(subagentDir)} folder`
6735
+ ];
6736
+ (0, import_node_child_process5.spawn)(vscodeCmd, chatArgs, { windowsHide: true, shell: true, detached: false });
6737
+ const start = Date.now();
6738
+ while (!await pathExists(aliveFile)) {
6739
+ if (Date.now() - start > timeout * 1e3) {
6740
+ console.error(`warning: Workspace readiness timeout after ${timeout}s`);
6741
+ return false;
6742
+ }
6743
+ await sleep2(pollInterval * 1e3);
6744
+ }
6745
+ return true;
6746
+ }
6747
+ async function launchVsCodeWithChat(subagentDir, chatId, attachmentPaths, requestInstructions, timestamp, vscodeCmd) {
6748
+ try {
6749
+ const workspacePath = import_node_path20.default.join(subagentDir, `${import_node_path20.default.basename(subagentDir)}.code-workspace`);
6750
+ const messagesDir = import_node_path20.default.join(subagentDir, "messages");
6751
+ await (0, import_promises15.mkdir)(messagesDir, { recursive: true });
6752
+ const reqFile = import_node_path20.default.join(messagesDir, `${timestamp}_req.md`);
6753
+ await (0, import_promises15.writeFile)(reqFile, requestInstructions, { encoding: "utf8" });
6754
+ const reqUri = pathToFileUri2(reqFile);
6755
+ const chatArgs = ["-r", "chat", "-m", chatId];
6756
+ for (const attachment of attachmentPaths) {
6757
+ chatArgs.push("-a", attachment);
6758
+ }
6759
+ chatArgs.push("-a", reqFile);
6760
+ chatArgs.push(`Follow instructions in [${import_node_path20.default.basename(reqFile)}](${reqUri})`);
6761
+ const workspaceReady = await ensureWorkspaceFocused(
6762
+ workspacePath,
6763
+ import_node_path20.default.basename(subagentDir),
6764
+ subagentDir,
6765
+ vscodeCmd
6766
+ );
6767
+ if (!workspaceReady) {
6768
+ console.error("warning: Workspace may not be fully ready");
6769
+ }
6770
+ await sleep2(500);
6771
+ (0, import_node_child_process5.spawn)(vscodeCmd, chatArgs, { windowsHide: true, shell: true, detached: false });
6772
+ return true;
6773
+ } catch (error) {
6774
+ console.error(`warning: Failed to launch VS Code: ${error.message}`);
6775
+ return false;
6776
+ }
6777
+ }
6778
+ async function launchVsCodeWithBatchChat(subagentDir, chatId, attachmentPaths, chatInstruction, vscodeCmd) {
6779
+ try {
6780
+ const workspacePath = import_node_path20.default.join(subagentDir, `${import_node_path20.default.basename(subagentDir)}.code-workspace`);
6781
+ const messagesDir = import_node_path20.default.join(subagentDir, "messages");
6782
+ await (0, import_promises15.mkdir)(messagesDir, { recursive: true });
6783
+ const chatArgs = ["-r", "chat", "-m", chatId];
6784
+ for (const attachment of attachmentPaths) {
6785
+ chatArgs.push("-a", attachment);
6786
+ }
6787
+ chatArgs.push(chatInstruction);
6788
+ const workspaceReady = await ensureWorkspaceFocused(
6789
+ workspacePath,
6790
+ import_node_path20.default.basename(subagentDir),
6791
+ subagentDir,
6792
+ vscodeCmd
6793
+ );
6794
+ if (!workspaceReady) {
6795
+ console.error("warning: Workspace may not be fully ready");
6796
+ }
6797
+ await sleep2(500);
6798
+ (0, import_node_child_process5.spawn)(vscodeCmd, chatArgs, { windowsHide: true, shell: true, detached: false });
6799
+ return true;
6800
+ } catch (error) {
6801
+ console.error(`warning: Failed to launch VS Code: ${error.message}`);
6802
+ return false;
6803
+ }
6804
+ }
6805
+
6806
+ // src/evaluation/providers/vscode/dispatch/workspaceManager.ts
6807
+ var import_promises16 = require("fs/promises");
6808
+ var import_node_path22 = __toESM(require("path"), 1);
6809
+
6810
+ // src/evaluation/providers/vscode/utils/workspace.ts
6811
+ var import_node_path21 = __toESM(require("path"), 1);
6812
+ var import_json5 = __toESM(require("json5"), 1);
6813
+ function transformWorkspacePaths(workspaceContent, templateDir) {
6814
+ let workspace;
6815
+ try {
6816
+ workspace = import_json5.default.parse(workspaceContent);
6817
+ } catch (error) {
6818
+ throw new Error(`Invalid workspace JSON: ${error.message}`);
6819
+ }
6820
+ if (!workspace.folders) {
6821
+ throw new Error("Workspace file must contain a 'folders' array");
6822
+ }
6823
+ if (!Array.isArray(workspace.folders)) {
6824
+ throw new Error("Workspace 'folders' must be an array");
6825
+ }
6826
+ const transformedFolders = workspace.folders.map((folder) => {
6827
+ const folderPath = folder.path;
6828
+ if (import_node_path21.default.isAbsolute(folderPath)) {
6829
+ return folder;
6830
+ }
6831
+ const absolutePath = import_node_path21.default.resolve(templateDir, folderPath);
6832
+ return {
6833
+ ...folder,
6834
+ path: absolutePath
6835
+ };
6836
+ });
6837
+ const updatedFolders = [{ path: "." }, ...transformedFolders];
6838
+ let transformedSettings = workspace.settings;
6839
+ if (workspace.settings) {
6840
+ transformedSettings = {
6841
+ ...workspace.settings
6842
+ };
6843
+ const chatSettingsKeys = [
6844
+ "chat.promptFilesLocations",
6845
+ "chat.instructionsFilesLocations",
6846
+ "chat.modeFilesLocations"
6847
+ ];
6848
+ for (const settingKey of chatSettingsKeys) {
6849
+ const locationMap = workspace.settings[settingKey];
6850
+ if (locationMap && typeof locationMap === "object") {
6851
+ const transformedMap = {};
6852
+ for (const [locationPath, value] of Object.entries(locationMap)) {
6853
+ const isAbsolute = import_node_path21.default.isAbsolute(locationPath);
6854
+ if (isAbsolute) {
6855
+ transformedMap[locationPath] = value;
6856
+ } else {
6857
+ const firstGlobIndex = locationPath.search(/[*]/);
6858
+ if (firstGlobIndex === -1) {
6859
+ const resolvedPath = import_node_path21.default.resolve(templateDir, locationPath).replace(/\\/g, "/");
6860
+ transformedMap[resolvedPath] = value;
6861
+ } else {
6862
+ const basePathEnd = locationPath.lastIndexOf("/", firstGlobIndex);
6863
+ const basePath = basePathEnd !== -1 ? locationPath.substring(0, basePathEnd) : ".";
6864
+ const patternPath = locationPath.substring(basePathEnd !== -1 ? basePathEnd : 0);
6865
+ const resolvedPath = (import_node_path21.default.resolve(templateDir, basePath) + patternPath).replace(
6866
+ /\\/g,
6867
+ "/"
6868
+ );
6869
+ transformedMap[resolvedPath] = value;
6870
+ }
6871
+ }
6872
+ }
6873
+ transformedSettings[settingKey] = transformedMap;
6874
+ }
6875
+ }
6876
+ }
6877
+ const transformedWorkspace = {
6878
+ ...workspace,
6879
+ folders: updatedFolders,
6880
+ settings: transformedSettings
6881
+ };
6882
+ return JSON.stringify(transformedWorkspace, null, 2);
6883
+ }
6884
+
6885
+ // src/evaluation/providers/vscode/dispatch/workspaceManager.ts
6886
+ var DEFAULT_WORKSPACE_TEMPLATE = {
6887
+ folders: [
6888
+ {
6889
+ path: "."
6890
+ }
6891
+ ]
6892
+ };
6893
+ function getSubagentRoot(vscodeCmd = "code") {
6894
+ return getDefaultSubagentRoot(vscodeCmd);
6895
+ }
6896
+ async function findUnlockedSubagent(subagentRoot) {
6897
+ if (!await pathExists(subagentRoot)) {
6898
+ return null;
6899
+ }
6900
+ const entries = await readDirEntries(subagentRoot);
6901
+ const subagents = entries.filter((entry) => entry.isDirectory && entry.name.startsWith("subagent-")).map((entry) => ({
6902
+ absolutePath: entry.absolutePath,
6903
+ number: Number.parseInt(entry.name.split("-")[1] ?? "", 10)
6904
+ })).filter((entry) => Number.isInteger(entry.number)).sort((a, b) => a.number - b.number);
6905
+ for (const subagent of subagents) {
6906
+ const lockFile = import_node_path22.default.join(subagent.absolutePath, DEFAULT_LOCK_NAME);
6907
+ if (!await pathExists(lockFile)) {
6908
+ return subagent.absolutePath;
6909
+ }
6910
+ }
6911
+ return null;
6912
+ }
6913
+ async function copyAgentConfig(subagentDir, workspaceTemplate) {
6914
+ let workspaceContent;
6915
+ if (workspaceTemplate) {
6916
+ const workspaceSrc = import_node_path22.default.resolve(workspaceTemplate);
6917
+ if (!await pathExists(workspaceSrc)) {
6918
+ throw new Error(`workspace template not found: ${workspaceSrc}`);
6919
+ }
6920
+ const stats = await (0, import_promises16.stat)(workspaceSrc);
6921
+ if (!stats.isFile()) {
6922
+ throw new Error(`workspace template must be a file, not a directory: ${workspaceSrc}`);
6923
+ }
6924
+ const templateText = await (0, import_promises16.readFile)(workspaceSrc, "utf8");
6925
+ workspaceContent = JSON.parse(templateText);
6926
+ } else {
6927
+ workspaceContent = DEFAULT_WORKSPACE_TEMPLATE;
6928
+ }
6929
+ const workspaceName = `${import_node_path22.default.basename(subagentDir)}.code-workspace`;
6930
+ const workspaceDst = import_node_path22.default.join(subagentDir, workspaceName);
6931
+ const templateDir = workspaceTemplate ? import_node_path22.default.dirname(import_node_path22.default.resolve(workspaceTemplate)) : subagentDir;
6932
+ const workspaceJson = JSON.stringify(workspaceContent, null, 2);
6933
+ const transformedContent = transformWorkspacePaths(workspaceJson, templateDir);
6934
+ await (0, import_promises16.writeFile)(workspaceDst, transformedContent, "utf8");
6935
+ const messagesDir = import_node_path22.default.join(subagentDir, "messages");
6936
+ await (0, import_promises16.mkdir)(messagesDir, { recursive: true });
6937
+ return { workspace: workspaceDst, messagesDir };
6938
+ }
6939
+ async function createSubagentLock(subagentDir) {
6940
+ const messagesDir = import_node_path22.default.join(subagentDir, "messages");
6941
+ if (await pathExists(messagesDir)) {
6942
+ const files = await (0, import_promises16.readdir)(messagesDir);
6943
+ await Promise.all(
6944
+ files.map(async (file) => {
6945
+ const target = import_node_path22.default.join(messagesDir, file);
6946
+ await removeIfExists(target);
6947
+ })
6948
+ );
6949
+ }
6950
+ const githubAgentsDir = import_node_path22.default.join(subagentDir, ".github", "agents");
6951
+ if (await pathExists(githubAgentsDir)) {
6952
+ const agentFiles = await (0, import_promises16.readdir)(githubAgentsDir);
6953
+ const preservedFiles = /* @__PURE__ */ new Set(["wakeup.md", "subagent.md"]);
6954
+ await Promise.all(
6955
+ agentFiles.filter((file) => file.endsWith(".md") && !preservedFiles.has(file)).map((file) => removeIfExists(import_node_path22.default.join(githubAgentsDir, file)))
6956
+ );
6957
+ }
6958
+ const lockFile = import_node_path22.default.join(subagentDir, DEFAULT_LOCK_NAME);
6959
+ await (0, import_promises16.writeFile)(lockFile, "", { encoding: "utf8" });
6960
+ return lockFile;
6961
+ }
6962
+ async function removeSubagentLock(subagentDir) {
6963
+ const lockFile = import_node_path22.default.join(subagentDir, DEFAULT_LOCK_NAME);
6964
+ await removeIfExists(lockFile);
6965
+ }
6966
+ async function prepareSubagentDirectory(subagentDir, promptFile, chatId, workspaceTemplate, dryRun) {
6967
+ if (dryRun) {
6968
+ return 0;
6969
+ }
6970
+ try {
6971
+ await copyAgentConfig(subagentDir, workspaceTemplate);
6972
+ } catch (error) {
6973
+ console.error(`error: ${error.message}`);
6974
+ return 1;
6975
+ }
6976
+ try {
6977
+ await createSubagentLock(subagentDir);
6978
+ } catch (error) {
6979
+ console.error(`error: Failed to create subagent lock: ${error.message}`);
6980
+ return 1;
6981
+ }
6982
+ if (promptFile) {
6983
+ const githubAgentsDir = import_node_path22.default.join(subagentDir, ".github", "agents");
6984
+ await (0, import_promises16.mkdir)(githubAgentsDir, { recursive: true });
6985
+ const agentFile = import_node_path22.default.join(githubAgentsDir, `${chatId}.md`);
6986
+ try {
6987
+ await (0, import_promises16.copyFile)(promptFile, agentFile);
6988
+ } catch (error) {
6989
+ console.error(`error: Failed to copy prompt file to agent mode: ${error.message}`);
6990
+ return 1;
6991
+ }
6992
+ }
6993
+ return 0;
6994
+ }
6995
+
6996
+ // src/evaluation/providers/vscode/dispatch/agentDispatch.ts
6997
+ function generateTimestamp() {
6998
+ return (/* @__PURE__ */ new Date()).toISOString().replace(/[-:TZ.]/g, "").slice(0, 14);
6999
+ }
7000
+ async function resolvePromptFile(promptFile) {
7001
+ if (!promptFile) {
7002
+ return void 0;
7003
+ }
7004
+ const resolvedPrompt = import_node_path23.default.resolve(promptFile);
7005
+ if (!await pathExists(resolvedPrompt)) {
7006
+ throw new Error(`Prompt file not found: ${resolvedPrompt}`);
7007
+ }
7008
+ const promptStats = await (0, import_promises17.stat)(resolvedPrompt);
7009
+ if (!promptStats.isFile()) {
7010
+ throw new Error(`Prompt file must be a file, not a directory: ${resolvedPrompt}`);
7011
+ }
7012
+ return resolvedPrompt;
7013
+ }
7014
+ async function resolveAttachments(extraAttachments) {
7015
+ if (!extraAttachments) {
7016
+ return [];
7017
+ }
7018
+ const resolved = [];
7019
+ for (const attachment of extraAttachments) {
7020
+ const resolvedPath = import_node_path23.default.resolve(attachment);
7021
+ if (!await pathExists(resolvedPath)) {
7022
+ throw new Error(`Attachment not found: ${resolvedPath}`);
7023
+ }
7024
+ resolved.push(resolvedPath);
7025
+ }
7026
+ return resolved;
7027
+ }
7028
+ async function dispatchAgentSession(options) {
7029
+ const {
7030
+ userQuery,
7031
+ promptFile,
7032
+ requestTemplate,
7033
+ extraAttachments,
7034
+ workspaceTemplate,
7035
+ dryRun = false,
7036
+ wait = true,
7037
+ vscodeCmd = "code",
7038
+ subagentRoot,
7039
+ silent = false
7040
+ } = options;
7041
+ try {
7042
+ let resolvedPrompt;
7043
+ try {
7044
+ resolvedPrompt = await resolvePromptFile(promptFile);
7045
+ } catch (error) {
7046
+ return {
7047
+ exitCode: 1,
7048
+ error: error.message
7049
+ };
7050
+ }
7051
+ const templateContent = requestTemplate ?? loadDefaultRequestTemplate();
7052
+ const subagentRootPath = subagentRoot ?? getSubagentRoot(vscodeCmd);
7053
+ const subagentDir = await findUnlockedSubagent(subagentRootPath);
7054
+ if (!subagentDir) {
7055
+ return {
7056
+ exitCode: 1,
7057
+ error: "No unlocked subagents available. Provision additional subagents with: subagent code provision --subagents <desired_total>"
7058
+ };
7059
+ }
7060
+ const subagentName = import_node_path23.default.basename(subagentDir);
7061
+ const chatId = Math.random().toString(16).slice(2, 10);
7062
+ const preparationResult = await prepareSubagentDirectory(
7063
+ subagentDir,
7064
+ resolvedPrompt,
7065
+ chatId,
7066
+ workspaceTemplate,
7067
+ dryRun
7068
+ );
7069
+ if (preparationResult !== 0) {
7070
+ return {
7071
+ exitCode: preparationResult,
7072
+ subagentName,
7073
+ error: "Failed to prepare subagent workspace"
7074
+ };
7075
+ }
7076
+ let attachments;
7077
+ try {
7078
+ attachments = await resolveAttachments(extraAttachments);
7079
+ } catch (attachmentError) {
7080
+ return {
7081
+ exitCode: 1,
7082
+ subagentName,
7083
+ error: attachmentError.message
7084
+ };
7085
+ }
7086
+ const timestamp = generateTimestamp();
7087
+ const messagesDir = import_node_path23.default.join(subagentDir, "messages");
7088
+ const responseFileTmp = import_node_path23.default.join(messagesDir, `${timestamp}_res.tmp.md`);
7089
+ const responseFileFinal = import_node_path23.default.join(messagesDir, `${timestamp}_res.md`);
7090
+ const requestInstructions = createRequestPrompt(
7091
+ userQuery,
7092
+ responseFileTmp,
7093
+ responseFileFinal,
7094
+ templateContent
7095
+ );
7096
+ if (dryRun) {
7097
+ return {
7098
+ exitCode: 0,
7099
+ subagentName,
7100
+ responseFile: responseFileFinal,
7101
+ tempFile: responseFileTmp
7102
+ };
7103
+ }
7104
+ const launchSuccess = await launchVsCodeWithChat(
7105
+ subagentDir,
7106
+ chatId,
7107
+ attachments,
7108
+ requestInstructions,
7109
+ timestamp,
7110
+ vscodeCmd
7111
+ );
7112
+ if (!launchSuccess) {
7113
+ return {
7114
+ exitCode: 1,
7115
+ subagentName,
7116
+ responseFile: responseFileFinal,
7117
+ tempFile: responseFileTmp,
7118
+ error: "Failed to launch VS Code for subagent session"
7119
+ };
7120
+ }
7121
+ if (!wait) {
7122
+ return {
7123
+ exitCode: 0,
7124
+ subagentName,
7125
+ responseFile: responseFileFinal,
7126
+ tempFile: responseFileTmp
7127
+ };
7128
+ }
7129
+ const received = await waitForResponseOutput(responseFileFinal, 1e3, silent);
7130
+ if (!received) {
7131
+ return {
7132
+ exitCode: 1,
7133
+ subagentName,
7134
+ responseFile: responseFileFinal,
7135
+ tempFile: responseFileTmp,
7136
+ error: "Timed out waiting for agent response"
7137
+ };
7138
+ }
7139
+ await removeSubagentLock(subagentDir);
7140
+ return {
7141
+ exitCode: 0,
7142
+ subagentName,
7143
+ responseFile: responseFileFinal,
7144
+ tempFile: responseFileTmp
7145
+ };
7146
+ } catch (error) {
7147
+ return {
7148
+ exitCode: 1,
7149
+ error: error.message
7150
+ };
7151
+ }
7152
+ }
7153
+ async function dispatchBatchAgent(options) {
7154
+ const {
7155
+ userQueries,
7156
+ promptFile,
7157
+ requestTemplate,
7158
+ extraAttachments,
7159
+ workspaceTemplate,
7160
+ dryRun = false,
7161
+ wait = false,
7162
+ vscodeCmd = "code",
7163
+ subagentRoot,
7164
+ silent = false
7165
+ } = options;
7166
+ if (!userQueries || userQueries.length === 0) {
7167
+ return {
7168
+ exitCode: 1,
7169
+ requestFiles: [],
7170
+ queryCount: 0,
7171
+ error: "At least one query is required for batch dispatch"
7172
+ };
7173
+ }
7174
+ const queryCount = userQueries.length;
7175
+ let requestFiles = [];
7176
+ let responseFilesFinal = [];
7177
+ let subagentName;
7178
+ try {
7179
+ let resolvedPrompt;
7180
+ try {
7181
+ resolvedPrompt = await resolvePromptFile(promptFile);
7182
+ } catch (error) {
7183
+ return {
7184
+ exitCode: 1,
7185
+ requestFiles,
7186
+ queryCount,
7187
+ error: error.message
7188
+ };
7189
+ }
7190
+ const batchRequestTemplateContent = requestTemplate ?? loadDefaultBatchRequestTemplate();
7191
+ const orchestratorTemplateContent = loadDefaultBatchOrchestratorTemplate();
7192
+ const subagentRootPath = subagentRoot ?? getSubagentRoot(vscodeCmd);
7193
+ const subagentDir = await findUnlockedSubagent(subagentRootPath);
7194
+ if (!subagentDir) {
7195
+ return {
7196
+ exitCode: 1,
7197
+ requestFiles,
7198
+ queryCount,
7199
+ error: "No unlocked subagents available. Provision additional subagents with: subagent code provision --subagents <desired_total>"
7200
+ };
7201
+ }
7202
+ subagentName = import_node_path23.default.basename(subagentDir);
7203
+ const chatId = Math.random().toString(16).slice(2, 10);
7204
+ const preparationResult = await prepareSubagentDirectory(
7205
+ subagentDir,
7206
+ resolvedPrompt,
7207
+ chatId,
7208
+ workspaceTemplate,
7209
+ dryRun
7210
+ );
7211
+ if (preparationResult !== 0) {
7212
+ return {
7213
+ exitCode: preparationResult,
7214
+ subagentName,
7215
+ requestFiles,
7216
+ queryCount,
7217
+ error: "Failed to prepare subagent workspace"
7218
+ };
7219
+ }
7220
+ let attachments;
7221
+ try {
7222
+ attachments = await resolveAttachments(extraAttachments);
7223
+ } catch (attachmentError) {
7224
+ return {
7225
+ exitCode: 1,
7226
+ subagentName,
7227
+ requestFiles,
7228
+ queryCount,
7229
+ error: attachmentError.message
7230
+ };
7231
+ }
7232
+ const timestamp = generateTimestamp();
7233
+ const messagesDir = import_node_path23.default.join(subagentDir, "messages");
7234
+ requestFiles = userQueries.map(
7235
+ (_, index) => import_node_path23.default.join(messagesDir, `${timestamp}_${index}_req.md`)
7236
+ );
7237
+ const responseTmpFiles = userQueries.map(
7238
+ (_, index) => import_node_path23.default.join(messagesDir, `${timestamp}_${index}_res.tmp.md`)
7239
+ );
7240
+ responseFilesFinal = userQueries.map(
7241
+ (_, index) => import_node_path23.default.join(messagesDir, `${timestamp}_${index}_res.md`)
7242
+ );
7243
+ const orchestratorFile = import_node_path23.default.join(messagesDir, `${timestamp}_orchestrator.md`);
7244
+ if (!dryRun) {
7245
+ await Promise.all(
7246
+ userQueries.map((query, index) => {
7247
+ const reqFile = requestFiles[index];
7248
+ const tmpFile = responseTmpFiles[index];
7249
+ const finalFile = responseFilesFinal[index];
7250
+ return (0, import_promises17.writeFile)(
7251
+ reqFile,
7252
+ createBatchRequestPrompt(query, tmpFile, finalFile, batchRequestTemplateContent),
7253
+ { encoding: "utf8" }
7254
+ );
7255
+ })
7256
+ );
7257
+ const orchestratorContent = createBatchOrchestratorPrompt(
7258
+ requestFiles,
7259
+ responseFilesFinal,
7260
+ orchestratorTemplateContent
7261
+ );
7262
+ await (0, import_promises17.writeFile)(orchestratorFile, orchestratorContent, { encoding: "utf8" });
7263
+ }
7264
+ const chatAttachments = [orchestratorFile, ...attachments];
7265
+ const orchestratorUri = pathToFileUri2(orchestratorFile);
7266
+ const chatInstruction = `Follow instructions in [${timestamp}_orchestrator.md](${orchestratorUri}). Use #runSubagent tool.`;
7267
+ if (dryRun) {
7268
+ return {
7269
+ exitCode: 0,
7270
+ subagentName,
7271
+ requestFiles,
7272
+ responseFiles: wait ? responseFilesFinal : void 0,
7273
+ queryCount
7274
+ };
7275
+ }
7276
+ const launchSuccess = await launchVsCodeWithBatchChat(
7277
+ subagentDir,
7278
+ chatId,
7279
+ chatAttachments,
7280
+ chatInstruction,
7281
+ vscodeCmd
7282
+ );
7283
+ if (!launchSuccess) {
7284
+ return {
7285
+ exitCode: 1,
7286
+ subagentName,
7287
+ requestFiles,
7288
+ queryCount,
7289
+ error: "Failed to launch VS Code for batch dispatch"
7290
+ };
7291
+ }
7292
+ if (!wait) {
7293
+ return {
7294
+ exitCode: 0,
7295
+ subagentName,
7296
+ requestFiles,
7297
+ queryCount
7298
+ };
7299
+ }
7300
+ const responsesCompleted = await waitForBatchResponses(responseFilesFinal, 1e3, silent);
7301
+ if (!responsesCompleted) {
7302
+ return {
7303
+ exitCode: 1,
7304
+ subagentName,
7305
+ requestFiles,
7306
+ responseFiles: responseFilesFinal,
7307
+ queryCount,
7308
+ error: "Timed out waiting for batch responses"
7309
+ };
7310
+ }
7311
+ await removeSubagentLock(subagentDir);
7312
+ return {
7313
+ exitCode: 0,
7314
+ subagentName,
7315
+ requestFiles,
7316
+ responseFiles: responseFilesFinal,
7317
+ queryCount
7318
+ };
7319
+ } catch (error) {
7320
+ return {
7321
+ exitCode: 1,
7322
+ subagentName,
7323
+ requestFiles,
7324
+ responseFiles: responseFilesFinal.length > 0 ? responseFilesFinal : void 0,
7325
+ queryCount,
7326
+ error: error.message
7327
+ };
7328
+ }
7329
+ }
7330
+
7331
+ // src/evaluation/providers/vscode/dispatch/provision.ts
7332
+ var import_promises18 = require("fs/promises");
7333
+ var import_node_path24 = __toESM(require("path"), 1);
7334
+ var DEFAULT_WORKSPACE_TEMPLATE2 = {
7335
+ folders: [
7336
+ {
7337
+ path: "."
7338
+ }
7339
+ ],
7340
+ settings: {
7341
+ "chat.modeFilesLocations": {
7342
+ ".github/agents/**/*.md": true
7343
+ }
7344
+ }
7345
+ };
7346
+ var DEFAULT_WAKEUP_CONTENT2 = `---
7347
+ description: 'Wake-up Signal'
7348
+ tools: ['edit', 'runNotebooks', 'search', 'new', 'runCommands', 'runTasks', 'usages', 'vscodeAPI', 'problems', 'changes', 'testFailure', 'openSimpleBrowser', 'fetch', 'githubRepo']
7349
+ model: GPT-4.1 (copilot)
7350
+ ---`;
7351
+ async function provisionSubagents(options) {
7352
+ const {
7353
+ targetRoot,
7354
+ subagents,
7355
+ lockName = DEFAULT_LOCK_NAME,
7356
+ force = false,
7357
+ dryRun = false,
7358
+ workspaceTemplate = DEFAULT_WORKSPACE_TEMPLATE2,
7359
+ wakeupContent = DEFAULT_WAKEUP_CONTENT2
7360
+ } = options;
7361
+ if (!Number.isInteger(subagents) || subagents < 1) {
7362
+ throw new Error("subagents must be a positive integer");
7363
+ }
7364
+ const targetPath = import_node_path24.default.resolve(targetRoot);
7365
+ if (!dryRun) {
7366
+ await ensureDir(targetPath);
7367
+ }
7368
+ let highestNumber = 0;
7369
+ const lockedSubagents = /* @__PURE__ */ new Set();
7370
+ const existingSubagents = [];
7371
+ if (await pathExists(targetPath)) {
7372
+ const entries = await readDirEntries(targetPath);
7373
+ for (const entry of entries) {
7374
+ if (!entry.isDirectory || !entry.name.startsWith("subagent-")) {
7375
+ continue;
7376
+ }
7377
+ const suffix = entry.name.split("-")[1];
7378
+ if (!suffix) continue;
7379
+ const parsed = Number.parseInt(suffix, 10);
7380
+ if (!Number.isInteger(parsed)) {
7381
+ continue;
7382
+ }
7383
+ highestNumber = Math.max(highestNumber, parsed);
7384
+ const lockFile = import_node_path24.default.join(entry.absolutePath, lockName);
7385
+ const locked = await pathExists(lockFile);
7386
+ if (locked) {
7387
+ lockedSubagents.add(entry.absolutePath);
7388
+ }
7389
+ existingSubagents.push({ number: parsed, absolutePath: entry.absolutePath });
7390
+ }
7391
+ existingSubagents.sort((a, b) => a.number - b.number);
7392
+ }
7393
+ const created = [];
7394
+ const skippedExisting = [];
7395
+ let subagentsProvisioned = 0;
7396
+ for (const subagent of existingSubagents) {
7397
+ if (subagentsProvisioned >= subagents) {
7398
+ break;
7399
+ }
7400
+ const subagentDir = subagent.absolutePath;
7401
+ const githubAgentsDir = import_node_path24.default.join(subagentDir, ".github", "agents");
7402
+ const lockFile = import_node_path24.default.join(subagentDir, lockName);
7403
+ const workspaceDst = import_node_path24.default.join(subagentDir, `${import_node_path24.default.basename(subagentDir)}.code-workspace`);
7404
+ const wakeupDst = import_node_path24.default.join(githubAgentsDir, "wakeup.md");
7405
+ const isLocked = await pathExists(lockFile);
7406
+ if (isLocked && !force) {
7407
+ continue;
7408
+ }
7409
+ if (isLocked && force) {
7410
+ if (!dryRun) {
7411
+ await removeIfExists(lockFile);
7412
+ await ensureDir(githubAgentsDir);
7413
+ await (0, import_promises18.writeFile)(workspaceDst, JSON.stringify(workspaceTemplate, null, 2), "utf8");
7414
+ await (0, import_promises18.writeFile)(wakeupDst, wakeupContent, "utf8");
7415
+ }
7416
+ created.push(subagentDir);
7417
+ lockedSubagents.delete(subagentDir);
7418
+ subagentsProvisioned += 1;
7419
+ continue;
7420
+ }
7421
+ if (!isLocked && force) {
7422
+ if (!dryRun) {
7423
+ await ensureDir(githubAgentsDir);
7424
+ await (0, import_promises18.writeFile)(workspaceDst, JSON.stringify(workspaceTemplate, null, 2), "utf8");
7425
+ await (0, import_promises18.writeFile)(wakeupDst, wakeupContent, "utf8");
7426
+ }
7427
+ created.push(subagentDir);
7428
+ subagentsProvisioned += 1;
7429
+ continue;
7430
+ }
7431
+ if (!dryRun && !await pathExists(workspaceDst)) {
7432
+ await ensureDir(githubAgentsDir);
7433
+ await (0, import_promises18.writeFile)(workspaceDst, JSON.stringify(workspaceTemplate, null, 2), "utf8");
7434
+ await (0, import_promises18.writeFile)(wakeupDst, wakeupContent, "utf8");
7435
+ }
7436
+ skippedExisting.push(subagentDir);
7437
+ subagentsProvisioned += 1;
7438
+ }
7439
+ let nextIndex = highestNumber;
7440
+ while (subagentsProvisioned < subagents) {
7441
+ nextIndex += 1;
7442
+ const subagentDir = import_node_path24.default.join(targetPath, `subagent-${nextIndex}`);
7443
+ const githubAgentsDir = import_node_path24.default.join(subagentDir, ".github", "agents");
7444
+ const workspaceDst = import_node_path24.default.join(subagentDir, `${import_node_path24.default.basename(subagentDir)}.code-workspace`);
7445
+ const wakeupDst = import_node_path24.default.join(githubAgentsDir, "wakeup.md");
7446
+ if (!dryRun) {
7447
+ await ensureDir(subagentDir);
7448
+ await ensureDir(githubAgentsDir);
7449
+ await (0, import_promises18.writeFile)(workspaceDst, JSON.stringify(workspaceTemplate, null, 2), "utf8");
7450
+ await (0, import_promises18.writeFile)(wakeupDst, wakeupContent, "utf8");
7451
+ }
7452
+ created.push(subagentDir);
7453
+ subagentsProvisioned += 1;
7454
+ }
7455
+ return {
7456
+ created,
7457
+ skippedExisting,
7458
+ skippedLocked: Array.from(lockedSubagents).sort()
7459
+ };
7460
+ }
6433
7461
 
6434
7462
  // src/evaluation/providers/vscode-templates.ts
6435
7463
  var AGENTV_REQUEST_TEMPLATE = `[[ ## task ## ]]
@@ -6466,7 +7494,7 @@ var AGENTV_BATCH_REQUEST_TEMPLATE = `[[ ## task ## ]]
6466
7494
  3. Do not unlock the workspace from this request; batch orchestration will handle unlocking after all responses are ready.
6467
7495
  `;
6468
7496
 
6469
- // src/evaluation/providers/vscode.ts
7497
+ // src/evaluation/providers/vscode-provider.ts
6470
7498
  var VSCodeProvider = class {
6471
7499
  id;
6472
7500
  kind;
@@ -6485,7 +7513,7 @@ var VSCodeProvider = class {
6485
7513
  }
6486
7514
  const inputFiles = normalizeAttachments(request.inputFiles);
6487
7515
  const promptContent = buildPromptDocument2(request, inputFiles, request.guideline_patterns);
6488
- const session = await (0, import_subagent.dispatchAgentSession)({
7516
+ const session = await dispatchAgentSession({
6489
7517
  userQuery: promptContent,
6490
7518
  extraAttachments: inputFiles,
6491
7519
  requestTemplate: AGENTV_REQUEST_TEMPLATE,
@@ -6532,7 +7560,7 @@ var VSCodeProvider = class {
6532
7560
  const userQueries = normalizedRequests.map(
6533
7561
  ({ request, inputFiles }) => buildPromptDocument2(request, inputFiles, request.guideline_patterns)
6534
7562
  );
6535
- const session = await (0, import_subagent.dispatchBatchAgent)({
7563
+ const session = await dispatchBatchAgent({
6536
7564
  userQueries,
6537
7565
  extraAttachments: combinedInputFiles,
6538
7566
  requestTemplate: AGENTV_BATCH_REQUEST_TEMPLATE,
@@ -6598,8 +7626,8 @@ function buildMandatoryPrereadBlock2(guidelineFiles, attachmentFiles) {
6598
7626
  return "";
6599
7627
  }
6600
7628
  const buildList = (files) => files.map((absolutePath) => {
6601
- const fileName = import_node_path15.default.basename(absolutePath);
6602
- const fileUri = pathToFileUri2(absolutePath);
7629
+ const fileName = import_node_path25.default.basename(absolutePath);
7630
+ const fileUri = pathToFileUri3(absolutePath);
6603
7631
  return `* [${fileName}](${fileUri})`;
6604
7632
  });
6605
7633
  const sections = [];
@@ -6623,8 +7651,8 @@ function collectGuidelineFiles2(attachments, guidelinePatterns) {
6623
7651
  }
6624
7652
  const unique = /* @__PURE__ */ new Map();
6625
7653
  for (const attachment of attachments) {
6626
- const absolutePath = import_node_path15.default.resolve(attachment);
6627
- const normalized = absolutePath.split(import_node_path15.default.sep).join("/");
7654
+ const absolutePath = import_node_path25.default.resolve(attachment);
7655
+ const normalized = absolutePath.split(import_node_path25.default.sep).join("/");
6628
7656
  if (isGuidelineFile(normalized, guidelinePatterns)) {
6629
7657
  if (!unique.has(absolutePath)) {
6630
7658
  unique.set(absolutePath, absolutePath);
@@ -6639,15 +7667,15 @@ function collectAttachmentFiles(attachments) {
6639
7667
  }
6640
7668
  const unique = /* @__PURE__ */ new Map();
6641
7669
  for (const attachment of attachments) {
6642
- const absolutePath = import_node_path15.default.resolve(attachment);
7670
+ const absolutePath = import_node_path25.default.resolve(attachment);
6643
7671
  if (!unique.has(absolutePath)) {
6644
7672
  unique.set(absolutePath, absolutePath);
6645
7673
  }
6646
7674
  }
6647
7675
  return Array.from(unique.values());
6648
7676
  }
6649
- function pathToFileUri2(filePath) {
6650
- const absolutePath = import_node_path15.default.isAbsolute(filePath) ? filePath : import_node_path15.default.resolve(filePath);
7677
+ function pathToFileUri3(filePath) {
7678
+ const absolutePath = import_node_path25.default.isAbsolute(filePath) ? filePath : import_node_path25.default.resolve(filePath);
6651
7679
  const normalizedPath = absolutePath.replace(/\\/g, "/");
6652
7680
  if (/^[a-zA-Z]:\//.test(normalizedPath)) {
6653
7681
  return `file:///${normalizedPath}`;
@@ -6660,7 +7688,7 @@ function normalizeAttachments(attachments) {
6660
7688
  }
6661
7689
  const deduped = /* @__PURE__ */ new Set();
6662
7690
  for (const attachment of attachments) {
6663
- deduped.add(import_node_path15.default.resolve(attachment));
7691
+ deduped.add(import_node_path25.default.resolve(attachment));
6664
7692
  }
6665
7693
  return Array.from(deduped);
6666
7694
  }
@@ -6669,7 +7697,7 @@ function mergeAttachments(all) {
6669
7697
  for (const list of all) {
6670
7698
  if (!list) continue;
6671
7699
  for (const inputFile of list) {
6672
- deduped.add(import_node_path15.default.resolve(inputFile));
7700
+ deduped.add(import_node_path25.default.resolve(inputFile));
6673
7701
  }
6674
7702
  }
6675
7703
  return deduped.size > 0 ? Array.from(deduped) : void 0;
@@ -6677,12 +7705,12 @@ function mergeAttachments(all) {
6677
7705
  async function ensureVSCodeSubagents(options) {
6678
7706
  const { kind, count, verbose = false } = options;
6679
7707
  const vscodeCmd = kind === "vscode-insiders" ? "code-insiders" : "code";
6680
- const subagentRoot = (0, import_subagent.getSubagentRoot)(vscodeCmd);
7708
+ const subagentRoot = getSubagentRoot(vscodeCmd);
6681
7709
  try {
6682
7710
  if (verbose) {
6683
7711
  console.log(`Provisioning ${count} subagent(s) via: subagent ${vscodeCmd} provision`);
6684
7712
  }
6685
- const result = await (0, import_subagent.provisionSubagents)({
7713
+ const result = await provisionSubagents({
6686
7714
  targetRoot: subagentRoot,
6687
7715
  subagents: count,
6688
7716
  dryRun: false
@@ -6716,9 +7744,9 @@ total unlocked subagents available: ${result.created.length + result.skippedExis
6716
7744
  }
6717
7745
 
6718
7746
  // src/evaluation/providers/targets-file.ts
6719
- var import_node_fs6 = require("fs");
6720
- var import_promises13 = require("fs/promises");
6721
- var import_node_path16 = __toESM(require("path"), 1);
7747
+ var import_node_fs7 = require("fs");
7748
+ var import_promises19 = require("fs/promises");
7749
+ var import_node_path26 = __toESM(require("path"), 1);
6722
7750
  var import_yaml4 = require("yaml");
6723
7751
  function isRecord(value) {
6724
7752
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -6748,18 +7776,18 @@ function assertTargetDefinition(value, index, filePath) {
6748
7776
  }
6749
7777
  async function fileExists3(filePath) {
6750
7778
  try {
6751
- await (0, import_promises13.access)(filePath, import_node_fs6.constants.F_OK);
7779
+ await (0, import_promises19.access)(filePath, import_node_fs7.constants.F_OK);
6752
7780
  return true;
6753
7781
  } catch {
6754
7782
  return false;
6755
7783
  }
6756
7784
  }
6757
7785
  async function readTargetDefinitions(filePath) {
6758
- const absolutePath = import_node_path16.default.resolve(filePath);
7786
+ const absolutePath = import_node_path26.default.resolve(filePath);
6759
7787
  if (!await fileExists3(absolutePath)) {
6760
7788
  throw new Error(`targets.yaml not found at ${absolutePath}`);
6761
7789
  }
6762
- const raw = await (0, import_promises13.readFile)(absolutePath, "utf8");
7790
+ const raw = await (0, import_promises19.readFile)(absolutePath, "utf8");
6763
7791
  const parsed = (0, import_yaml4.parse)(raw);
6764
7792
  if (!isRecord(parsed)) {
6765
7793
  throw new Error(`targets.yaml at ${absolutePath} must be a YAML object with a 'targets' field`);
@@ -6923,10 +7951,10 @@ async function execFileWithStdinBun(argv, stdinPayload, options) {
6923
7951
  }
6924
7952
  }
6925
7953
  async function execFileWithStdinNode(argv, stdinPayload, options) {
6926
- const { spawn: spawn4 } = await import("child_process");
7954
+ const { spawn: spawn5 } = await import("child_process");
6927
7955
  return new Promise((resolve, reject) => {
6928
7956
  const [cmd, ...args] = argv;
6929
- const child = spawn4(cmd, args, {
7957
+ const child = spawn5(cmd, args, {
6930
7958
  cwd: options.cwd,
6931
7959
  stdio: ["pipe", "pipe", "pipe"],
6932
7960
  // Merge additional env vars with process.env
@@ -6966,21 +7994,21 @@ async function execFileWithStdinNode(argv, stdinPayload, options) {
6966
7994
  });
6967
7995
  }
6968
7996
  async function execShellWithStdin(command, stdinPayload, options = {}) {
6969
- const { mkdir: mkdir4, readFile: readFile9, rm: rm4, writeFile: writeFile4 } = await import("fs/promises");
7997
+ const { mkdir: mkdir8, readFile: readFile11, rm: rm5, writeFile: writeFile8 } = await import("fs/promises");
6970
7998
  const { tmpdir: tmpdir4 } = await import("os");
6971
- const path18 = await import("path");
7999
+ const path28 = await import("path");
6972
8000
  const { randomUUID: randomUUID4 } = await import("crypto");
6973
- const dir = path18.join(tmpdir4(), `agentv-exec-${randomUUID4()}`);
6974
- await mkdir4(dir, { recursive: true });
6975
- const stdinPath = path18.join(dir, "stdin.txt");
6976
- const stdoutPath = path18.join(dir, "stdout.txt");
6977
- const stderrPath = path18.join(dir, "stderr.txt");
6978
- await writeFile4(stdinPath, stdinPayload, "utf8");
8001
+ const dir = path28.join(tmpdir4(), `agentv-exec-${randomUUID4()}`);
8002
+ await mkdir8(dir, { recursive: true });
8003
+ const stdinPath = path28.join(dir, "stdin.txt");
8004
+ const stdoutPath = path28.join(dir, "stdout.txt");
8005
+ const stderrPath = path28.join(dir, "stderr.txt");
8006
+ await writeFile8(stdinPath, stdinPayload, "utf8");
6979
8007
  const wrappedCommand = process.platform === "win32" ? `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}` : `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}`;
6980
- const { spawn: spawn4 } = await import("child_process");
8008
+ const { spawn: spawn5 } = await import("child_process");
6981
8009
  try {
6982
8010
  const exitCode = await new Promise((resolve, reject) => {
6983
- const child = spawn4(wrappedCommand, {
8011
+ const child = spawn5(wrappedCommand, {
6984
8012
  shell: true,
6985
8013
  cwd: options.cwd,
6986
8014
  stdio: ["ignore", "ignore", "ignore"],
@@ -7004,11 +8032,11 @@ async function execShellWithStdin(command, stdinPayload, options = {}) {
7004
8032
  resolve(code ?? 0);
7005
8033
  });
7006
8034
  });
7007
- const stdout = (await readFile9(stdoutPath, "utf8")).replace(/\r\n/g, "\n");
7008
- const stderr = (await readFile9(stderrPath, "utf8")).replace(/\r\n/g, "\n");
8035
+ const stdout = (await readFile11(stdoutPath, "utf8")).replace(/\r\n/g, "\n");
8036
+ const stderr = (await readFile11(stderrPath, "utf8")).replace(/\r\n/g, "\n");
7009
8037
  return { stdout, stderr, exitCode };
7010
8038
  } finally {
7011
- await rm4(dir, { recursive: true, force: true });
8039
+ await rm5(dir, { recursive: true, force: true });
7012
8040
  }
7013
8041
  }
7014
8042
 
@@ -7277,7 +8305,7 @@ var CodeEvaluator = class {
7277
8305
  outputMessages: context.outputMessages ?? null,
7278
8306
  guidelineFiles: context.evalCase.guideline_paths,
7279
8307
  inputFiles: context.evalCase.file_paths.filter(
7280
- (path18) => !context.evalCase.guideline_paths.includes(path18)
8308
+ (path28) => !context.evalCase.guideline_paths.includes(path28)
7281
8309
  ),
7282
8310
  inputMessages: context.evalCase.input_messages,
7283
8311
  traceSummary: context.traceSummary ?? null,
@@ -8224,115 +9252,115 @@ var FieldAccuracyEvaluator = class {
8224
9252
  * Evaluate a single field against the expected value.
8225
9253
  */
8226
9254
  evaluateField(fieldConfig, candidateData, expectedData) {
8227
- const { path: path18, match, required = true, weight = 1 } = fieldConfig;
8228
- const candidateValue = resolvePath(candidateData, path18);
8229
- const expectedValue = resolvePath(expectedData, path18);
9255
+ const { path: path28, match, required = true, weight = 1 } = fieldConfig;
9256
+ const candidateValue = resolvePath(candidateData, path28);
9257
+ const expectedValue = resolvePath(expectedData, path28);
8230
9258
  if (expectedValue === void 0) {
8231
9259
  return {
8232
- path: path18,
9260
+ path: path28,
8233
9261
  score: 1,
8234
9262
  // No expected value means no comparison needed
8235
9263
  weight,
8236
9264
  hit: true,
8237
- message: `${path18}: no expected value`
9265
+ message: `${path28}: no expected value`
8238
9266
  };
8239
9267
  }
8240
9268
  if (candidateValue === void 0) {
8241
9269
  if (required) {
8242
9270
  return {
8243
- path: path18,
9271
+ path: path28,
8244
9272
  score: 0,
8245
9273
  weight,
8246
9274
  hit: false,
8247
- message: `${path18} (required, missing)`
9275
+ message: `${path28} (required, missing)`
8248
9276
  };
8249
9277
  }
8250
9278
  return {
8251
- path: path18,
9279
+ path: path28,
8252
9280
  score: 1,
8253
9281
  // Don't penalize missing optional fields
8254
9282
  weight: 0,
8255
9283
  // Zero weight means it won't affect the score
8256
9284
  hit: true,
8257
- message: `${path18}: optional field missing`
9285
+ message: `${path28}: optional field missing`
8258
9286
  };
8259
9287
  }
8260
9288
  switch (match) {
8261
9289
  case "exact":
8262
- return this.compareExact(path18, candidateValue, expectedValue, weight);
9290
+ return this.compareExact(path28, candidateValue, expectedValue, weight);
8263
9291
  case "numeric_tolerance":
8264
9292
  return this.compareNumericTolerance(
8265
- path18,
9293
+ path28,
8266
9294
  candidateValue,
8267
9295
  expectedValue,
8268
9296
  fieldConfig,
8269
9297
  weight
8270
9298
  );
8271
9299
  case "date":
8272
- return this.compareDate(path18, candidateValue, expectedValue, fieldConfig, weight);
9300
+ return this.compareDate(path28, candidateValue, expectedValue, fieldConfig, weight);
8273
9301
  default:
8274
9302
  return {
8275
- path: path18,
9303
+ path: path28,
8276
9304
  score: 0,
8277
9305
  weight,
8278
9306
  hit: false,
8279
- message: `${path18}: unknown match type "${match}"`
9307
+ message: `${path28}: unknown match type "${match}"`
8280
9308
  };
8281
9309
  }
8282
9310
  }
8283
9311
  /**
8284
9312
  * Exact equality comparison.
8285
9313
  */
8286
- compareExact(path18, candidateValue, expectedValue, weight) {
9314
+ compareExact(path28, candidateValue, expectedValue, weight) {
8287
9315
  if (deepEqual(candidateValue, expectedValue)) {
8288
9316
  return {
8289
- path: path18,
9317
+ path: path28,
8290
9318
  score: 1,
8291
9319
  weight,
8292
9320
  hit: true,
8293
- message: path18
9321
+ message: path28
8294
9322
  };
8295
9323
  }
8296
9324
  if (typeof candidateValue !== typeof expectedValue) {
8297
9325
  return {
8298
- path: path18,
9326
+ path: path28,
8299
9327
  score: 0,
8300
9328
  weight,
8301
9329
  hit: false,
8302
- message: `${path18} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
9330
+ message: `${path28} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
8303
9331
  };
8304
9332
  }
8305
9333
  return {
8306
- path: path18,
9334
+ path: path28,
8307
9335
  score: 0,
8308
9336
  weight,
8309
9337
  hit: false,
8310
- message: `${path18} (value mismatch)`
9338
+ message: `${path28} (value mismatch)`
8311
9339
  };
8312
9340
  }
8313
9341
  /**
8314
9342
  * Numeric comparison with absolute or relative tolerance.
8315
9343
  */
8316
- compareNumericTolerance(path18, candidateValue, expectedValue, fieldConfig, weight) {
9344
+ compareNumericTolerance(path28, candidateValue, expectedValue, fieldConfig, weight) {
8317
9345
  const { tolerance = 0, relative = false } = fieldConfig;
8318
9346
  const candidateNum = toNumber(candidateValue);
8319
9347
  const expectedNum = toNumber(expectedValue);
8320
9348
  if (candidateNum === null || expectedNum === null) {
8321
9349
  return {
8322
- path: path18,
9350
+ path: path28,
8323
9351
  score: 0,
8324
9352
  weight,
8325
9353
  hit: false,
8326
- message: `${path18} (non-numeric value)`
9354
+ message: `${path28} (non-numeric value)`
8327
9355
  };
8328
9356
  }
8329
9357
  if (!Number.isFinite(candidateNum) || !Number.isFinite(expectedNum)) {
8330
9358
  return {
8331
- path: path18,
9359
+ path: path28,
8332
9360
  score: 0,
8333
9361
  weight,
8334
9362
  hit: false,
8335
- message: `${path18} (invalid numeric value)`
9363
+ message: `${path28} (invalid numeric value)`
8336
9364
  };
8337
9365
  }
8338
9366
  const diff = Math.abs(candidateNum - expectedNum);
@@ -8345,61 +9373,61 @@ var FieldAccuracyEvaluator = class {
8345
9373
  }
8346
9374
  if (withinTolerance) {
8347
9375
  return {
8348
- path: path18,
9376
+ path: path28,
8349
9377
  score: 1,
8350
9378
  weight,
8351
9379
  hit: true,
8352
- message: `${path18} (within tolerance: diff=${diff.toFixed(2)})`
9380
+ message: `${path28} (within tolerance: diff=${diff.toFixed(2)})`
8353
9381
  };
8354
9382
  }
8355
9383
  return {
8356
- path: path18,
9384
+ path: path28,
8357
9385
  score: 0,
8358
9386
  weight,
8359
9387
  hit: false,
8360
- message: `${path18} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
9388
+ message: `${path28} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
8361
9389
  };
8362
9390
  }
8363
9391
  /**
8364
9392
  * Date comparison with format normalization.
8365
9393
  */
8366
- compareDate(path18, candidateValue, expectedValue, fieldConfig, weight) {
9394
+ compareDate(path28, candidateValue, expectedValue, fieldConfig, weight) {
8367
9395
  const formats = fieldConfig.formats ?? DEFAULT_DATE_FORMATS;
8368
9396
  const candidateDate = parseDate(String(candidateValue), formats);
8369
9397
  const expectedDate = parseDate(String(expectedValue), formats);
8370
9398
  if (candidateDate === null) {
8371
9399
  return {
8372
- path: path18,
9400
+ path: path28,
8373
9401
  score: 0,
8374
9402
  weight,
8375
9403
  hit: false,
8376
- message: `${path18} (unparseable candidate date)`
9404
+ message: `${path28} (unparseable candidate date)`
8377
9405
  };
8378
9406
  }
8379
9407
  if (expectedDate === null) {
8380
9408
  return {
8381
- path: path18,
9409
+ path: path28,
8382
9410
  score: 0,
8383
9411
  weight,
8384
9412
  hit: false,
8385
- message: `${path18} (unparseable expected date)`
9413
+ message: `${path28} (unparseable expected date)`
8386
9414
  };
8387
9415
  }
8388
9416
  if (candidateDate.getFullYear() === expectedDate.getFullYear() && candidateDate.getMonth() === expectedDate.getMonth() && candidateDate.getDate() === expectedDate.getDate()) {
8389
9417
  return {
8390
- path: path18,
9418
+ path: path28,
8391
9419
  score: 1,
8392
9420
  weight,
8393
9421
  hit: true,
8394
- message: path18
9422
+ message: path28
8395
9423
  };
8396
9424
  }
8397
9425
  return {
8398
- path: path18,
9426
+ path: path28,
8399
9427
  score: 0,
8400
9428
  weight,
8401
9429
  hit: false,
8402
- message: `${path18} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
9430
+ message: `${path28} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
8403
9431
  };
8404
9432
  }
8405
9433
  /**
@@ -8439,11 +9467,11 @@ var FieldAccuracyEvaluator = class {
8439
9467
  };
8440
9468
  }
8441
9469
  };
8442
- function resolvePath(obj, path18) {
8443
- if (!path18 || !obj) {
9470
+ function resolvePath(obj, path28) {
9471
+ if (!path28 || !obj) {
8444
9472
  return void 0;
8445
9473
  }
8446
- const parts = path18.split(/\.|\[|\]/).filter((p) => p.length > 0);
9474
+ const parts = path28.split(/\.|\[|\]/).filter((p) => p.length > 0);
8447
9475
  let current = obj;
8448
9476
  for (const part of parts) {
8449
9477
  if (current === null || current === void 0) {
@@ -8963,7 +9991,7 @@ var ToolTrajectoryEvaluator = class {
8963
9991
 
8964
9992
  // src/evaluation/orchestrator.ts
8965
9993
  var import_node_crypto5 = require("crypto");
8966
- var import_node_path17 = __toESM(require("path"), 1);
9994
+ var import_node_path27 = __toESM(require("path"), 1);
8967
9995
  var import_micromatch4 = __toESM(require("micromatch"), 1);
8968
9996
 
8969
9997
  // ../../node_modules/.bun/yocto-queue@1.2.2/node_modules/yocto-queue/index.js
@@ -9766,7 +10794,7 @@ async function runEvaluatorList(options) {
9766
10794
  });
9767
10795
  }
9768
10796
  if (evaluator.type === "composite") {
9769
- const evalFileDir = evalCase.guideline_paths[0] ? import_node_path17.default.dirname(evalCase.guideline_paths[0]) : process.cwd();
10797
+ const evalFileDir = evalCase.guideline_paths[0] ? import_node_path27.default.dirname(evalCase.guideline_paths[0]) : process.cwd();
9770
10798
  const createEvaluator = (memberConfig) => {
9771
10799
  switch (memberConfig.type) {
9772
10800
  case "llm_judge":
@@ -10122,7 +11150,7 @@ async function executePromptTemplate(script, context, config, timeoutMs) {
10122
11150
  };
10123
11151
  const inputJson = JSON.stringify(toSnakeCaseDeep(payload), null, 2);
10124
11152
  const scriptPath = script[script.length - 1];
10125
- const cwd = import_node_path17.default.dirname(scriptPath);
11153
+ const cwd = import_node_path27.default.dirname(scriptPath);
10126
11154
  try {
10127
11155
  const stdout = await executeScript(script, inputJson, timeoutMs, cwd);
10128
11156
  const prompt = stdout.trim();