agentv 4.35.1 → 4.36.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/{artifact-writer-G57MG52C.js → artifact-writer-3YRN6YTA.js} +4 -4
  2. package/dist/{chunk-CRMGUVRZ.js → chunk-4M6FAQTW.js} +85 -19
  3. package/dist/chunk-4M6FAQTW.js.map +1 -0
  4. package/dist/{chunk-INOKS5LF.js → chunk-7KZ2AF26.js} +269 -57
  5. package/dist/chunk-7KZ2AF26.js.map +1 -0
  6. package/dist/{chunk-KJGYL3M3.js → chunk-HVBAVOAH.js} +72 -50
  7. package/dist/chunk-HVBAVOAH.js.map +1 -0
  8. package/dist/{chunk-KNF3AGCI.js → chunk-P5JONEWJ.js} +231 -35
  9. package/dist/chunk-P5JONEWJ.js.map +1 -0
  10. package/dist/{chunk-6QEIZ33V.js → chunk-TUTURE2B.js} +1227 -372
  11. package/dist/chunk-TUTURE2B.js.map +1 -0
  12. package/dist/cli.js +5 -5
  13. package/dist/dashboard/assets/index-DA96FAM5.js +119 -0
  14. package/dist/dashboard/assets/{index-Bdk-9a_8.js → index-l4t97uO8.js} +1 -1
  15. package/dist/dashboard/assets/index-nmrFBoNd.css +1 -0
  16. package/dist/dashboard/index.html +2 -2
  17. package/dist/{dist-M4B77IW4.js → dist-BSFUYS54.js} +73 -3
  18. package/dist/index.js +5 -5
  19. package/dist/{interactive-VYQ5SYMR.js → interactive-IEC63EVP.js} +5 -5
  20. package/dist/skills/agentv-eval-writer/SKILL.md +6 -0
  21. package/dist/{ts-eval-loader-EQJX3OLT-THE7D3GR.js → ts-eval-loader-4DU65XGW-YM47FFG2.js} +2 -2
  22. package/package.json +1 -1
  23. package/dist/chunk-6QEIZ33V.js.map +0 -1
  24. package/dist/chunk-CRMGUVRZ.js.map +0 -1
  25. package/dist/chunk-INOKS5LF.js.map +0 -1
  26. package/dist/chunk-KJGYL3M3.js.map +0 -1
  27. package/dist/chunk-KNF3AGCI.js.map +0 -1
  28. package/dist/dashboard/assets/index-BPMAZqjE.css +0 -1
  29. package/dist/dashboard/assets/index-BWO0UcxG.js +0 -118
  30. /package/dist/{artifact-writer-G57MG52C.js.map → artifact-writer-3YRN6YTA.js.map} +0 -0
  31. /package/dist/{dist-M4B77IW4.js.map → dist-BSFUYS54.js.map} +0 -0
  32. /package/dist/{interactive-VYQ5SYMR.js.map → interactive-IEC63EVP.js.map} +0 -0
  33. /package/dist/{ts-eval-loader-EQJX3OLT-THE7D3GR.js.map → ts-eval-loader-4DU65XGW-YM47FFG2.js.map} +0 -0
@@ -1,5 +1,6 @@
1
1
  import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
2
2
  import {
3
+ buildTraceFromMessages,
3
4
  external_exports,
4
5
  extractLastAssistantContent,
5
6
  getAgentvConfigDir,
@@ -12,7 +13,7 @@ import {
12
13
  parseYamlValue,
13
14
  toCamelCaseDeep,
14
15
  toSnakeCaseDeep
15
- } from "./chunk-6QEIZ33V.js";
16
+ } from "./chunk-TUTURE2B.js";
16
17
 
17
18
  // ../../packages/core/dist/index.js
18
19
  import { readFileSync } from "node:fs";
