agentv 2.14.3 → 2.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,7 +11,7 @@ import {
11
11
  validateEvalFile,
12
12
  validateFileReferences,
13
13
  validateTargetsFile
14
- } from "./chunk-MDAFSKDI.js";
14
+ } from "./chunk-ZDSLKUCM.js";
15
15
  import {
16
16
  RepoManager,
17
17
  assembleLlmJudgePrompt,
@@ -22,13 +22,14 @@ import {
22
22
  generateRubrics,
23
23
  getAgentvHome,
24
24
  getGitCacheRoot,
25
+ getWorkspacePoolRoot,
25
26
  loadTestById,
26
27
  loadTests,
27
28
  normalizeLineEndings,
28
29
  toCamelCaseDeep,
29
30
  toSnakeCaseDeep,
30
31
  trimBaselineResult
31
- } from "./chunk-TK4PB62M.js";
32
+ } from "./chunk-VBK7BJLE.js";
32
33
  import {
33
34
  __commonJS,
34
35
  __esm,
@@ -4050,6 +4051,15 @@ var evalRunCommand = command({
4050
4051
  long: "cleanup-workspaces",
4051
4052
  description: "Always cleanup temporary workspaces, even on failure"
4052
4053
  }),
4054
+ poolWorkspaces: flag({
4055
+ long: "pool-workspaces",
4056
+ description: "Reuse materialized workspaces across eval runs"
4057
+ }),
4058
+ workspace: option({
4059
+ type: optional(string),
4060
+ long: "workspace",
4061
+ description: "Use an existing directory as the workspace directly (skips clone/copy/pool)"
4062
+ }),
4053
4063
  otelFile: option({
4054
4064
  type: optional(string),
4055
4065
  long: "otel-file",
@@ -4089,7 +4099,7 @@ var evalRunCommand = command({
4089
4099
  },
4090
4100
  handler: async (args) => {
4091
4101
  if (args.evalPaths.length === 0 && process.stdin.isTTY) {
4092
- const { launchInteractiveWizard } = await import("./interactive-SQSP4PL3.js");
4102
+ const { launchInteractiveWizard } = await import("./interactive-SSGXAAKA.js");
4093
4103
  await launchInteractiveWizard();
4094
4104
  return;
4095
4105
  }
@@ -4113,6 +4123,8 @@ var evalRunCommand = command({
4113
4123
  verbose: args.verbose,
4114
4124
  keepWorkspaces: args.keepWorkspaces,
4115
4125
  cleanupWorkspaces: args.cleanupWorkspaces,
4126
+ poolWorkspaces: args.poolWorkspaces,
4127
+ workspace: args.workspace,
4116
4128
  trace: false,
4117
4129
  otelFile: args.otelFile,
4118
4130
  traceFile: args.traceFile,
@@ -4335,9 +4347,9 @@ function readTemplatesRecursively(dir, relativePath) {
4335
4347
  const entries2 = readdirSync(dir);
4336
4348
  for (const entry of entries2) {
4337
4349
  const fullPath = path4.join(dir, entry);
4338
- const stat2 = statSync(fullPath);
4350
+ const stat3 = statSync(fullPath);
4339
4351
  const entryRelativePath = relativePath ? path4.join(relativePath, entry) : entry;
4340
- if (stat2.isDirectory()) {
4352
+ if (stat3.isDirectory()) {
4341
4353
  templates.push(...readTemplatesRecursively(fullPath, entryRelativePath));
4342
4354
  } else {
4343
4355
  const content = readFileSync3(fullPath, "utf-8");
@@ -4600,7 +4612,7 @@ function listResultFiles(cwd, limit) {
4600
4612
  for (const filename of files) {
4601
4613
  const filePath = path6.join(resultsDir, filename);
4602
4614
  try {
4603
- const stat2 = statSync2(filePath);
4615
+ const stat3 = statSync2(filePath);
4604
4616
  const results = loadResultFile(filePath);
4605
4617
  const testCount = results.length;
4606
4618
  const passCount = results.filter((r) => r.score >= 1).length;
@@ -4615,7 +4627,7 @@ function listResultFiles(cwd, limit) {
4615
4627
  testCount,
4616
4628
  passRate,
4617
4629
  avgScore,
4618
- sizeBytes: stat2.size
4630
+ sizeBytes: stat3.size
4619
4631
  });
4620
4632
  } catch {
4621
4633
  }
@@ -5645,18 +5657,192 @@ var validateCommand = command({
5645
5657
  }
5646
5658
  });
5647
5659
 
5660
+ // src/commands/workspace/clean.ts
5661
+ import { existsSync as existsSync3 } from "node:fs";
5662
+ import { readFile as readFile3, readdir as readdir2, rm } from "node:fs/promises";
5663
+ import path8 from "node:path";
5664
+ async function confirm(message) {
5665
+ const readline2 = await import("node:readline");
5666
+ const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
5667
+ const answer = await new Promise((resolve2) => {
5668
+ rl.question(`${message} [y/N] `, resolve2);
5669
+ });
5670
+ rl.close();
5671
+ return answer.toLowerCase() === "y";
5672
+ }
5673
+ var cleanCommand2 = command({
5674
+ name: "clean",
5675
+ description: "Remove workspace pool entries",
5676
+ args: {
5677
+ repo: option({
5678
+ type: optional(string),
5679
+ long: "repo",
5680
+ description: "Only remove pools containing this repo URL"
5681
+ }),
5682
+ force: flag({
5683
+ long: "force",
5684
+ short: "f",
5685
+ description: "Skip confirmation prompt"
5686
+ })
5687
+ },
5688
+ handler: async ({ repo, force }) => {
5689
+ const poolRoot = getWorkspacePoolRoot();
5690
+ if (!existsSync3(poolRoot)) {
5691
+ console.log("No workspace pool entries found.");
5692
+ return;
5693
+ }
5694
+ if (repo) {
5695
+ const entries2 = await readdir2(poolRoot, { withFileTypes: true });
5696
+ const poolDirs = entries2.filter((e) => e.isDirectory());
5697
+ const matchingDirs = [];
5698
+ for (const dir of poolDirs) {
5699
+ const poolDir = path8.join(poolRoot, dir.name);
5700
+ const metadataPath = path8.join(poolDir, "metadata.json");
5701
+ try {
5702
+ const raw = await readFile3(metadataPath, "utf-8");
5703
+ const metadata = JSON.parse(raw);
5704
+ const hasRepo = metadata.repos?.some((r) => {
5705
+ if (r.source.type === "git" && r.source.url) {
5706
+ return r.source.url.toLowerCase().includes(repo.toLowerCase());
5707
+ }
5708
+ return false;
5709
+ });
5710
+ if (hasRepo) {
5711
+ matchingDirs.push(poolDir);
5712
+ }
5713
+ } catch {
5714
+ }
5715
+ }
5716
+ if (matchingDirs.length === 0) {
5717
+ console.log(`No workspace pool entries found matching repo "${repo}".`);
5718
+ return;
5719
+ }
5720
+ if (!force) {
5721
+ const confirmed = await confirm(
5722
+ `Remove ${matchingDirs.length} pool entry(s) matching repo "${repo}"?`
5723
+ );
5724
+ if (!confirmed) {
5725
+ console.log("Cancelled.");
5726
+ return;
5727
+ }
5728
+ }
5729
+ for (const dir of matchingDirs) {
5730
+ await rm(dir, { recursive: true, force: true });
5731
+ console.log(`Removed: ${path8.basename(dir).slice(0, 12)}...`);
5732
+ }
5733
+ console.log("Done.");
5734
+ } else {
5735
+ if (!force) {
5736
+ const confirmed = await confirm(`Remove all workspace pool entries from ${poolRoot}?`);
5737
+ if (!confirmed) {
5738
+ console.log("Cancelled.");
5739
+ return;
5740
+ }
5741
+ }
5742
+ await rm(poolRoot, { recursive: true, force: true });
5743
+ console.log("Workspace pool cleaned.");
5744
+ }
5745
+ }
5746
+ });
5747
+
5748
+ // src/commands/workspace/list.ts
5749
+ import { existsSync as existsSync4 } from "node:fs";
5750
+ import { readFile as readFile4, readdir as readdir3, stat as stat2 } from "node:fs/promises";
5751
+ import path9 from "node:path";
5752
+ async function getDirectorySize(dirPath) {
5753
+ let totalSize = 0;
5754
+ try {
5755
+ const entries2 = await readdir3(dirPath, { withFileTypes: true });
5756
+ for (const entry of entries2) {
5757
+ const fullPath = path9.join(dirPath, entry.name);
5758
+ if (entry.isDirectory()) {
5759
+ totalSize += await getDirectorySize(fullPath);
5760
+ } else {
5761
+ const stats = await stat2(fullPath);
5762
+ totalSize += stats.size;
5763
+ }
5764
+ }
5765
+ } catch {
5766
+ }
5767
+ return totalSize;
5768
+ }
5769
+ function formatSize2(bytes) {
5770
+ if (bytes < 1024) return `${bytes} B`;
5771
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
5772
+ if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
5773
+ return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
5774
+ }
5775
+ var listCommand = command({
5776
+ name: "list",
5777
+ description: "List workspace pool entries",
5778
+ args: {},
5779
+ handler: async () => {
5780
+ const poolRoot = getWorkspacePoolRoot();
5781
+ if (!existsSync4(poolRoot)) {
5782
+ console.log("No workspace pool entries found.");
5783
+ return;
5784
+ }
5785
+ const entries2 = await readdir3(poolRoot, { withFileTypes: true });
5786
+ const poolDirs = entries2.filter((e) => e.isDirectory());
5787
+ if (poolDirs.length === 0) {
5788
+ console.log("No workspace pool entries found.");
5789
+ return;
5790
+ }
5791
+ for (const dir of poolDirs) {
5792
+ const poolDir = path9.join(poolRoot, dir.name);
5793
+ const fingerprint = dir.name;
5794
+ const poolEntries = await readdir3(poolDir, { withFileTypes: true });
5795
+ const slots = poolEntries.filter((e) => e.isDirectory() && e.name.startsWith("slot-"));
5796
+ const metadataPath = path9.join(poolDir, "metadata.json");
5797
+ let metadata = null;
5798
+ try {
5799
+ const raw = await readFile4(metadataPath, "utf-8");
5800
+ metadata = JSON.parse(raw);
5801
+ } catch {
5802
+ }
5803
+ const size = await getDirectorySize(poolDir);
5804
+ console.log(` ${fingerprint.slice(0, 12)}...`);
5805
+ console.log(` Slots: ${slots.length}`);
5806
+ console.log(` Size: ${formatSize2(size)}`);
5807
+ if (metadata) {
5808
+ if (metadata.templatePath) {
5809
+ console.log(` Template: ${metadata.templatePath}`);
5810
+ }
5811
+ if (metadata.repos && metadata.repos.length > 0) {
5812
+ const repoSources = metadata.repos.map(
5813
+ (r) => r.source.type === "git" ? r.source.url : r.source.path
5814
+ );
5815
+ console.log(` Repos: ${repoSources.join(", ")}`);
5816
+ }
5817
+ console.log(` Created: ${metadata.createdAt}`);
5818
+ }
5819
+ console.log();
5820
+ }
5821
+ }
5822
+ });
5823
+
5824
+ // src/commands/workspace/index.ts
5825
+ var workspaceCommand = subcommands({
5826
+ name: "workspace",
5827
+ description: "Manage workspace pool",
5828
+ cmds: {
5829
+ list: listCommand,
5830
+ clean: cleanCommand2
5831
+ }
5832
+ });
5833
+
5648
5834
  // src/update-check.ts
5649
5835
  import { spawn as spawn2 } from "node:child_process";
5650
- import { readFile as readFile3 } from "node:fs/promises";
5836
+ import { readFile as readFile5 } from "node:fs/promises";
5651
5837
  import { join as join2 } from "node:path";
5652
5838
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
5653
5839
  var AGENTV_DIR = getAgentvHome();
5654
5840
  var CACHE_FILE = "version-check.json";
5655
5841
  var NPM_REGISTRY_URL = "https://registry.npmjs.org/agentv/latest";
5656
- async function getCachedUpdateInfo(path8) {
5657
- const filePath = path8 ?? join2(AGENTV_DIR, CACHE_FILE);
5842
+ async function getCachedUpdateInfo(path10) {
5843
+ const filePath = path10 ?? join2(AGENTV_DIR, CACHE_FILE);
5658
5844
  try {
5659
- const raw = await readFile3(filePath, "utf-8");
5845
+ const raw = await readFile5(filePath, "utf-8");
5660
5846
  const data = JSON.parse(raw);
5661
5847
  if (typeof data.latestVersion === "string" && typeof data.lastCheckedAt === "string") {
5662
5848
  return data;
@@ -5748,7 +5934,8 @@ var app = subcommands({
5748
5934
  self: selfCommand,
5749
5935
  trace: traceCommand,
5750
5936
  trim: trimCommand,
5751
- validate: validateCommand
5937
+ validate: validateCommand,
5938
+ workspace: workspaceCommand
5752
5939
  }
5753
5940
  });
5754
5941
  var PROMPT_EVAL_SUBCOMMANDS = /* @__PURE__ */ new Set(["overview", "input", "judge"]);
@@ -5794,4 +5981,4 @@ export {
5794
5981
  preprocessArgv,
5795
5982
  runCli
5796
5983
  };
5797
- //# sourceMappingURL=chunk-D3WKMO6D.js.map
5984
+ //# sourceMappingURL=chunk-IKGJTJSU.js.map