@@ -547,6 +548,8 @@ function extractReposFromObject(obj) {
547
548
  var execFileAsync = promisify(execFile);
548
549
  var RESULTS_REPO_RESULTS_DIR = ".agentv/results";
549
550
  var RESULTS_REPO_RUNS_DIR = `${RESULTS_REPO_RESULTS_DIR}/runs`;
551
+ var RESULTS_REPO_COMMIT_EMAIL = "agentv@results-repo";
552
+ var RESULTS_REPO_COMMIT_NAME = "AgentV Results";
550
553
  var activeResultsRepoSyncs = /* @__PURE__ */ new Set();
551
554
  function sanitizeRepoSlug(repo) {
552
555
  return repo.trim().replace(/[^A-Za-z0-9._-]+/g, "-");
@@ -567,10 +570,12 @@ function expandHome(p) {
567
570
  }
568
571
  function normalizeResultsConfig(config) {
569
572
  const repo = config.repo.trim();
573
+ const branch = config.branch?.trim();
570
574
  const resolvedPath = config.path ? expandHome(config.path.trim()) : path3.join(getAgentvDataDir(), "results", sanitizeRepoSlug(repo));
571
575
  return {
572
576
  mode: "github",
573
577
  repo,
578
+ ...branch ? { branch } : {},
574
579
  path: resolvedPath,
575
580
  auto_push: config.auto_push === true,
576
581
  branch_prefix: config.branch_prefix?.trim() || "eval-results"
@@ -638,6 +643,10 @@ async function runGit(args, options) {
638
643
  async function runGh(args, options) {
639
644
  return runCommand("gh", args, options);
640
645
  }
646
+ async function ensureResultsRepoCommitIdentity(repoDir) {
647
+ await runGit(["config", "user.email", RESULTS_REPO_COMMIT_EMAIL], { cwd: repoDir });
648
+ await runGit(["config", "user.name", RESULTS_REPO_COMMIT_NAME], { cwd: repoDir });
649
+ }
641
650
  async function resolveDefaultBranch(repoDir) {
642
651
  try {
643
652
  const { stdout } = await runGit(["symbolic-ref", "refs/remotes/origin/HEAD"], { cwd: repoDir });
@@ -660,6 +669,64 @@ async function resolveDefaultBranch(repoDir) {
660
669
  async function fetchResultsRepo(repoDir) {
661
670
  await runGit(["fetch", "origin", "--prune"], { cwd: repoDir });
662
671
  }
672
+ function remoteBranchRef(branch) {
673
+ return `origin/${branch}`;
674
+ }
675
+ function missingConfiguredBranchError(config) {
676
+ const branch = config.branch ?? "<unknown>";
677
+ return new Error(
678
+ [
679
+ `Results repo remote branch '${branch}' does not exist in ${config.repo}.`,
680
+ "Create the storage branch once, then retry. Example:",
681
+ ` git clone ${resolveResultsRepoUrl(config.repo)} /tmp/agentv-results-init`,
682
+ " cd /tmp/agentv-results-init",
683
+ ` git switch --orphan ${branch}`,
684
+ " git rm -rf .",
685
+ ' git commit --allow-empty -m "chore(results): initialize AgentV results branch"',
686
+ ` git push origin HEAD:${branch}`
687
+ ].join("\n")
688
+ );
689
+ }
690
+ async function assertConfiguredResultsBranchExists(repoDir, config) {
691
+ if (!config.branch) {
692
+ return void 0;
693
+ }
694
+ const ref = remoteBranchRef(config.branch);
695
+ const { stdout } = await runGit(["rev-parse", "--verify", `${ref}^{commit}`], {
696
+ cwd: repoDir,
697
+ check: false
698
+ });
699
+ if (!stdout.trim()) {
700
+ throw missingConfiguredBranchError(config);
701
+ }
702
+ return ref;
703
+ }
704
+ async function localBranchExists(repoDir, branch) {
705
+ const { stdout } = await runGit(["rev-parse", "--verify", `refs/heads/${branch}`], {
706
+ cwd: repoDir,
707
+ check: false
708
+ });
709
+ return stdout.trim().length > 0;
710
+ }
711
+ async function checkoutConfiguredResultsBranch(repoDir, config) {
712
+ const remoteRef = await assertConfiguredResultsBranchExists(repoDir, config);
713
+ if (!config.branch || !remoteRef) {
714
+ return void 0;
715
+ }
716
+ const currentBranch = await getCurrentBranch(repoDir);
717
+ if (currentBranch !== config.branch) {
718
+ if (await localBranchExists(repoDir, config.branch)) {
719
+ await runGit(["checkout", config.branch], { cwd: repoDir });
720
+ } else {
721
+ await runGit(["checkout", "--track", "-b", config.branch, remoteRef], { cwd: repoDir });
722
+ }
723
+ }
724
+ await runGit(["branch", "--set-upstream-to", remoteRef, config.branch], {
725
+ cwd: repoDir,
726
+ check: false
727
+ });
728
+ return remoteRef;
729
+ }
663
730
  async function isGitRepository(repoDir) {
664
731
  try {
665
732
  const { stdout } = await runGit(["rev-parse", "--is-inside-work-tree"], { cwd: repoDir });
@@ -763,7 +830,10 @@ async function getCurrentBranch(repoDir) {
763
830
  });
764
831
  return sha.trim() ? `HEAD@${sha.trim()}` : void 0;
765
832
  }
766
- async function resolveComparisonRef(repoDir) {
833
+ async function resolveComparisonRef(repoDir, config) {
834
+ if (config?.branch) {
835
+ return assertConfiguredResultsBranchExists(repoDir, config);
836
+ }
767
837
  const { stdout: upstream } = await runGit(
768
838
  ["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{upstream}"],
769
839
  { cwd: repoDir, check: false }
@@ -826,9 +896,9 @@ async function buildGitDiffSummary(repoDir, upstream) {
826
896
  }
827
897
  return summaries.length > 0 ? summaries.join("\n") : void 0;
828
898
  }
829
- async function inspectResultsRepoGit(repoDir) {
899
+ async function inspectResultsRepoGit(repoDir, config) {
830
900
  const branch = await getCurrentBranch(repoDir);
831
- const upstream = await resolveComparisonRef(repoDir);
901
+ const upstream = await resolveComparisonRef(repoDir, config);
832
902
  const { stdout: porcelain } = await runGit(
833
903
  ["status", "--porcelain=v1", "--untracked-files=all"],
834
904
  {
@@ -936,7 +1006,10 @@ function getPushTargetBranch(upstream, baseBranch) {
936
1006
  return upstream?.startsWith("origin/") ? upstream.slice("origin/".length) : baseBranch;
937
1007
  }
938
1008
  async function statusFromInspection(normalized, repoDir) {
939
- return withGitInspection(getResultsRepoStatus(normalized), await inspectResultsRepoGit(repoDir));
1009
+ return withGitInspection(
1010
+ getResultsRepoStatus(normalized),
1011
+ await inspectResultsRepoGit(repoDir, normalized)
1012
+ );
940
1013
  }
941
1014
  async function getResultsRepoSyncStatus(config) {
942
1015
  const baseStatus = getResultsRepoStatus(config);
@@ -957,10 +1030,15 @@ async function getResultsRepoSyncStatus(config) {
957
1030
  };
958
1031
  }
959
1032
  try {
960
- return withGitInspection(baseStatus, await inspectResultsRepoGit(normalized.path));
1033
+ if (normalized.branch) {
1034
+ await fetchResultsRepo(normalized.path);
1035
+ await checkoutConfiguredResultsBranch(normalized.path, normalized);
1036
+ }
1037
+ return withGitInspection(baseStatus, await inspectResultsRepoGit(normalized.path, normalized));
961
1038
  } catch (error) {
962
1039
  return {
963
1040
  ...baseStatus,
1041
+ ...normalized.branch ? { available: false } : {},
964
1042
  sync_status: "unavailable",
965
1043
  last_error: getStatusMessage(error)
966
1044
  };
@@ -971,6 +1049,7 @@ async function syncResultsRepo(config) {
971
1049
  try {
972
1050
  const repoDir = await ensureResultsRepoClone(normalized);
973
1051
  await fetchResultsRepo(repoDir);
1052
+ await checkoutConfiguredResultsBranch(repoDir, normalized);
974
1053
  updateStatusFile(normalized, {
975
1054
  last_synced_at: (/* @__PURE__ */ new Date()).toISOString(),
976
1055
  last_error: void 0
@@ -1004,7 +1083,8 @@ async function syncResultsRepoForProject(config) {
1004
1083
  try {
1005
1084
  const repoDir = await ensureResultsRepoClone(normalized);
1006
1085
  await fetchResultsRepo(repoDir);
1007
- let inspection = await inspectResultsRepoGit(repoDir);
1086
+ await checkoutConfiguredResultsBranch(repoDir, normalized);
1087
+ let inspection = await inspectResultsRepoGit(repoDir, normalized);
1008
1088
  if (inspection.syncStatus === "conflicted") {
1009
1089
  const status = withGitInspection(getResultsRepoStatus(normalized), inspection);
1010
1090
  updateStatusFile(normalized, {
@@ -1047,9 +1127,9 @@ async function syncResultsRepoForProject(config) {
1047
1127
  try {
1048
1128
  await runGit(["merge", "--ff-only", inspection.upstream], { cwd: repoDir });
1049
1129
  pullPerformed = true;
1050
- inspection = await inspectResultsRepoGit(repoDir);
1130
+ inspection = await inspectResultsRepoGit(repoDir, normalized);
1051
1131
  } catch (error) {
1052
- inspection = await inspectResultsRepoGit(repoDir);
1132
+ inspection = await inspectResultsRepoGit(repoDir, normalized);
1053
1133
  const status = withGitInspection(getResultsRepoStatus(normalized), inspection);
1054
1134
  const reason = `Results repo could not be fast-forwarded: ${getStatusMessage(error)}`;
1055
1135
  updateStatusFile(normalized, { last_error: reason });
@@ -1062,6 +1142,7 @@ async function syncResultsRepoForProject(config) {
1062
1142
  }
1063
1143
  if (inspection.syncStatus === "dirty") {
1064
1144
  await runGit(["add", "--all", "--", RESULTS_REPO_RESULTS_DIR], { cwd: repoDir });
1145
+ await ensureResultsRepoCommitIdentity(repoDir);
1065
1146
  await runGit(
1066
1147
  [
1067
1148
  "commit",
@@ -1075,7 +1156,7 @@ async function syncResultsRepoForProject(config) {
1075
1156
  }
1076
1157
  );
1077
1158
  commitCreated = true;
1078
- inspection = await inspectResultsRepoGit(repoDir);
1159
+ inspection = await inspectResultsRepoGit(repoDir, normalized);
1079
1160
  }
1080
1161
  }
1081
1162
  if (inspection.syncStatus === "diverged") {
@@ -1104,9 +1185,9 @@ async function syncResultsRepoForProject(config) {
1104
1185
  try {
1105
1186
  await runGit(["merge", "--ff-only", inspection.upstream], { cwd: repoDir });
1106
1187
  pullPerformed = true;
1107
- inspection = await inspectResultsRepoGit(repoDir);
1188
+ inspection = await inspectResultsRepoGit(repoDir, normalized);
1108
1189
  } catch (error) {
1109
- inspection = await inspectResultsRepoGit(repoDir);
1190
+ inspection = await inspectResultsRepoGit(repoDir, normalized);
1110
1191
  const status = withGitInspection(getResultsRepoStatus(normalized), inspection);
1111
1192
  const reason = `Results repo could not be fast-forwarded: ${getStatusMessage(error)}`;
1112
1193
  updateStatusFile(normalized, { last_error: reason });
@@ -1137,16 +1218,16 @@ async function syncResultsRepoForProject(config) {
1137
1218
  commitCreated
1138
1219
  });
1139
1220
  }
1140
- const baseBranch = await resolveDefaultBranch(repoDir);
1221
+ const baseBranch = normalized.branch ?? await resolveDefaultBranch(repoDir);
1141
1222
  const targetBranch = getPushTargetBranch(inspection.upstream, baseBranch);
1142
1223
  try {
1143
1224
  await runGit(["push", "origin", `HEAD:${targetBranch}`], { cwd: repoDir });
1144
1225
  pushPerformed = true;
1145
1226
  await fetchResultsRepo(repoDir);
1146
- inspection = await inspectResultsRepoGit(repoDir);
1227
+ inspection = await inspectResultsRepoGit(repoDir, normalized);
1147
1228
  } catch (error) {
1148
1229
  await fetchResultsRepo(repoDir).catch(() => void 0);
1149
- inspection = await inspectResultsRepoGit(repoDir);
1230
+ inspection = await inspectResultsRepoGit(repoDir, normalized);
1150
1231
  const status = withGitInspection(getResultsRepoStatus(normalized), inspection);
1151
1232
  const reason = `Results repo push was rejected: ${getStatusMessage(error)}`;
1152
1233
  updateStatusFile(normalized, { last_error: reason });
@@ -1240,6 +1321,7 @@ async function commitAndPushResultsBranch(params) {
1240
1321
  if (diffStdout.trim().length === 0) {
1241
1322
  return false;
1242
1323
  }
1324
+ await ensureResultsRepoCommitIdentity(params.repoDir);
1243
1325
  await runGit(["commit", "-m", params.commitMessage], { cwd: params.repoDir });
1244
1326
  await runGit(["push", "-u", "origin", params.branchName], { cwd: params.repoDir });
1245
1327
  return true;
@@ -1276,17 +1358,17 @@ async function createDraftResultsPr(params) {
1276
1358
  return stdout.trim();
1277
1359
  }
1278
1360
  var DIRECT_PUSH_MAX_RETRIES = 3;
1279
- async function hasUnpushedCommits(repoDir, baseBranch) {
1280
- const { stdout } = await runGit(["rev-list", "--count", `origin/${baseBranch}..HEAD`], {
1361
+ async function hasUnpushedCommits(repoDir, upstreamRef) {
1362
+ const { stdout } = await runGit(["rev-list", "--count", `${upstreamRef}..HEAD`], {
1281
1363
  cwd: repoDir,
1282
1364
  check: false
1283
1365
  });
1284
1366
  return Number.parseInt(stdout.trim(), 10) > 0;
1285
1367
  }
1286
- async function pushDirectResultsToBase(params) {
1368
+ async function pushDirectResultsToStorageBranch(params) {
1287
1369
  for (let attempt = 1; attempt <= DIRECT_PUSH_MAX_RETRIES; attempt++) {
1288
1370
  try {
1289
- await runGit(["push", "origin", `HEAD:${params.baseBranch}`], { cwd: params.repoDir });
1371
+ await runGit(["push", "origin", `HEAD:${params.storageBranch}`], { cwd: params.repoDir });
1290
1372
  updateStatusFile(params.normalized, {
1291
1373
  last_synced_at: (/* @__PURE__ */ new Date()).toISOString(),
1292
1374
  last_error: void 0
@@ -1296,7 +1378,7 @@ async function pushDirectResultsToBase(params) {
1296
1378
  const message = error instanceof Error ? error.message : String(error);
1297
1379
  if (attempt < DIRECT_PUSH_MAX_RETRIES && message.includes("non-fast-forward")) {
1298
1380
  await fetchResultsRepo(params.repoDir);
1299
- await runGit(["rebase", `origin/${params.baseBranch}`], { cwd: params.repoDir });
1381
+ await runGit(["rebase", params.upstreamRef], { cwd: params.repoDir });
1300
1382
  } else {
1301
1383
  throw error;
1302
1384
  }
@@ -1306,8 +1388,10 @@ async function pushDirectResultsToBase(params) {
1306
1388
  async function directPushResults(params) {
1307
1389
  const normalized = normalizeResultsConfig(params.config);
1308
1390
  const repoDir = await ensureResultsRepoClone(normalized);
1309
- const baseBranch = await resolveDefaultBranch(repoDir);
1310
1391
  await fetchResultsRepo(repoDir);
1392
+ const configuredRef = await checkoutConfiguredResultsBranch(repoDir, normalized);
1393
+ const storageBranch = normalized.branch ?? await resolveDefaultBranch(repoDir);
1394
+ const upstreamRef = configuredRef ?? remoteBranchRef(storageBranch);
1311
1395
  const targetRunId = buildGitRunId(params.destinationPath);
1312
1396
  const destinationDir = path3.join(
1313
1397
  repoDir,
@@ -1326,20 +1410,21 @@ async function directPushResults(params) {
1326
1410
  check: false
1327
1411
  });
1328
1412
  if (status.trim().length === 0) {
1329
- if (await hasUnpushedCommits(repoDir, baseBranch)) {
1330
- const aheadPaths = await getAheadPaths(repoDir, `origin/${baseBranch}`);
1413
+ if (await hasUnpushedCommits(repoDir, upstreamRef)) {
1414
+ const aheadPaths = await getAheadPaths(repoDir, upstreamRef);
1331
1415
  if (!areSafeResultsRepoPaths(aheadPaths)) {
1332
1416
  throw new Error("Results repo has non-results committed changes");
1333
1417
  }
1334
- await pushDirectResultsToBase({ normalized, repoDir, baseBranch });
1418
+ await pushDirectResultsToStorageBranch({ normalized, repoDir, storageBranch, upstreamRef });
1335
1419
  return true;
1336
1420
  }
1337
1421
  return false;
1338
1422
  }
1423
+ await ensureResultsRepoCommitIdentity(repoDir);
1339
1424
  await runGit(["commit", "-m", params.commitMessage, "-m", `Agentv-Run: ${targetRunId}`], {
1340
1425
  cwd: repoDir
1341
1426
  });
1342
- await pushDirectResultsToBase({ normalized, repoDir, baseBranch });
1427
+ await pushDirectResultsToStorageBranch({ normalized, repoDir, storageBranch, upstreamRef });
1343
1428
  return true;
1344
1429
  }
1345
1430
  function buildGitRunId(relativeRunPath) {
@@ -1445,6 +1530,75 @@ function parseGitBatchBlobs(output) {
1445
1530
  }
1446
1531
  return blobs;
1447
1532
  }
1533
+ function buildWipBranchName(runDir) {
1534
+ const hostname = os.hostname().replace(/[^A-Za-z0-9._-]+/g, "-").slice(0, 40);
1535
+ const runBasename = path3.basename(runDir).replace(/[^A-Za-z0-9._-]+/g, "-").slice(0, 60);
1536
+ return `agentv/inflight/${hostname}/${runBasename}`;
1537
+ }
1538
+ async function setupWipWorktree(params) {
1539
+ const normalized = normalizeResultsConfig(params.config);
1540
+ const cloneDir = await ensureResultsRepoClone(normalized);
1541
+ await fetchResultsRepo(cloneDir);
1542
+ const baseRef = normalized.branch ? await assertConfiguredResultsBranchExists(cloneDir, normalized) : remoteBranchRef(await resolveDefaultBranch(cloneDir));
1543
+ if (!baseRef) {
1544
+ throw missingConfiguredBranchError(normalized);
1545
+ }
1546
+ const worktreeRoot = await mkdtemp(path3.join(os.tmpdir(), "agentv-wip-"));
1547
+ const worktreeDir = path3.join(worktreeRoot, "repo");
1548
+ await runGit(["worktree", "add", "-B", params.wipBranch, worktreeDir, baseRef], {
1549
+ cwd: cloneDir
1550
+ });
1551
+ await runGit(["config", "user.email", "agentv@wip-checkpoint"], { cwd: worktreeDir });
1552
+ await runGit(["config", "user.name", "AgentV WIP Checkpoint"], { cwd: worktreeDir });
1553
+ return {
1554
+ wipBranch: params.wipBranch,
1555
+ worktreeDir,
1556
+ cloneDir,
1557
+ cleanup: async () => {
1558
+ try {
1559
+ await runGit(["worktree", "remove", "--force", worktreeDir], { cwd: cloneDir });
1560
+ } finally {
1561
+ await rm(worktreeRoot, { recursive: true, force: true }).catch(() => void 0);
1562
+ }
1563
+ }
1564
+ };
1565
+ }
1566
+ async function pushWipCheckpoint(params) {
1567
+ const destinationDir = path3.join(
1568
+ params.handle.worktreeDir,
1569
+ RESULTS_REPO_RUNS_DIR,
1570
+ params.destinationPath
1571
+ );
1572
+ await stageResultsArtifacts({
1573
+ repoDir: params.handle.worktreeDir,
1574
+ sourceDir: params.sourceDir,
1575
+ destinationDir
1576
+ });
1577
+ await runGit(["add", "--all", "--", RESULTS_REPO_RESULTS_DIR], {
1578
+ cwd: params.handle.worktreeDir
1579
+ });
1580
+ const { stdout: status } = await runGit(["status", "--porcelain"], {
1581
+ cwd: params.handle.worktreeDir,
1582
+ check: false
1583
+ });
1584
+ if (!status.trim()) {
1585
+ return false;
1586
+ }
1587
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
1588
+ await runGit(
1589
+ ["commit", "--amend", "-m", `wip(results): checkpoint ${params.handle.wipBranch} ${timestamp}`],
1590
+ { cwd: params.handle.worktreeDir }
1591
+ );
1592
+ await runGit(["push", "--force", "origin", params.handle.wipBranch], {
1593
+ cwd: params.handle.worktreeDir
1594
+ });
1595
+ return true;
1596
+ }
1597
+ async function deleteWipBranch(params) {
1598
+ const normalized = normalizeResultsConfig(params.config);
1599
+ const cloneDir = await ensureResultsRepoClone(normalized);
1600
+ await runGit(["push", "origin", "--delete", params.wipBranch], { cwd: cloneDir });
1601
+ }
1448
1602
  async function listGitRuns(repoDir, ref = "origin/main") {
1449
1603
  const { stdout: treeOut } = await runGit(
1450
1604
  ["ls-tree", "-r", "--name-only", ref, RESULTS_REPO_RUNS_DIR],
@@ -1563,6 +1717,7 @@ function fromYaml(raw) {
1563
1717
  const sync = r.sync && typeof r.sync === "object" ? r.sync : void 0;
1564
1718
  entry.results = {
1565
1719
  repoUrl: r.repo_url.trim(),
1720
+ ...typeof r.branch === "string" && r.branch.trim().length > 0 ? { branch: r.branch.trim() } : {},
1566
1721
  ...typeof r.path === "string" && r.path.trim().length > 0 ? { path: r.path.trim() } : {},
1567
1722
  ...sync && typeof sync.auto_push === "boolean" ? { sync: { autoPush: sync.auto_push } } : {},
1568
1723
  ...typeof r.branch_prefix === "string" && r.branch_prefix.trim().length > 0 ? { branchPrefix: r.branch_prefix.trim() } : {}
@@ -1584,6 +1739,7 @@ function toYaml(entry) {
1584
1739
  if (entry.results) {
1585
1740
  yaml.results = {
1586
1741
  repo_url: entry.results.repoUrl,
1742
+ ...entry.results.branch !== void 0 && { branch: entry.results.branch },
1587
1743
  ...entry.results.path !== void 0 && { path: entry.results.path },
1588
1744
  ...entry.results.sync?.autoPush !== void 0 && {
1589
1745
  sync: { auto_push: entry.results.sync.autoPush }
@@ -1924,9 +2080,7 @@ var OtelTraceExporter = class {
1924
2080
  if (result.suite) rootSpan.setAttribute("agentv.suite", result.suite);
1925
2081
  rootSpan.setAttribute("agentv.score", result.score);
1926
2082
  if (captureContent && result.output.length > 0) {
1927
- const lastMsg = result.output[result.output.length - 1];
1928
- const text = typeof lastMsg.content === "string" ? lastMsg.content : JSON.stringify(lastMsg.content);
1929
- rootSpan.setAttribute("agentv.output_text", text);
2083
+ rootSpan.setAttribute("agentv.output_text", result.output);
1930
2084
  }
1931
2085
  if (result.durationMs != null)
1932
2086
  rootSpan.setAttribute("agentv.trace.duration_ms", result.durationMs);
@@ -1952,10 +2106,11 @@ var OtelTraceExporter = class {
1952
2106
  if (t.llmCallCount != null)
1953
2107
  rootSpan.setAttribute("agentv.trace.llm_call_count", t.llmCallCount);
1954
2108
  }
1955
- if (result.output) {
2109
+ const traceMessages = result.trace?.messages ?? [];
2110
+ if (traceMessages.length > 0) {
1956
2111
  const parentCtx2 = api.trace.setSpan(api.context.active(), rootSpan);
1957
2112
  if (this.options.groupTurns) {
1958
- const turns = groupMessagesIntoTurns(result.output);
2113
+ const turns = groupMessagesIntoTurns(traceMessages);
1959
2114
  if (turns.length > 1) {
1960
2115
  for (const [i, turn] of turns.entries()) {
1961
2116
  api.context.with(parentCtx2, () => {
@@ -1973,12 +2128,12 @@ var OtelTraceExporter = class {
1973
2128
  });
1974
2129
  }
1975
2130
  } else {
1976
- for (const msg of result.output) {
2131
+ for (const msg of traceMessages) {
1977
2132
  this.exportMessage(tracer, api, parentCtx2, msg, captureContent);
1978
2133
  }
1979
2134
  }
1980
2135
  } else {
1981
- for (const msg of result.output) {
2136
+ for (const msg of traceMessages) {
1982
2137
  this.exportMessage(tracer, api, parentCtx2, msg, captureContent);
1983
2138
  }
1984
2139
  }
@@ -2245,9 +2400,9 @@ var OtelStreamingObserver = class {
2245
2400
  if (this.observedChildSpans || !this.rootCtx) {
2246
2401
  return;
2247
2402
  }
2248
- const model = result.output.find((msg) => msg.role === "assistant")?.metadata?.model ?? result.target ?? "unknown";
2403
+ const model = result.trace.messages.find((msg) => msg.role === "assistant")?.metadata?.model ?? result.target ?? "unknown";
2249
2404
  this.onLlmCall(String(model), result.tokenUsage);
2250
- for (const message of result.output) {
2405
+ for (const message of result.trace.messages) {
2251
2406
  for (const toolCall of message.toolCalls ?? []) {
2252
2407
  this.onToolCall(
2253
2408
  toolCall.tool,
@@ -2860,6 +3015,41 @@ function toTranscriptJsonLines(entry, options) {
2860
3015
  source
2861
3016
  }));
2862
3017
  }
3018
+ function traceToTranscriptJsonLines(trace, options) {
3019
+ const provider = (typeof trace.metadata?.provider === "string" ? trace.metadata.provider : void 0) ?? options?.target ?? "agentv";
3020
+ const sessionId = (typeof trace.metadata?.provider_session_id === "string" ? trace.metadata.provider_session_id : void 0) ?? (typeof trace.metadata?.eval_case_id === "string" ? trace.metadata.eval_case_id : void 0) ?? options?.testId ?? "trace";
3021
+ return toTranscriptJsonLines(
3022
+ {
3023
+ messages: [...trace.messages],
3024
+ source: {
3025
+ provider,
3026
+ sessionId,
3027
+ startedAt: trace.startTime
3028
+ },
3029
+ tokenUsage: trace.tokenUsage,
3030
+ durationMs: trace.durationMs,
3031
+ costUsd: trace.costUsd
3032
+ },
3033
+ options
3034
+ );
3035
+ }
3036
+ function traceFromTranscriptJsonLines(lines) {
3037
+ const [entry] = groupTranscriptJsonLines(lines);
3038
+ if (!entry) {
3039
+ return buildTraceFromMessages();
3040
+ }
3041
+ return buildTraceFromMessages({
3042
+ output: entry.messages,
3043
+ tokenUsage: entry.tokenUsage,
3044
+ durationMs: entry.durationMs,
3045
+ costUsd: entry.costUsd ?? void 0,
3046
+ startTime: entry.source.startedAt,
3047
+ provider: entry.source.provider,
3048
+ target: entry.target,
3049
+ testId: entry.testId,
3050
+ conversationId: entry.source.sessionId
3051
+ });
3052
+ }
2863
3053
  function buildReplayMessage(line) {
2864
3054
  const camelCased = toCamelCaseDeep(line);
2865
3055
  return {
@@ -2999,6 +3189,10 @@ export {
2999
3189
  pushResultsRepoBranch,
3000
3190
  createDraftResultsPr,
3001
3191
  directPushResults,
3192
+ buildWipBranchName,
3193
+ setupWipWorktree,
3194
+ pushWipCheckpoint,
3195
+ deleteWipBranch,
3002
3196
  listGitRuns,
3003
3197
  materializeGitRun,
3004
3198
  getProjectsRegistryPath,
@@ -3027,10 +3221,12 @@ export {
3027
3221
  discoverCodexSessions,
3028
3222
  discoverClaudeSessions,
3029
3223
  toTranscriptJsonLines,
3224
+ traceToTranscriptJsonLines,
3225
+ traceFromTranscriptJsonLines,
3030
3226
  groupTranscriptJsonLines,
3031
3227
  readTranscriptJsonl,
3032
3228
  readTranscriptFile,
3033
3229
  TranscriptProvider,
3034
3230
  createAgentKernel
3035
3231
  };
3036
- //# sourceMappingURL=chunk-KNF3AGCI.js.map
3232
+ //# sourceMappingURL=chunk-P5JONEWJ.js.map