agentv 3.13.2 → 3.14.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.
@@ -301,7 +301,7 @@ var require_dist = __commonJS({
301
301
  }
302
302
  });
303
303
 
304
- // ../../packages/core/dist/chunk-ZB3AUPES.js
304
+ // ../../packages/core/dist/chunk-HP5PFOVK.js
305
305
  import { constants } from "node:fs";
306
306
  import { access, readFile } from "node:fs/promises";
307
307
  import path from "node:path";
@@ -419,7 +419,7 @@ __export(external_exports2, {
419
419
  void: () => voidType
420
420
  });
421
421
 
422
- // ../../packages/core/dist/chunk-ZB3AUPES.js
422
+ // ../../packages/core/dist/chunk-HP5PFOVK.js
423
423
  import { readFile as readFile2 } from "node:fs/promises";
424
424
  import path3 from "node:path";
425
425
  import fg from "fast-glob";
@@ -926,6 +926,15 @@ function resolveTargetDefinition(definition, env = process.env, evalFilePath) {
926
926
  providerBatching,
927
927
  config: resolveCopilotCliConfig(parsed, env, evalFilePath)
928
928
  };
929
+ case "copilot-log":
930
+ return {
931
+ kind: "copilot-log",
932
+ name: parsed.name,
933
+ graderTarget: parsed.grader_target ?? parsed.judge_target,
934
+ workers: parsed.workers,
935
+ providerBatching,
936
+ config: resolveCopilotLogConfig(parsed, env)
937
+ };
929
938
  case "pi":
930
939
  case "pi-coding-agent":
931
940
  return {
@@ -1644,8 +1653,8 @@ function resolveCliConfig(target, env, evalFilePath) {
1644
1653
  const parseResult = CliTargetInputSchema.safeParse(target, { errorMap: cliErrorMap });
1645
1654
  if (!parseResult.success) {
1646
1655
  const firstError = parseResult.error.errors[0];
1647
- const path45 = firstError?.path.join(".") || "";
1648
- const prefix = path45 ? `${target.name} ${path45}: ` : `${target.name}: `;
1656
+ const path47 = firstError?.path.join(".") || "";
1657
+ const prefix = path47 ? `${target.name} ${path47}: ` : `${target.name}: `;
1649
1658
  throw new Error(`${prefix}${firstError?.message}`);
1650
1659
  }
1651
1660
  const normalized = normalizeCliTargetInput(parseResult.data, env, evalFilePath);
@@ -1718,6 +1727,43 @@ function resolveString(source, env, description, allowLiteral = false) {
1718
1727
  }
1719
1728
  return value;
1720
1729
  }
1730
+ function resolveDiscover(value, targetName) {
1731
+ if (value === void 0 || value === null) return void 0;
1732
+ if (value === "latest") return "latest";
1733
+ throw new Error(`Target "${targetName}": discover must be "latest" (got "${String(value)}")`);
1734
+ }
1735
+ function resolveCopilotLogConfig(target, env) {
1736
+ const sessionDirSource = target.session_dir ?? target.sessionDir;
1737
+ const sessionIdSource = target.session_id ?? target.sessionId;
1738
+ const discoverSource = target.discover;
1739
+ const sessionStateDirSource = target.session_state_dir ?? target.sessionStateDir;
1740
+ const cwdSource = target.cwd;
1741
+ return {
1742
+ sessionDir: resolveOptionalString(
1743
+ sessionDirSource,
1744
+ env,
1745
+ `${target.name} copilot-log session_dir`,
1746
+ { allowLiteral: true, optionalEnv: true }
1747
+ ),
1748
+ sessionId: resolveOptionalString(
1749
+ sessionIdSource,
1750
+ env,
1751
+ `${target.name} copilot-log session_id`,
1752
+ { allowLiteral: true, optionalEnv: true }
1753
+ ),
1754
+ discover: resolveDiscover(discoverSource, target.name),
1755
+ sessionStateDir: resolveOptionalString(
1756
+ sessionStateDirSource,
1757
+ env,
1758
+ `${target.name} copilot-log session_state_dir`,
1759
+ { allowLiteral: true, optionalEnv: true }
1760
+ ),
1761
+ cwd: resolveOptionalString(cwdSource, env, `${target.name} copilot-log cwd`, {
1762
+ allowLiteral: true,
1763
+ optionalEnv: true
1764
+ })
1765
+ };
1766
+ }
1721
1767
  function resolveOptionalString(source, env, description, options) {
1722
1768
  if (source === void 0 || source === null) {
1723
1769
  return void 0;
@@ -2001,6 +2047,7 @@ var KNOWN_PROVIDERS = [
2001
2047
  "codex",
2002
2048
  "copilot-sdk",
2003
2049
  "copilot-cli",
2050
+ "copilot-log",
2004
2051
  "pi-coding-agent",
2005
2052
  "pi-cli",
2006
2053
  "claude",
@@ -6687,7 +6734,7 @@ function createOpenRouter(options = {}) {
6687
6734
  );
6688
6735
  const createChatModel = (modelId, settings = {}) => new OpenRouterChatLanguageModel(modelId, settings, {
6689
6736
  provider: "openrouter.chat",
6690
- url: ({ path: path45 }) => `${baseURL}${path45}`,
6737
+ url: ({ path: path47 }) => `${baseURL}${path47}`,
6691
6738
  headers: getHeaders,
6692
6739
  compatibility,
6693
6740
  fetch: options.fetch,
@@ -6695,7 +6742,7 @@ function createOpenRouter(options = {}) {
6695
6742
  });
6696
6743
  const createCompletionModel = (modelId, settings = {}) => new OpenRouterCompletionLanguageModel(modelId, settings, {
6697
6744
  provider: "openrouter.completion",
6698
- url: ({ path: path45 }) => `${baseURL}${path45}`,
6745
+ url: ({ path: path47 }) => `${baseURL}${path47}`,
6699
6746
  headers: getHeaders,
6700
6747
  compatibility,
6701
6748
  fetch: options.fetch,
@@ -6703,14 +6750,14 @@ function createOpenRouter(options = {}) {
6703
6750
  });
6704
6751
  const createEmbeddingModel = (modelId, settings = {}) => new OpenRouterEmbeddingModel(modelId, settings, {
6705
6752
  provider: "openrouter.embedding",
6706
- url: ({ path: path45 }) => `${baseURL}${path45}`,
6753
+ url: ({ path: path47 }) => `${baseURL}${path47}`,
6707
6754
  headers: getHeaders,
6708
6755
  fetch: options.fetch,
6709
6756
  extraBody: options.extraBody
6710
6757
  });
6711
6758
  const createImageModel = (modelId, settings = {}) => new OpenRouterImageModel(modelId, settings, {
6712
6759
  provider: "openrouter.image",
6713
- url: ({ path: path45 }) => `${baseURL}${path45}`,
6760
+ url: ({ path: path47 }) => `${baseURL}${path47}`,
6714
6761
  headers: getHeaders,
6715
6762
  fetch: options.fetch,
6716
6763
  extraBody: options.extraBody
@@ -14210,52 +14257,60 @@ import { createWriteStream as createWriteStream4, existsSync, readdirSync } from
14210
14257
  import { arch, platform } from "node:os";
14211
14258
  import path14 from "node:path";
14212
14259
  import { fileURLToPath as fileURLToPath2 } from "node:url";
14260
+ import { readFile as readFile8 } from "node:fs/promises";
14261
+ import { homedir as homedir2 } from "node:os";
14262
+ import path17 from "node:path";
14263
+ import { readFile as readFile7, readdir, stat } from "node:fs/promises";
14264
+ import { homedir } from "node:os";
14265
+ import path16 from "node:path";
14266
+ import { parse as parseYaml22 } from "yaml";
14213
14267
  import { randomUUID as randomUUID6 } from "node:crypto";
14214
14268
  import { mkdir as mkdir5 } from "node:fs/promises";
14215
- import path16 from "node:path";
14269
+ import path18 from "node:path";
14216
14270
  import { spawn as spawn3 } from "node:child_process";
14217
14271
  import { randomUUID as randomUUID7 } from "node:crypto";
14218
14272
  import { createWriteStream as createWriteStream5 } from "node:fs";
14219
14273
  import { mkdir as mkdir6, mkdtemp, rm, writeFile } from "node:fs/promises";
14220
14274
  import { tmpdir } from "node:os";
14221
- import path17 from "node:path";
14275
+ import path19 from "node:path";
14222
14276
  import { execSync } from "node:child_process";
14223
14277
  import { randomUUID as randomUUID8 } from "node:crypto";
14224
- import { createWriteStream as createWriteStream6 } from "node:fs";
14278
+ import { accessSync, createWriteStream as createWriteStream6 } from "node:fs";
14225
14279
  import { mkdir as mkdir7 } from "node:fs/promises";
14226
- import path18 from "node:path";
14280
+ import path20 from "node:path";
14227
14281
  import { createInterface } from "node:readline";
14282
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
14228
14283
  import { exec as exec2 } from "node:child_process";
14229
- import { constants as constants3, access as access3, stat as stat4 } from "node:fs/promises";
14230
- import path30 from "node:path";
14284
+ import { constants as constants3, access as access3, stat as stat5 } from "node:fs/promises";
14285
+ import path322 from "node:path";
14231
14286
  import { promisify as promisify3 } from "node:util";
14232
- import { stat as stat3, writeFile as writeFile4 } from "node:fs/promises";
14233
- import path28 from "node:path";
14287
+ import { stat as stat4, writeFile as writeFile4 } from "node:fs/promises";
14288
+ import path30 from "node:path";
14234
14289
  import { constants as constants22 } from "node:fs";
14235
- import { access as access22, mkdir as mkdir8, readdir, rm as rm2, stat } from "node:fs/promises";
14236
- import path19 from "node:path";
14237
- import path20 from "node:path";
14290
+ import { access as access22, mkdir as mkdir8, readdir as readdir2, rm as rm2, stat as stat2 } from "node:fs/promises";
14238
14291
  import path21 from "node:path";
14239
- import { readFile as readFile7 } from "node:fs/promises";
14240
14292
  import path222 from "node:path";
14293
+ import path23 from "node:path";
14294
+ import { readFile as readFile9 } from "node:fs/promises";
14295
+ import path24 from "node:path";
14241
14296
  import { exec, spawn as spawn4 } from "node:child_process";
14242
14297
  import { mkdir as mkdir9, writeFile as writeFile2 } from "node:fs/promises";
14243
- import path25 from "node:path";
14244
- import { promisify as promisify2 } from "node:util";
14245
- import path24 from "node:path";
14246
- import os2 from "node:os";
14247
- import path23 from "node:path";
14248
- import { copyFile, mkdir as mkdir10, readFile as readFile8, readdir as readdir2, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
14249
14298
  import path27 from "node:path";
14299
+ import { promisify as promisify2 } from "node:util";
14250
14300
  import path26 from "node:path";
14301
+ import os2 from "node:os";
14302
+ import path25 from "node:path";
14303
+ import { copyFile, mkdir as mkdir10, readFile as readFile10, readdir as readdir3, stat as stat3, writeFile as writeFile3 } from "node:fs/promises";
14304
+ import path29 from "node:path";
14305
+ import path28 from "node:path";
14251
14306
  import JSON5 from "json5";
14252
14307
  import { writeFile as writeFile5 } from "node:fs/promises";
14253
- import path29 from "node:path";
14254
- import { constants as constants4 } from "node:fs";
14255
- import { access as access4, readFile as readFile9 } from "node:fs/promises";
14256
14308
  import path31 from "node:path";
14309
+ import { constants as constants4 } from "node:fs";
14310
+ import { access as access4, readFile as readFile11 } from "node:fs/promises";
14311
+ import path33 from "node:path";
14257
14312
  import { parse as parse4 } from "yaml";
14258
- import path322 from "node:path";
14313
+ import path34 from "node:path";
14259
14314
  import fg2 from "fast-glob";
14260
14315
  import { mkdtemp as mkdtemp2, rm as rm3, writeFile as writeFile6 } from "node:fs/promises";
14261
14316
  import { tmpdir as tmpdir2 } from "node:os";
@@ -14263,38 +14318,38 @@ import { dirname, join } from "node:path";
14263
14318
  import { randomBytes } from "node:crypto";
14264
14319
  import { createServer } from "node:http";
14265
14320
  import fs2 from "node:fs/promises";
14266
- import path33 from "node:path";
14321
+ import path35 from "node:path";
14267
14322
  import { createHash as createHash2, randomUUID as randomUUID9 } from "node:crypto";
14268
- import { copyFile as copyFile2, mkdir as mkdir14, readdir as readdir6, stat as stat7 } from "node:fs/promises";
14269
- import path422 from "node:path";
14323
+ import { copyFile as copyFile2, mkdir as mkdir14, readdir as readdir7, stat as stat8 } from "node:fs/promises";
14324
+ import path44 from "node:path";
14270
14325
  import micromatch3 from "micromatch";
14271
- import path34 from "node:path";
14272
- import path35 from "node:path";
14273
- import fg22 from "fast-glob";
14274
14326
  import path36 from "node:path";
14327
+ import path37 from "node:path";
14328
+ import fg22 from "fast-glob";
14329
+ import path38 from "node:path";
14275
14330
  import fg3 from "fast-glob";
14276
14331
  import { exec as execCallback } from "node:child_process";
14277
14332
  import { readdirSync as readdirSync2, statSync } from "node:fs";
14278
- import path37 from "node:path";
14333
+ import path39 from "node:path";
14279
14334
  import { promisify as promisify4 } from "node:util";
14280
- import { cp, mkdir as mkdir12, readdir as readdir3, rm as rm4, stat as stat5 } from "node:fs/promises";
14281
- import path38 from "node:path";
14335
+ import { cp, mkdir as mkdir12, readdir as readdir4, rm as rm4, stat as stat6 } from "node:fs/promises";
14336
+ import path40 from "node:path";
14282
14337
  import { execFile } from "node:child_process";
14283
14338
  import { createHash } from "node:crypto";
14284
14339
  import { existsSync as existsSync2 } from "node:fs";
14285
- import { cp as cp2, mkdir as mkdir13, readFile as readFile10, readdir as readdir4, rm as rm5, unlink, writeFile as writeFile7 } from "node:fs/promises";
14286
- import path39 from "node:path";
14340
+ import { cp as cp2, mkdir as mkdir13, readFile as readFile12, readdir as readdir5, rm as rm5, unlink, writeFile as writeFile7 } from "node:fs/promises";
14341
+ import path41 from "node:path";
14287
14342
  import { promisify as promisify5 } from "node:util";
14288
14343
  import { execFile as execFile2 } from "node:child_process";
14289
14344
  import { existsSync as existsSync3 } from "node:fs";
14290
- import path40 from "node:path";
14345
+ import path422 from "node:path";
14291
14346
  import { promisify as promisify6 } from "node:util";
14292
- import { readdir as readdir5, stat as stat6 } from "node:fs/promises";
14293
- import path41 from "node:path";
14294
- import { existsSync as existsSync4 } from "node:fs";
14347
+ import { readdir as readdir6, stat as stat7 } from "node:fs/promises";
14295
14348
  import path43 from "node:path";
14296
- import { mkdir as mkdir15, readFile as readFile11, writeFile as writeFile8 } from "node:fs/promises";
14297
- import path44 from "node:path";
14349
+ import { existsSync as existsSync4 } from "node:fs";
14350
+ import path45 from "node:path";
14351
+ import { mkdir as mkdir15, readFile as readFile13, writeFile as writeFile8 } from "node:fs/promises";
14352
+ import path46 from "node:path";
14298
14353
  function computeTraceSummary(messages) {
14299
14354
  const toolCallCounts = {};
14300
14355
  const toolDurations = {};
@@ -20541,6 +20596,249 @@ function summarizeAcpEvent(eventType, data) {
20541
20596
  return void 0;
20542
20597
  }
20543
20598
  }
20599
+ function parseCopilotEvents(eventsJsonl) {
20600
+ const messages = [];
20601
+ const meta = { sessionId: "", model: "", cwd: "" };
20602
+ let totalInputTokens = 0;
20603
+ let totalOutputTokens = 0;
20604
+ let hasUsage = false;
20605
+ let startTimestamp;
20606
+ let endTimestamp;
20607
+ const toolCallsInProgress = /* @__PURE__ */ new Map();
20608
+ const lines = eventsJsonl.split("\n").filter((l) => l.trim().length > 0);
20609
+ for (const line of lines) {
20610
+ let event;
20611
+ try {
20612
+ event = JSON.parse(line);
20613
+ } catch {
20614
+ continue;
20615
+ }
20616
+ const eventType = event.type;
20617
+ if (!eventType) continue;
20618
+ const data = event.data ?? {};
20619
+ switch (eventType) {
20620
+ case "session.start": {
20621
+ meta.sessionId = String(data.sessionId ?? "");
20622
+ const ctx = data.context;
20623
+ meta.cwd = String(ctx?.cwd ?? "");
20624
+ meta.repository = ctx?.repository ? String(ctx.repository) : void 0;
20625
+ meta.branch = ctx?.branch ? String(ctx.branch) : void 0;
20626
+ const ts = event.timestamp ?? data.startTime;
20627
+ meta.startedAt = ts ? String(ts) : void 0;
20628
+ startTimestamp = ts ? String(ts) : void 0;
20629
+ break;
20630
+ }
20631
+ case "user.message": {
20632
+ messages.push({
20633
+ role: "user",
20634
+ content: data.content != null ? String(data.content) : ""
20635
+ });
20636
+ break;
20637
+ }
20638
+ case "assistant.message": {
20639
+ const toolRequests = data.toolRequests;
20640
+ const toolCalls = (toolRequests ?? []).map((req) => ({
20641
+ tool: String(req.name ?? req.toolName ?? ""),
20642
+ input: req.arguments,
20643
+ id: req.toolCallId ? String(req.toolCallId) : void 0
20644
+ }));
20645
+ messages.push({
20646
+ role: "assistant",
20647
+ content: data.content != null ? String(data.content) : void 0,
20648
+ toolCalls: toolCalls.length > 0 ? toolCalls : void 0
20649
+ });
20650
+ break;
20651
+ }
20652
+ case "skill.invoked": {
20653
+ const skillName = String(data.name ?? "");
20654
+ messages.push({
20655
+ role: "assistant",
20656
+ toolCalls: [
20657
+ {
20658
+ tool: "Skill",
20659
+ input: { skill: skillName }
20660
+ }
20661
+ ]
20662
+ });
20663
+ break;
20664
+ }
20665
+ case "tool.execution_start": {
20666
+ const toolCallId = String(data.toolCallId ?? "");
20667
+ if (toolCallId) {
20668
+ toolCallsInProgress.set(toolCallId, {
20669
+ toolName: String(data.toolName ?? ""),
20670
+ input: data.arguments,
20671
+ toolCallId
20672
+ });
20673
+ }
20674
+ break;
20675
+ }
20676
+ case "tool.execution_complete": {
20677
+ const toolCallId = String(data.toolCallId ?? "");
20678
+ const started = toolCallsInProgress.get(toolCallId);
20679
+ if (started) {
20680
+ toolCallsInProgress.delete(toolCallId);
20681
+ messages.push({
20682
+ role: "assistant",
20683
+ toolCalls: [
20684
+ {
20685
+ tool: started.toolName,
20686
+ input: started.input,
20687
+ output: data.result,
20688
+ id: toolCallId
20689
+ }
20690
+ ]
20691
+ });
20692
+ }
20693
+ break;
20694
+ }
20695
+ case "session.shutdown": {
20696
+ endTimestamp = event.timestamp ? String(event.timestamp) : void 0;
20697
+ const modelMetrics = data.modelMetrics;
20698
+ if (modelMetrics) {
20699
+ for (const metrics of Object.values(modelMetrics)) {
20700
+ if (metrics.usage) {
20701
+ hasUsage = true;
20702
+ totalInputTokens += Number(metrics.usage.inputTokens ?? 0);
20703
+ totalOutputTokens += Number(metrics.usage.outputTokens ?? 0);
20704
+ }
20705
+ }
20706
+ }
20707
+ const currentModel = data.currentModel;
20708
+ if (currentModel && !meta.model) {
20709
+ meta.model = String(currentModel);
20710
+ }
20711
+ break;
20712
+ }
20713
+ }
20714
+ }
20715
+ let durationMs;
20716
+ if (startTimestamp && endTimestamp) {
20717
+ durationMs = new Date(endTimestamp).getTime() - new Date(startTimestamp).getTime();
20718
+ }
20719
+ return {
20720
+ messages,
20721
+ meta,
20722
+ tokenUsage: hasUsage ? { input: totalInputTokens, output: totalOutputTokens } : void 0,
20723
+ durationMs
20724
+ };
20725
+ }
20726
+ var DEFAULT_SESSION_STATE_DIR = () => path16.join(homedir(), ".copilot", "session-state");
20727
+ async function discoverCopilotSessions(opts) {
20728
+ const sessionStateDir = opts?.sessionStateDir ?? DEFAULT_SESSION_STATE_DIR();
20729
+ const limit = opts?.limit ?? 10;
20730
+ let entries;
20731
+ try {
20732
+ entries = await readdir(sessionStateDir);
20733
+ } catch {
20734
+ return [];
20735
+ }
20736
+ const sessions = [];
20737
+ for (const entry of entries) {
20738
+ const sessionDir = path16.join(sessionStateDir, entry);
20739
+ const workspacePath = path16.join(sessionDir, "workspace.yaml");
20740
+ const eventsPath = path16.join(sessionDir, "events.jsonl");
20741
+ try {
20742
+ const workspaceContent = await readFile7(workspacePath, "utf8");
20743
+ const workspace = parseYaml22(workspaceContent) ?? {};
20744
+ const cwd = String(workspace.cwd ?? "");
20745
+ let updatedAt;
20746
+ try {
20747
+ const eventsStat = await stat(eventsPath);
20748
+ updatedAt = eventsStat.mtime;
20749
+ } catch {
20750
+ updatedAt = /* @__PURE__ */ new Date(0);
20751
+ }
20752
+ let isActive = true;
20753
+ try {
20754
+ const fd = await import("node:fs/promises").then((fs3) => fs3.open(eventsPath, "r"));
20755
+ try {
20756
+ const fstat = await fd.stat();
20757
+ const tailSize = Math.min(fstat.size, 4096);
20758
+ const buf = Buffer.alloc(tailSize);
20759
+ await fd.read(buf, 0, tailSize, Math.max(0, fstat.size - tailSize));
20760
+ isActive = !buf.toString("utf8").includes('"session.shutdown"');
20761
+ } finally {
20762
+ await fd.close();
20763
+ }
20764
+ } catch {
20765
+ }
20766
+ sessions.push({
20767
+ sessionId: entry,
20768
+ sessionDir,
20769
+ cwd,
20770
+ repository: workspace.repository ? String(workspace.repository) : void 0,
20771
+ updatedAt,
20772
+ isActive
20773
+ });
20774
+ } catch {
20775
+ }
20776
+ }
20777
+ let filtered = sessions;
20778
+ if (opts?.cwd) {
20779
+ filtered = filtered.filter((s) => s.cwd === opts.cwd);
20780
+ }
20781
+ if (opts?.repository) {
20782
+ filtered = filtered.filter((s) => s.repository === opts.repository);
20783
+ }
20784
+ filtered.sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime());
20785
+ return filtered.slice(0, limit);
20786
+ }
20787
+ var CopilotLogProvider = class {
20788
+ id;
20789
+ kind = "copilot-log";
20790
+ targetName;
20791
+ config;
20792
+ constructor(targetName, config) {
20793
+ this.targetName = targetName;
20794
+ this.id = `copilot-log:${targetName}`;
20795
+ this.config = config;
20796
+ }
20797
+ async invoke(_request) {
20798
+ const sessionDir = await this.resolveSessionDir();
20799
+ const eventsPath = path17.join(sessionDir, "events.jsonl");
20800
+ let eventsContent;
20801
+ try {
20802
+ eventsContent = await readFile8(eventsPath, "utf8");
20803
+ } catch (err) {
20804
+ throw new Error(
20805
+ `Failed to read Copilot session transcript at ${eventsPath}: ${err instanceof Error ? err.message : String(err)}`
20806
+ );
20807
+ }
20808
+ const parsed = parseCopilotEvents(eventsContent);
20809
+ return {
20810
+ output: parsed.messages,
20811
+ tokenUsage: parsed.tokenUsage,
20812
+ durationMs: parsed.durationMs,
20813
+ startTime: parsed.meta.startedAt
20814
+ };
20815
+ }
20816
+ async resolveSessionDir() {
20817
+ if (this.config.sessionDir) {
20818
+ return this.config.sessionDir;
20819
+ }
20820
+ if (this.config.sessionId) {
20821
+ const stateDir = this.config.sessionStateDir ?? path17.join(homedir2(), ".copilot", "session-state");
20822
+ return path17.join(stateDir, this.config.sessionId);
20823
+ }
20824
+ if (this.config.discover === "latest") {
20825
+ const sessions = await discoverCopilotSessions({
20826
+ sessionStateDir: this.config.sessionStateDir,
20827
+ cwd: this.config.cwd,
20828
+ limit: 1
20829
+ });
20830
+ if (sessions.length === 0) {
20831
+ throw new Error(
20832
+ `No Copilot CLI sessions found${this.config.cwd ? ` for cwd=${this.config.cwd}` : ""}. Check that sessions exist in ${this.config.sessionStateDir ?? "~/.copilot/session-state/"}`
20833
+ );
20834
+ }
20835
+ return sessions[0].sessionDir;
20836
+ }
20837
+ throw new Error(
20838
+ 'CopilotLogProvider requires one of: sessionDir, sessionId, or discover="latest"'
20839
+ );
20840
+ }
20841
+ };
20544
20842
  var GLOBAL_LOGS_KEY4 = Symbol.for("agentv.copilotSdkLogs");
20545
20843
  var GLOBAL_SUBSCRIBERS_KEY4 = Symbol.for("agentv.copilotSdkLogSubscribers");
20546
20844
  function getCopilotSdkLogStore() {
@@ -20826,10 +21124,10 @@ var CopilotSdkProvider = class {
20826
21124
  }
20827
21125
  resolveCwd(cwdOverride) {
20828
21126
  if (cwdOverride) {
20829
- return path16.resolve(cwdOverride);
21127
+ return path18.resolve(cwdOverride);
20830
21128
  }
20831
21129
  if (this.config.cwd) {
20832
- return path16.resolve(this.config.cwd);
21130
+ return path18.resolve(this.config.cwd);
20833
21131
  }
20834
21132
  return void 0;
20835
21133
  }
@@ -20838,9 +21136,9 @@ var CopilotSdkProvider = class {
20838
21136
  return void 0;
20839
21137
  }
20840
21138
  if (this.config.logDir) {
20841
- return path16.resolve(this.config.logDir);
21139
+ return path18.resolve(this.config.logDir);
20842
21140
  }
20843
- return path16.join(process.cwd(), ".agentv", "logs", "copilot-sdk");
21141
+ return path18.join(process.cwd(), ".agentv", "logs", "copilot-sdk");
20844
21142
  }
20845
21143
  async createStreamLogger(request) {
20846
21144
  const logDir = this.resolveLogDirectory();
@@ -20854,7 +21152,7 @@ var CopilotSdkProvider = class {
20854
21152
  console.warn(`Skipping Copilot SDK stream logging (could not create ${logDir}): ${message}`);
20855
21153
  return void 0;
20856
21154
  }
20857
- const filePath = path16.join(logDir, buildLogFilename4(request, this.targetName, "copilot-sdk"));
21155
+ const filePath = path18.join(logDir, buildLogFilename4(request, this.targetName, "copilot-sdk"));
20858
21156
  try {
20859
21157
  const logger = await CopilotStreamLogger.create(
20860
21158
  {
@@ -21038,13 +21336,14 @@ var PiCliProvider = class {
21038
21336
  const inputFiles = normalizeInputFiles(request.inputFiles);
21039
21337
  const startTime = (/* @__PURE__ */ new Date()).toISOString();
21040
21338
  const startMs = Date.now();
21041
- const workspaceRoot = await this.createWorkspace();
21339
+ const hasExternalCwd = !!(request.cwd || this.config.cwd);
21340
+ const workspaceRoot = hasExternalCwd ? void 0 : await this.createWorkspace();
21341
+ const cwd = this.resolveCwd(workspaceRoot, request.cwd);
21042
21342
  const logger = await this.createStreamLogger(request).catch(() => void 0);
21043
21343
  try {
21044
- const promptFile = path17.join(workspaceRoot, PROMPT_FILENAME);
21344
+ const promptFile = path19.join(cwd, PROMPT_FILENAME);
21045
21345
  await writeFile(promptFile, request.question, "utf8");
21046
21346
  const args = this.buildPiArgs(request.question, inputFiles);
21047
- const cwd = this.resolveCwd(workspaceRoot, request.cwd);
21048
21347
  const result = await this.executePi(args, cwd, request.signal, logger);
21049
21348
  if (result.timedOut) {
21050
21349
  throw new Error(
@@ -21086,7 +21385,7 @@ var PiCliProvider = class {
21086
21385
  args,
21087
21386
  executable: this.config.executable,
21088
21387
  promptFile,
21089
- workspace: workspaceRoot,
21388
+ workspace: workspaceRoot ?? cwd,
21090
21389
  inputFiles,
21091
21390
  logFile: logger?.filePath
21092
21391
  },
@@ -21098,17 +21397,22 @@ var PiCliProvider = class {
21098
21397
  };
21099
21398
  } finally {
21100
21399
  await logger?.close();
21101
- await this.cleanupWorkspace(workspaceRoot);
21400
+ if (workspaceRoot) {
21401
+ await this.cleanupWorkspace(workspaceRoot);
21402
+ }
21102
21403
  }
21103
21404
  }
21104
21405
  resolveCwd(workspaceRoot, cwdOverride) {
21105
21406
  if (cwdOverride) {
21106
- return path17.resolve(cwdOverride);
21407
+ return path19.resolve(cwdOverride);
21408
+ }
21409
+ if (this.config.cwd) {
21410
+ return path19.resolve(this.config.cwd);
21107
21411
  }
21108
- if (!this.config.cwd) {
21412
+ if (workspaceRoot) {
21109
21413
  return workspaceRoot;
21110
21414
  }
21111
- return path17.resolve(this.config.cwd);
21415
+ return process.cwd();
21112
21416
  }
21113
21417
  buildPiArgs(prompt, inputFiles) {
21114
21418
  const args = [];
@@ -21189,7 +21493,7 @@ ${prompt}` : prompt;
21189
21493
  return env;
21190
21494
  }
21191
21495
  async createWorkspace() {
21192
- return await mkdtemp(path17.join(tmpdir(), WORKSPACE_PREFIX));
21496
+ return await mkdtemp(path19.join(tmpdir(), WORKSPACE_PREFIX));
21193
21497
  }
21194
21498
  async cleanupWorkspace(workspaceRoot) {
21195
21499
  try {
@@ -21199,9 +21503,9 @@ ${prompt}` : prompt;
21199
21503
  }
21200
21504
  resolveLogDirectory() {
21201
21505
  if (this.config.logDir) {
21202
- return path17.resolve(this.config.logDir);
21506
+ return path19.resolve(this.config.logDir);
21203
21507
  }
21204
- return path17.join(process.cwd(), ".agentv", "logs", "pi-cli");
21508
+ return path19.join(process.cwd(), ".agentv", "logs", "pi-cli");
21205
21509
  }
21206
21510
  async createStreamLogger(request) {
21207
21511
  const logDir = this.resolveLogDirectory();
@@ -21215,7 +21519,7 @@ ${prompt}` : prompt;
21215
21519
  console.warn(`Skipping Pi stream logging (could not create ${logDir}): ${message}`);
21216
21520
  return void 0;
21217
21521
  }
21218
- const filePath = path17.join(logDir, buildLogFilename5(request, this.targetName));
21522
+ const filePath = path19.join(logDir, buildLogFilename5(request, this.targetName));
21219
21523
  try {
21220
21524
  const logger = await PiStreamLogger.create({
21221
21525
  filePath,
@@ -21652,9 +21956,10 @@ async function defaultPiRunner(options) {
21652
21956
  }
21653
21957
  var piCodingAgentModule = null;
21654
21958
  var piAiModule = null;
21959
+ var loadingPromise = null;
21655
21960
  async function promptInstall() {
21656
21961
  if (!process.stdout.isTTY) return false;
21657
- const rl = createInterface({ input: process.stdin, output: process.stderr });
21962
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
21658
21963
  try {
21659
21964
  return await new Promise((resolve2) => {
21660
21965
  rl.question(
@@ -21666,43 +21971,74 @@ async function promptInstall() {
21666
21971
  rl.close();
21667
21972
  }
21668
21973
  }
21669
- async function loadSdkModules() {
21670
- if (!piCodingAgentModule || !piAiModule) {
21974
+ function findAgentvRoot() {
21975
+ const thisFile = fileURLToPath3(import.meta.url);
21976
+ let dir = path20.dirname(thisFile);
21977
+ for (let i = 0; i < 10; i++) {
21671
21978
  try {
21979
+ const pkg = path20.join(dir, "package.json");
21980
+ accessSync(pkg);
21981
+ return dir;
21982
+ } catch {
21983
+ const parent = path20.dirname(dir);
21984
+ if (parent === dir) break;
21985
+ dir = parent;
21986
+ }
21987
+ }
21988
+ return path20.dirname(thisFile);
21989
+ }
21990
+ async function doLoadSdkModules() {
21991
+ try {
21992
+ [piCodingAgentModule, piAiModule] = await Promise.all([
21993
+ import("@mariozechner/pi-coding-agent"),
21994
+ import("@mariozechner/pi-ai")
21995
+ ]);
21996
+ } catch {
21997
+ if (await promptInstall()) {
21998
+ const installDir = findAgentvRoot();
21999
+ console.error(`Installing @mariozechner/pi-coding-agent into ${installDir}...`);
22000
+ execSync("bun add @mariozechner/pi-coding-agent", {
22001
+ cwd: installDir,
22002
+ stdio: "inherit"
22003
+ });
21672
22004
  [piCodingAgentModule, piAiModule] = await Promise.all([
21673
22005
  import("@mariozechner/pi-coding-agent"),
21674
22006
  import("@mariozechner/pi-ai")
21675
22007
  ]);
21676
- } catch {
21677
- if (await promptInstall()) {
21678
- console.error("Installing @mariozechner/pi-coding-agent...");
21679
- execSync("bun add @mariozechner/pi-coding-agent", { stdio: "inherit" });
21680
- [piCodingAgentModule, piAiModule] = await Promise.all([
21681
- import("@mariozechner/pi-coding-agent"),
21682
- import("@mariozechner/pi-ai")
21683
- ]);
21684
- } else {
21685
- throw new Error(
21686
- "pi-coding-agent SDK is not installed. Install it with:\n bun add @mariozechner/pi-coding-agent"
21687
- );
21688
- }
22008
+ } else {
22009
+ throw new Error(
22010
+ "pi-coding-agent SDK is not installed. Install it with:\n bun add @mariozechner/pi-coding-agent"
22011
+ );
21689
22012
  }
21690
22013
  }
22014
+ }
22015
+ async function loadSdkModules() {
22016
+ if (!piCodingAgentModule || !piAiModule) {
22017
+ if (!loadingPromise) {
22018
+ loadingPromise = doLoadSdkModules().catch((err) => {
22019
+ loadingPromise = null;
22020
+ throw err;
22021
+ });
22022
+ }
22023
+ await loadingPromise;
22024
+ }
22025
+ const piSdk = piCodingAgentModule;
22026
+ const piAi = piAiModule;
21691
22027
  const toolMap = {
21692
- read: piCodingAgentModule.readTool,
21693
- bash: piCodingAgentModule.bashTool,
21694
- edit: piCodingAgentModule.editTool,
21695
- write: piCodingAgentModule.writeTool,
21696
- grep: piCodingAgentModule.grepTool,
21697
- find: piCodingAgentModule.findTool,
21698
- ls: piCodingAgentModule.lsTool
22028
+ read: piSdk.readTool,
22029
+ bash: piSdk.bashTool,
22030
+ edit: piSdk.editTool,
22031
+ write: piSdk.writeTool,
22032
+ grep: piSdk.grepTool,
22033
+ find: piSdk.findTool,
22034
+ ls: piSdk.lsTool
21699
22035
  };
21700
22036
  return {
21701
- createAgentSession: piCodingAgentModule.createAgentSession,
21702
- codingTools: piCodingAgentModule.codingTools,
22037
+ createAgentSession: piSdk.createAgentSession,
22038
+ codingTools: piSdk.codingTools,
21703
22039
  toolMap,
21704
- SessionManager: piCodingAgentModule.SessionManager,
21705
- getModel: piAiModule.getModel
22040
+ SessionManager: piSdk.SessionManager,
22041
+ getModel: piAi.getModel
21706
22042
  };
21707
22043
  }
21708
22044
  var PiCodingAgentProvider = class {
@@ -21891,10 +22227,10 @@ ${fileList}`;
21891
22227
  }
21892
22228
  resolveCwd(cwdOverride) {
21893
22229
  if (cwdOverride) {
21894
- return path18.resolve(cwdOverride);
22230
+ return path20.resolve(cwdOverride);
21895
22231
  }
21896
22232
  if (this.config.cwd) {
21897
- return path18.resolve(this.config.cwd);
22233
+ return path20.resolve(this.config.cwd);
21898
22234
  }
21899
22235
  return process.cwd();
21900
22236
  }
@@ -21913,9 +22249,9 @@ ${fileList}`;
21913
22249
  }
21914
22250
  resolveLogDirectory() {
21915
22251
  if (this.config.logDir) {
21916
- return path18.resolve(this.config.logDir);
22252
+ return path20.resolve(this.config.logDir);
21917
22253
  }
21918
- return path18.join(process.cwd(), ".agentv", "logs", "pi-coding-agent");
22254
+ return path20.join(process.cwd(), ".agentv", "logs", "pi-coding-agent");
21919
22255
  }
21920
22256
  async createStreamLogger(request) {
21921
22257
  const logDir = this.resolveLogDirectory();
@@ -21929,7 +22265,7 @@ ${fileList}`;
21929
22265
  console.warn(`Skipping Pi stream logging (could not create ${logDir}): ${message}`);
21930
22266
  return void 0;
21931
22267
  }
21932
- const filePath = path18.join(logDir, buildLogFilename6(request, this.targetName));
22268
+ const filePath = path20.join(logDir, buildLogFilename6(request, this.targetName));
21933
22269
  try {
21934
22270
  const logger = await PiStreamLogger2.create({
21935
22271
  filePath,
@@ -22149,10 +22485,10 @@ async function ensureDir(target) {
22149
22485
  await mkdir8(target, { recursive: true });
22150
22486
  }
22151
22487
  async function readDirEntries(target) {
22152
- const entries = await readdir(target, { withFileTypes: true });
22488
+ const entries = await readdir2(target, { withFileTypes: true });
22153
22489
  return entries.map((entry) => ({
22154
22490
  name: entry.name,
22155
- absolutePath: path19.join(target, entry.name),
22491
+ absolutePath: path21.join(target, entry.name),
22156
22492
  isDirectory: entry.isDirectory()
22157
22493
  }));
22158
22494
  }
@@ -22166,7 +22502,7 @@ async function removeIfExists(target) {
22166
22502
  }
22167
22503
  }
22168
22504
  function pathToFileUri2(filePath) {
22169
- const absolutePath = path20.isAbsolute(filePath) ? filePath : path20.resolve(filePath);
22505
+ const absolutePath = path222.isAbsolute(filePath) ? filePath : path222.resolve(filePath);
22170
22506
  const normalizedPath = absolutePath.replace(/\\/g, "/");
22171
22507
  if (/^[a-zA-Z]:\//.test(normalizedPath)) {
22172
22508
  return `file:///${normalizedPath}`;
@@ -22258,8 +22594,8 @@ function createBatchRequestPrompt(userQuery, responseFileTmp, responseFileFinal,
22258
22594
  });
22259
22595
  }
22260
22596
  function createBatchOrchestratorPrompt(requestFiles, responseFiles, templateContent) {
22261
- const requestLines = requestFiles.map((file, index) => `${index + 1}. messages/${path21.basename(file)}`).join("\n");
22262
- const responseList = responseFiles.map((file) => `"${path21.basename(file)}"`).join(", ");
22597
+ const requestLines = requestFiles.map((file, index) => `${index + 1}. messages/${path23.basename(file)}`).join("\n");
22598
+ const responseList = responseFiles.map((file) => `"${path23.basename(file)}"`).join(", ");
22263
22599
  return renderTemplate2(templateContent, {
22264
22600
  requestFiles: requestLines,
22265
22601
  responseList
@@ -22298,7 +22634,7 @@ async function waitForResponseOutput(responseFileFinal, pollInterval = 1e3, sile
22298
22634
  const maxAttempts = 10;
22299
22635
  while (attempts < maxAttempts) {
22300
22636
  try {
22301
- const content = await readFile7(responseFileFinal, { encoding: "utf8" });
22637
+ const content = await readFile9(responseFileFinal, { encoding: "utf8" });
22302
22638
  if (!silent) {
22303
22639
  process.stdout.write(`${content}
22304
22640
  `);
@@ -22319,7 +22655,7 @@ async function waitForResponseOutput(responseFileFinal, pollInterval = 1e3, sile
22319
22655
  }
22320
22656
  async function waitForBatchResponses(responseFilesFinal, pollInterval = 1e3, silent = false, timeoutMs = DEFAULT_TIMEOUT_MS) {
22321
22657
  if (!silent) {
22322
- const fileList = responseFilesFinal.map((file) => path222.basename(file)).join(", ");
22658
+ const fileList = responseFilesFinal.map((file) => path24.basename(file)).join(", ");
22323
22659
  console.error(`waiting for ${responseFilesFinal.length} batch response(s): ${fileList}`);
22324
22660
  }
22325
22661
  const deadline = Date.now() + timeoutMs;
@@ -22328,7 +22664,7 @@ async function waitForBatchResponses(responseFilesFinal, pollInterval = 1e3, sil
22328
22664
  while (pending.size > 0) {
22329
22665
  if (Date.now() >= deadline) {
22330
22666
  if (!silent) {
22331
- const remaining = [...pending].map((f) => path222.basename(f)).join(", ");
22667
+ const remaining = [...pending].map((f) => path24.basename(f)).join(", ");
22332
22668
  console.error(
22333
22669
  `error: timed out after ${Math.round(timeoutMs / 1e3)}s waiting for batch responses. Still pending: ${remaining}`
22334
22670
  );
@@ -22355,7 +22691,7 @@ async function waitForBatchResponses(responseFilesFinal, pollInterval = 1e3, sil
22355
22691
  const maxAttempts = 10;
22356
22692
  while (attempts < maxAttempts) {
22357
22693
  try {
22358
- const content = await readFile7(file, { encoding: "utf8" });
22694
+ const content = await readFile9(file, { encoding: "utf8" });
22359
22695
  if (!silent) {
22360
22696
  process.stdout.write(`${content}
22361
22697
  `);
@@ -22385,25 +22721,25 @@ function getAgentvHome() {
22385
22721
  }
22386
22722
  return envHome;
22387
22723
  }
22388
- return path23.join(os2.homedir(), ".agentv");
22724
+ return path25.join(os2.homedir(), ".agentv");
22389
22725
  }
22390
22726
  function getWorkspacesRoot() {
22391
- return path23.join(getAgentvHome(), "workspaces");
22727
+ return path25.join(getAgentvHome(), "workspaces");
22392
22728
  }
22393
22729
  function getSubagentsRoot() {
22394
- return path23.join(getAgentvHome(), "subagents");
22730
+ return path25.join(getAgentvHome(), "subagents");
22395
22731
  }
22396
22732
  function getTraceStateRoot() {
22397
- return path23.join(getAgentvHome(), "trace-state");
22733
+ return path25.join(getAgentvHome(), "trace-state");
22398
22734
  }
22399
22735
  function getWorkspacePoolRoot() {
22400
- return path23.join(getAgentvHome(), "workspace-pool");
22736
+ return path25.join(getAgentvHome(), "workspace-pool");
22401
22737
  }
22402
22738
  var DEFAULT_LOCK_NAME = "subagent.lock";
22403
22739
  var DEFAULT_ALIVE_FILENAME = ".alive";
22404
22740
  function getDefaultSubagentRoot(vscodeCmd = "code") {
22405
22741
  const folder = vscodeCmd === "code-insiders" ? "vscode-insiders-agents" : "vscode-agents";
22406
- return path24.join(getSubagentsRoot(), folder);
22742
+ return path26.join(getSubagentsRoot(), folder);
22407
22743
  }
22408
22744
  var DEFAULT_SUBAGENT_ROOT = getDefaultSubagentRoot();
22409
22745
  var execAsync2 = promisify2(exec);
@@ -22468,11 +22804,11 @@ async function ensureWorkspaceFocused(workspacePath, workspaceName, subagentDir,
22468
22804
  await raceSpawnError(child);
22469
22805
  return true;
22470
22806
  }
22471
- const aliveFile = path25.join(subagentDir, DEFAULT_ALIVE_FILENAME);
22807
+ const aliveFile = path27.join(subagentDir, DEFAULT_ALIVE_FILENAME);
22472
22808
  await removeIfExists(aliveFile);
22473
- const githubAgentsDir = path25.join(subagentDir, ".github", "agents");
22809
+ const githubAgentsDir = path27.join(subagentDir, ".github", "agents");
22474
22810
  await mkdir9(githubAgentsDir, { recursive: true });
22475
- const wakeupDst = path25.join(githubAgentsDir, "wakeup.md");
22811
+ const wakeupDst = path27.join(githubAgentsDir, "wakeup.md");
22476
22812
  await writeFile2(wakeupDst, DEFAULT_WAKEUP_CONTENT, "utf8");
22477
22813
  const workspaceChild = spawnVsCode(vscodeCmd, [workspacePath], {
22478
22814
  label: "open-workspace"
@@ -22485,7 +22821,7 @@ async function ensureWorkspaceFocused(workspacePath, workspaceName, subagentDir,
22485
22821
  "chat",
22486
22822
  "-m",
22487
22823
  wakeupChatId,
22488
- `create a file named .alive in the ${path25.basename(subagentDir)} folder`
22824
+ `create a file named .alive in the ${path27.basename(subagentDir)} folder`
22489
22825
  ];
22490
22826
  const wakeupChild = spawnVsCode(vscodeCmd, chatArgs, { label: "send-wakeup-chat" });
22491
22827
  await raceSpawnError(wakeupChild);
@@ -22500,10 +22836,10 @@ async function ensureWorkspaceFocused(workspacePath, workspaceName, subagentDir,
22500
22836
  return true;
22501
22837
  }
22502
22838
  async function launchVsCodeWithChat(subagentDir, chatId, attachmentPaths, requestInstructions, timestamp, vscodeCmd) {
22503
- const workspacePath = path25.join(subagentDir, `${path25.basename(subagentDir)}.code-workspace`);
22504
- const messagesDir = path25.join(subagentDir, "messages");
22839
+ const workspacePath = path27.join(subagentDir, `${path27.basename(subagentDir)}.code-workspace`);
22840
+ const messagesDir = path27.join(subagentDir, "messages");
22505
22841
  await mkdir9(messagesDir, { recursive: true });
22506
- const reqFile = path25.join(messagesDir, `${timestamp}_req.md`);
22842
+ const reqFile = path27.join(messagesDir, `${timestamp}_req.md`);
22507
22843
  await writeFile2(reqFile, requestInstructions, { encoding: "utf8" });
22508
22844
  const reqUri = pathToFileUri2(reqFile);
22509
22845
  const chatArgs = ["-r", "chat", "-m", chatId];
@@ -22511,16 +22847,16 @@ async function launchVsCodeWithChat(subagentDir, chatId, attachmentPaths, reques
22511
22847
  chatArgs.push("-a", attachment);
22512
22848
  }
22513
22849
  chatArgs.push("-a", reqFile);
22514
- chatArgs.push(`Follow instructions in [${path25.basename(reqFile)}](${reqUri})`);
22850
+ chatArgs.push(`Follow instructions in [${path27.basename(reqFile)}](${reqUri})`);
22515
22851
  const workspaceReady = await ensureWorkspaceFocused(
22516
22852
  workspacePath,
22517
- path25.basename(subagentDir),
22853
+ path27.basename(subagentDir),
22518
22854
  subagentDir,
22519
22855
  vscodeCmd
22520
22856
  );
22521
22857
  if (!workspaceReady) {
22522
22858
  throw new Error(
22523
- `VS Code workspace '${path25.basename(subagentDir)}' failed to become ready within the timeout. Check that '${vscodeCmd}' can open workspaces.`
22859
+ `VS Code workspace '${path27.basename(subagentDir)}' failed to become ready within the timeout. Check that '${vscodeCmd}' can open workspaces.`
22524
22860
  );
22525
22861
  }
22526
22862
  await sleep2(500);
@@ -22528,8 +22864,8 @@ async function launchVsCodeWithChat(subagentDir, chatId, attachmentPaths, reques
22528
22864
  await raceSpawnError(child);
22529
22865
  }
22530
22866
  async function launchVsCodeWithBatchChat(subagentDir, chatId, attachmentPaths, chatInstruction, vscodeCmd) {
22531
- const workspacePath = path25.join(subagentDir, `${path25.basename(subagentDir)}.code-workspace`);
22532
- const messagesDir = path25.join(subagentDir, "messages");
22867
+ const workspacePath = path27.join(subagentDir, `${path27.basename(subagentDir)}.code-workspace`);
22868
+ const messagesDir = path27.join(subagentDir, "messages");
22533
22869
  await mkdir9(messagesDir, { recursive: true });
22534
22870
  const chatArgs = ["-r", "chat", "-m", chatId];
22535
22871
  for (const attachment of attachmentPaths) {
@@ -22538,13 +22874,13 @@ async function launchVsCodeWithBatchChat(subagentDir, chatId, attachmentPaths, c
22538
22874
  chatArgs.push(chatInstruction);
22539
22875
  const workspaceReady = await ensureWorkspaceFocused(
22540
22876
  workspacePath,
22541
- path25.basename(subagentDir),
22877
+ path27.basename(subagentDir),
22542
22878
  subagentDir,
22543
22879
  vscodeCmd
22544
22880
  );
22545
22881
  if (!workspaceReady) {
22546
22882
  throw new Error(
22547
- `VS Code workspace '${path25.basename(subagentDir)}' failed to become ready within the timeout. Check that '${vscodeCmd}' can open workspaces.`
22883
+ `VS Code workspace '${path27.basename(subagentDir)}' failed to become ready within the timeout. Check that '${vscodeCmd}' can open workspaces.`
22548
22884
  );
22549
22885
  }
22550
22886
  await sleep2(500);
@@ -22566,10 +22902,10 @@ function transformWorkspacePaths(workspaceContent, templateDir) {
22566
22902
  }
22567
22903
  const transformedFolders = workspace.folders.map((folder) => {
22568
22904
  const folderPath = folder.path;
22569
- if (path26.isAbsolute(folderPath)) {
22905
+ if (path28.isAbsolute(folderPath)) {
22570
22906
  return folder;
22571
22907
  }
22572
- const absolutePath = path26.resolve(templateDir, folderPath);
22908
+ const absolutePath = path28.resolve(templateDir, folderPath);
22573
22909
  return {
22574
22910
  ...folder,
22575
22911
  path: absolutePath
@@ -22591,19 +22927,19 @@ function transformWorkspacePaths(workspaceContent, templateDir) {
22591
22927
  if (locationMap && typeof locationMap === "object") {
22592
22928
  const transformedMap = {};
22593
22929
  for (const [locationPath, value] of Object.entries(locationMap)) {
22594
- const isAbsolute = path26.isAbsolute(locationPath);
22930
+ const isAbsolute = path28.isAbsolute(locationPath);
22595
22931
  if (isAbsolute) {
22596
22932
  transformedMap[locationPath] = value;
22597
22933
  } else {
22598
22934
  const firstGlobIndex = locationPath.search(/[*]/);
22599
22935
  if (firstGlobIndex === -1) {
22600
- const resolvedPath = path26.resolve(templateDir, locationPath).replace(/\\/g, "/");
22936
+ const resolvedPath = path28.resolve(templateDir, locationPath).replace(/\\/g, "/");
22601
22937
  transformedMap[resolvedPath] = value;
22602
22938
  } else {
22603
22939
  const basePathEnd = locationPath.lastIndexOf("/", firstGlobIndex);
22604
22940
  const basePath = basePathEnd !== -1 ? locationPath.substring(0, basePathEnd) : ".";
22605
22941
  const patternPath = locationPath.substring(basePathEnd !== -1 ? basePathEnd : 0);
22606
- const resolvedPath = (path26.resolve(templateDir, basePath) + patternPath).replace(
22942
+ const resolvedPath = (path28.resolve(templateDir, basePath) + patternPath).replace(
22607
22943
  /\\/g,
22608
22944
  "/"
22609
22945
  );
@@ -22642,7 +22978,7 @@ async function findUnlockedSubagent(subagentRoot) {
22642
22978
  number: Number.parseInt(entry.name.split("-")[1] ?? "", 10)
22643
22979
  })).filter((entry) => Number.isInteger(entry.number)).sort((a, b) => a.number - b.number);
22644
22980
  for (const subagent of subagents) {
22645
- const lockFile = path27.join(subagent.absolutePath, DEFAULT_LOCK_NAME);
22981
+ const lockFile = path29.join(subagent.absolutePath, DEFAULT_LOCK_NAME);
22646
22982
  if (!await pathExists(lockFile)) {
22647
22983
  return subagent.absolutePath;
22648
22984
  }
@@ -22652,26 +22988,26 @@ async function findUnlockedSubagent(subagentRoot) {
22652
22988
  async function copyAgentConfig(subagentDir, workspaceTemplate, cwd) {
22653
22989
  let workspaceContent;
22654
22990
  if (workspaceTemplate) {
22655
- const workspaceSrc = path27.resolve(workspaceTemplate);
22991
+ const workspaceSrc = path29.resolve(workspaceTemplate);
22656
22992
  if (!await pathExists(workspaceSrc)) {
22657
22993
  throw new Error(`workspace template not found: ${workspaceSrc}`);
22658
22994
  }
22659
- const stats = await stat2(workspaceSrc);
22995
+ const stats = await stat3(workspaceSrc);
22660
22996
  if (!stats.isFile()) {
22661
22997
  throw new Error(`workspace template must be a file, not a directory: ${workspaceSrc}`);
22662
22998
  }
22663
- const templateText = await readFile8(workspaceSrc, "utf8");
22999
+ const templateText = await readFile10(workspaceSrc, "utf8");
22664
23000
  workspaceContent = JSON.parse(templateText);
22665
23001
  } else {
22666
23002
  workspaceContent = DEFAULT_WORKSPACE_TEMPLATE;
22667
23003
  }
22668
- const workspaceName = `${path27.basename(subagentDir)}.code-workspace`;
22669
- const workspaceDst = path27.join(subagentDir, workspaceName);
22670
- const templateDir = workspaceTemplate ? path27.dirname(path27.resolve(workspaceTemplate)) : subagentDir;
23004
+ const workspaceName = `${path29.basename(subagentDir)}.code-workspace`;
23005
+ const workspaceDst = path29.join(subagentDir, workspaceName);
23006
+ const templateDir = workspaceTemplate ? path29.dirname(path29.resolve(workspaceTemplate)) : subagentDir;
22671
23007
  const workspaceJson = JSON.stringify(workspaceContent, null, 2);
22672
23008
  let transformedContent = transformWorkspacePaths(workspaceJson, templateDir);
22673
23009
  if (cwd) {
22674
- const absCwd = path27.resolve(cwd);
23010
+ const absCwd = path29.resolve(cwd);
22675
23011
  const parsed = JSON.parse(transformedContent);
22676
23012
  const alreadyPresent = parsed.folders.some((f) => f.path === absCwd);
22677
23013
  if (!alreadyPresent) {
@@ -22680,35 +23016,35 @@ async function copyAgentConfig(subagentDir, workspaceTemplate, cwd) {
22680
23016
  }
22681
23017
  }
22682
23018
  await writeFile3(workspaceDst, transformedContent, "utf8");
22683
- const messagesDir = path27.join(subagentDir, "messages");
23019
+ const messagesDir = path29.join(subagentDir, "messages");
22684
23020
  await mkdir10(messagesDir, { recursive: true });
22685
23021
  return { workspace: workspaceDst, messagesDir };
22686
23022
  }
22687
23023
  async function createSubagentLock(subagentDir) {
22688
- const messagesDir = path27.join(subagentDir, "messages");
23024
+ const messagesDir = path29.join(subagentDir, "messages");
22689
23025
  if (await pathExists(messagesDir)) {
22690
- const files = await readdir2(messagesDir);
23026
+ const files = await readdir3(messagesDir);
22691
23027
  await Promise.all(
22692
23028
  files.map(async (file) => {
22693
- const target = path27.join(messagesDir, file);
23029
+ const target = path29.join(messagesDir, file);
22694
23030
  await removeIfExists(target);
22695
23031
  })
22696
23032
  );
22697
23033
  }
22698
- const githubAgentsDir = path27.join(subagentDir, ".github", "agents");
23034
+ const githubAgentsDir = path29.join(subagentDir, ".github", "agents");
22699
23035
  if (await pathExists(githubAgentsDir)) {
22700
- const agentFiles = await readdir2(githubAgentsDir);
23036
+ const agentFiles = await readdir3(githubAgentsDir);
22701
23037
  const preservedFiles = /* @__PURE__ */ new Set(["wakeup.md", "subagent.md"]);
22702
23038
  await Promise.all(
22703
- agentFiles.filter((file) => file.endsWith(".md") && !preservedFiles.has(file)).map((file) => removeIfExists(path27.join(githubAgentsDir, file)))
23039
+ agentFiles.filter((file) => file.endsWith(".md") && !preservedFiles.has(file)).map((file) => removeIfExists(path29.join(githubAgentsDir, file)))
22704
23040
  );
22705
23041
  }
22706
- const lockFile = path27.join(subagentDir, DEFAULT_LOCK_NAME);
23042
+ const lockFile = path29.join(subagentDir, DEFAULT_LOCK_NAME);
22707
23043
  await writeFile3(lockFile, "", { encoding: "utf8" });
22708
23044
  return lockFile;
22709
23045
  }
22710
23046
  async function removeSubagentLock(subagentDir) {
22711
- const lockFile = path27.join(subagentDir, DEFAULT_LOCK_NAME);
23047
+ const lockFile = path29.join(subagentDir, DEFAULT_LOCK_NAME);
22712
23048
  await removeIfExists(lockFile);
22713
23049
  }
22714
23050
  async function prepareSubagentDirectory(subagentDir, promptFile, chatId, workspaceTemplate, dryRun, cwd) {
@@ -22728,9 +23064,9 @@ async function prepareSubagentDirectory(subagentDir, promptFile, chatId, workspa
22728
23064
  return 1;
22729
23065
  }
22730
23066
  if (promptFile) {
22731
- const githubAgentsDir = path27.join(subagentDir, ".github", "agents");
23067
+ const githubAgentsDir = path29.join(subagentDir, ".github", "agents");
22732
23068
  await mkdir10(githubAgentsDir, { recursive: true });
22733
- const agentFile = path27.join(githubAgentsDir, `${chatId}.md`);
23069
+ const agentFile = path29.join(githubAgentsDir, `${chatId}.md`);
22734
23070
  try {
22735
23071
  await copyFile(promptFile, agentFile);
22736
23072
  } catch (error) {
@@ -22747,11 +23083,11 @@ async function resolvePromptFile(promptFile) {
22747
23083
  if (!promptFile) {
22748
23084
  return void 0;
22749
23085
  }
22750
- const resolvedPrompt = path28.resolve(promptFile);
23086
+ const resolvedPrompt = path30.resolve(promptFile);
22751
23087
  if (!await pathExists(resolvedPrompt)) {
22752
23088
  throw new Error(`Prompt file not found: ${resolvedPrompt}`);
22753
23089
  }
22754
- const promptStats = await stat3(resolvedPrompt);
23090
+ const promptStats = await stat4(resolvedPrompt);
22755
23091
  if (!promptStats.isFile()) {
22756
23092
  throw new Error(`Prompt file must be a file, not a directory: ${resolvedPrompt}`);
22757
23093
  }
@@ -22763,7 +23099,7 @@ async function resolveAttachments(extraAttachments) {
22763
23099
  }
22764
23100
  const resolved = [];
22765
23101
  for (const attachment of extraAttachments) {
22766
- const resolvedPath = path28.resolve(attachment);
23102
+ const resolvedPath = path30.resolve(attachment);
22767
23103
  if (!await pathExists(resolvedPath)) {
22768
23104
  throw new Error(`Attachment not found: ${resolvedPath}`);
22769
23105
  }
@@ -22805,7 +23141,7 @@ async function dispatchAgentSession(options) {
22805
23141
  error: "No unlocked subagents available. Provision additional subagents with: subagent code provision --subagents <desired_total>"
22806
23142
  };
22807
23143
  }
22808
- const subagentName = path28.basename(subagentDir);
23144
+ const subagentName = path30.basename(subagentDir);
22809
23145
  const chatId = Math.random().toString(16).slice(2, 10);
22810
23146
  const preparationResult = await prepareSubagentDirectory(
22811
23147
  subagentDir,
@@ -22833,9 +23169,9 @@ async function dispatchAgentSession(options) {
22833
23169
  };
22834
23170
  }
22835
23171
  const timestamp = generateTimestamp();
22836
- const messagesDir = path28.join(subagentDir, "messages");
22837
- const responseFileTmp = path28.join(messagesDir, `${timestamp}_res.tmp.md`);
22838
- const responseFileFinal = path28.join(messagesDir, `${timestamp}_res.md`);
23172
+ const messagesDir = path30.join(subagentDir, "messages");
23173
+ const responseFileTmp = path30.join(messagesDir, `${timestamp}_res.tmp.md`);
23174
+ const responseFileFinal = path30.join(messagesDir, `${timestamp}_res.md`);
22839
23175
  const requestInstructions = createRequestPrompt(
22840
23176
  userQuery,
22841
23177
  responseFileTmp,
@@ -22940,7 +23276,7 @@ async function dispatchBatchAgent(options) {
22940
23276
  error: "No unlocked subagents available. Provision additional subagents with: subagent code provision --subagents <desired_total>"
22941
23277
  };
22942
23278
  }
22943
- subagentName = path28.basename(subagentDir);
23279
+ subagentName = path30.basename(subagentDir);
22944
23280
  const chatId = Math.random().toString(16).slice(2, 10);
22945
23281
  const preparationResult = await prepareSubagentDirectory(
22946
23282
  subagentDir,
@@ -22971,17 +23307,17 @@ async function dispatchBatchAgent(options) {
22971
23307
  };
22972
23308
  }
22973
23309
  const timestamp = generateTimestamp();
22974
- const messagesDir = path28.join(subagentDir, "messages");
23310
+ const messagesDir = path30.join(subagentDir, "messages");
22975
23311
  requestFiles = userQueries.map(
22976
- (_, index) => path28.join(messagesDir, `${timestamp}_${index}_req.md`)
23312
+ (_, index) => path30.join(messagesDir, `${timestamp}_${index}_req.md`)
22977
23313
  );
22978
23314
  const responseTmpFiles = userQueries.map(
22979
- (_, index) => path28.join(messagesDir, `${timestamp}_${index}_res.tmp.md`)
23315
+ (_, index) => path30.join(messagesDir, `${timestamp}_${index}_res.tmp.md`)
22980
23316
  );
22981
23317
  responseFilesFinal = userQueries.map(
22982
- (_, index) => path28.join(messagesDir, `${timestamp}_${index}_res.md`)
23318
+ (_, index) => path30.join(messagesDir, `${timestamp}_${index}_res.md`)
22983
23319
  );
22984
- const orchestratorFile = path28.join(messagesDir, `${timestamp}_orchestrator.md`);
23320
+ const orchestratorFile = path30.join(messagesDir, `${timestamp}_orchestrator.md`);
22985
23321
  if (!dryRun) {
22986
23322
  await Promise.all(
22987
23323
  userQueries.map((query, index) => {
@@ -23094,7 +23430,7 @@ async function provisionSubagents(options) {
23094
23430
  if (!Number.isInteger(subagents) || subagents < 1) {
23095
23431
  throw new Error("subagents must be a positive integer");
23096
23432
  }
23097
- const targetPath = path29.resolve(targetRoot);
23433
+ const targetPath = path31.resolve(targetRoot);
23098
23434
  if (!dryRun) {
23099
23435
  await ensureDir(targetPath);
23100
23436
  }
@@ -23114,7 +23450,7 @@ async function provisionSubagents(options) {
23114
23450
  continue;
23115
23451
  }
23116
23452
  highestNumber = Math.max(highestNumber, parsed);
23117
- const lockFile = path29.join(entry.absolutePath, lockName);
23453
+ const lockFile = path31.join(entry.absolutePath, lockName);
23118
23454
  const locked = await pathExists(lockFile);
23119
23455
  if (locked) {
23120
23456
  lockedSubagents.add(entry.absolutePath);
@@ -23131,10 +23467,10 @@ async function provisionSubagents(options) {
23131
23467
  break;
23132
23468
  }
23133
23469
  const subagentDir = subagent.absolutePath;
23134
- const githubAgentsDir = path29.join(subagentDir, ".github", "agents");
23135
- const lockFile = path29.join(subagentDir, lockName);
23136
- const workspaceDst = path29.join(subagentDir, `${path29.basename(subagentDir)}.code-workspace`);
23137
- const wakeupDst = path29.join(githubAgentsDir, "wakeup.md");
23470
+ const githubAgentsDir = path31.join(subagentDir, ".github", "agents");
23471
+ const lockFile = path31.join(subagentDir, lockName);
23472
+ const workspaceDst = path31.join(subagentDir, `${path31.basename(subagentDir)}.code-workspace`);
23473
+ const wakeupDst = path31.join(githubAgentsDir, "wakeup.md");
23138
23474
  const isLocked = await pathExists(lockFile);
23139
23475
  if (isLocked && !force) {
23140
23476
  continue;
@@ -23172,10 +23508,10 @@ async function provisionSubagents(options) {
23172
23508
  let nextIndex = highestNumber;
23173
23509
  while (subagentsProvisioned < subagents) {
23174
23510
  nextIndex += 1;
23175
- const subagentDir = path29.join(targetPath, `subagent-${nextIndex}`);
23176
- const githubAgentsDir = path29.join(subagentDir, ".github", "agents");
23177
- const workspaceDst = path29.join(subagentDir, `${path29.basename(subagentDir)}.code-workspace`);
23178
- const wakeupDst = path29.join(githubAgentsDir, "wakeup.md");
23511
+ const subagentDir = path31.join(targetPath, `subagent-${nextIndex}`);
23512
+ const githubAgentsDir = path31.join(subagentDir, ".github", "agents");
23513
+ const workspaceDst = path31.join(subagentDir, `${path31.basename(subagentDir)}.code-workspace`);
23514
+ const wakeupDst = path31.join(githubAgentsDir, "wakeup.md");
23179
23515
  if (!dryRun) {
23180
23516
  await ensureDir(subagentDir);
23181
23517
  await ensureDir(githubAgentsDir);
@@ -23361,7 +23697,7 @@ var VSCodeProvider = class {
23361
23697
  async function locateVSCodeExecutable(candidate) {
23362
23698
  const includesPathSeparator = candidate.includes("/") || candidate.includes("\\");
23363
23699
  if (includesPathSeparator) {
23364
- const resolved = path30.isAbsolute(candidate) ? candidate : path30.resolve(candidate);
23700
+ const resolved = path322.isAbsolute(candidate) ? candidate : path322.resolve(candidate);
23365
23701
  try {
23366
23702
  await access3(resolved, constants3.F_OK);
23367
23703
  return resolved;
@@ -23390,7 +23726,7 @@ async function resolveWorkspaceTemplateFile(template) {
23390
23726
  return void 0;
23391
23727
  }
23392
23728
  try {
23393
- const stats = await stat4(path30.resolve(template));
23729
+ const stats = await stat5(path322.resolve(template));
23394
23730
  return stats.isFile() ? template : void 0;
23395
23731
  } catch {
23396
23732
  return template;
@@ -23414,7 +23750,7 @@ function buildMandatoryPrereadBlock2(attachmentFiles) {
23414
23750
  return "";
23415
23751
  }
23416
23752
  const buildList = (files) => files.map((absolutePath) => {
23417
- const fileName = path30.basename(absolutePath);
23753
+ const fileName = path322.basename(absolutePath);
23418
23754
  const fileUri = pathToFileUri3(absolutePath);
23419
23755
  return `* [${fileName}](${fileUri})`;
23420
23756
  });
@@ -23435,7 +23771,7 @@ function collectAttachmentFiles(attachments) {
23435
23771
  }
23436
23772
  const unique = /* @__PURE__ */ new Map();
23437
23773
  for (const attachment of attachments) {
23438
- const absolutePath = path30.resolve(attachment);
23774
+ const absolutePath = path322.resolve(attachment);
23439
23775
  if (!unique.has(absolutePath)) {
23440
23776
  unique.set(absolutePath, absolutePath);
23441
23777
  }
@@ -23443,7 +23779,7 @@ function collectAttachmentFiles(attachments) {
23443
23779
  return Array.from(unique.values());
23444
23780
  }
23445
23781
  function pathToFileUri3(filePath) {
23446
- const absolutePath = path30.isAbsolute(filePath) ? filePath : path30.resolve(filePath);
23782
+ const absolutePath = path322.isAbsolute(filePath) ? filePath : path322.resolve(filePath);
23447
23783
  const normalizedPath = absolutePath.replace(/\\/g, "/");
23448
23784
  if (/^[a-zA-Z]:\//.test(normalizedPath)) {
23449
23785
  return `file:///${normalizedPath}`;
@@ -23456,7 +23792,7 @@ function normalizeAttachments(attachments) {
23456
23792
  }
23457
23793
  const deduped = /* @__PURE__ */ new Set();
23458
23794
  for (const attachment of attachments) {
23459
- deduped.add(path30.resolve(attachment));
23795
+ deduped.add(path322.resolve(attachment));
23460
23796
  }
23461
23797
  return Array.from(deduped);
23462
23798
  }
@@ -23465,7 +23801,7 @@ function mergeAttachments(all) {
23465
23801
  for (const list of all) {
23466
23802
  if (!list) continue;
23467
23803
  for (const inputFile of list) {
23468
- deduped.add(path30.resolve(inputFile));
23804
+ deduped.add(path322.resolve(inputFile));
23469
23805
  }
23470
23806
  }
23471
23807
  return deduped.size > 0 ? Array.from(deduped) : void 0;
@@ -23545,11 +23881,11 @@ async function fileExists3(filePath) {
23545
23881
  }
23546
23882
  }
23547
23883
  async function readTargetDefinitions(filePath) {
23548
- const absolutePath = path31.resolve(filePath);
23884
+ const absolutePath = path33.resolve(filePath);
23549
23885
  if (!await fileExists3(absolutePath)) {
23550
23886
  throw new Error(`targets.yaml not found at ${absolutePath}`);
23551
23887
  }
23552
- const raw = await readFile9(absolutePath, "utf8");
23888
+ const raw = await readFile11(absolutePath, "utf8");
23553
23889
  const parsed = parse4(raw);
23554
23890
  if (!isRecord(parsed)) {
23555
23891
  throw new Error(`targets.yaml at ${absolutePath} must be a YAML object with a 'targets' field`);
@@ -23566,11 +23902,11 @@ function listTargetNames(definitions) {
23566
23902
  async function discoverProviders(registry, baseDir) {
23567
23903
  const patterns = ["*.ts", "*.js", "*.mts", "*.mjs"];
23568
23904
  const candidateDirs = [];
23569
- let dir = path322.resolve(baseDir);
23570
- const root = path322.parse(dir).root;
23905
+ let dir = path34.resolve(baseDir);
23906
+ const root = path34.parse(dir).root;
23571
23907
  while (dir !== root) {
23572
- candidateDirs.push(path322.join(dir, ".agentv", "providers"));
23573
- dir = path322.dirname(dir);
23908
+ candidateDirs.push(path34.join(dir, ".agentv", "providers"));
23909
+ dir = path34.dirname(dir);
23574
23910
  }
23575
23911
  let files = [];
23576
23912
  for (const providersDir of candidateDirs) {
@@ -23586,7 +23922,7 @@ async function discoverProviders(registry, baseDir) {
23586
23922
  }
23587
23923
  const discoveredKinds = [];
23588
23924
  for (const filePath of files) {
23589
- const basename = path322.basename(filePath);
23925
+ const basename = path34.basename(filePath);
23590
23926
  const kindName = basename.replace(/\.(ts|js|mts|mjs)$/, "");
23591
23927
  if (registry.has(kindName)) {
23592
23928
  continue;
@@ -23602,7 +23938,7 @@ async function discoverProviders(registry, baseDir) {
23602
23938
  }
23603
23939
  function createBuiltinProviderRegistry() {
23604
23940
  const registry = new ProviderRegistry();
23605
- registry.register("openai", (t) => new OpenAIProvider(t.name, t.config)).register("openrouter", (t) => new OpenRouterProvider(t.name, t.config)).register("azure", (t) => new AzureProvider(t.name, t.config)).register("anthropic", (t) => new AnthropicProvider(t.name, t.config)).register("gemini", (t) => new GeminiProvider(t.name, t.config)).register("cli", (t) => new CliProvider(t.name, t.config)).register("codex", (t) => new CodexProvider(t.name, t.config)).register("copilot-sdk", (t) => new CopilotSdkProvider(t.name, t.config)).register("copilot-cli", (t) => new CopilotCliProvider(t.name, t.config)).register("pi-coding-agent", (t) => new PiCodingAgentProvider(t.name, t.config)).register("pi-cli", (t) => new PiCliProvider(t.name, t.config)).register("claude-cli", (t) => new ClaudeCliProvider(t.name, t.config)).register("claude", (t) => new ClaudeCliProvider(t.name, t.config)).register("claude-sdk", (t) => new ClaudeSdkProvider(t.name, t.config)).register("mock", (t) => new MockProvider(t.name, t.config)).register("agentv", (t) => new AgentvProvider(t.name, t.config)).register("vscode", (t) => new VSCodeProvider(t.name, t.config, "vscode")).register(
23941
+ registry.register("openai", (t) => new OpenAIProvider(t.name, t.config)).register("openrouter", (t) => new OpenRouterProvider(t.name, t.config)).register("azure", (t) => new AzureProvider(t.name, t.config)).register("anthropic", (t) => new AnthropicProvider(t.name, t.config)).register("gemini", (t) => new GeminiProvider(t.name, t.config)).register("cli", (t) => new CliProvider(t.name, t.config)).register("codex", (t) => new CodexProvider(t.name, t.config)).register("copilot-sdk", (t) => new CopilotSdkProvider(t.name, t.config)).register("copilot-cli", (t) => new CopilotCliProvider(t.name, t.config)).register("copilot-log", (t) => new CopilotLogProvider(t.name, t.config)).register("pi-coding-agent", (t) => new PiCodingAgentProvider(t.name, t.config)).register("pi-cli", (t) => new PiCliProvider(t.name, t.config)).register("claude-cli", (t) => new ClaudeCliProvider(t.name, t.config)).register("claude", (t) => new ClaudeCliProvider(t.name, t.config)).register("claude-sdk", (t) => new ClaudeSdkProvider(t.name, t.config)).register("mock", (t) => new MockProvider(t.name, t.config)).register("agentv", (t) => new AgentvProvider(t.name, t.config)).register("vscode", (t) => new VSCodeProvider(t.name, t.config, "vscode")).register(
23606
23942
  "vscode-insiders",
23607
23943
  (t) => new VSCodeProvider(t.name, t.config, "vscode-insiders")
23608
23944
  );
@@ -23800,15 +24136,15 @@ async function execFileWithStdinNode(argv, stdinPayload, options) {
23800
24136
  });
23801
24137
  }
23802
24138
  async function execShellWithStdin(command, stdinPayload, options = {}) {
23803
- const { mkdir: mkdir16, readFile: readFile12, rm: rm6, writeFile: writeFile9 } = await import("node:fs/promises");
24139
+ const { mkdir: mkdir16, readFile: readFile14, rm: rm6, writeFile: writeFile9 } = await import("node:fs/promises");
23804
24140
  const { tmpdir: tmpdir3 } = await import("node:os");
23805
- const path45 = await import("node:path");
24141
+ const path47 = await import("node:path");
23806
24142
  const { randomUUID: randomUUID10 } = await import("node:crypto");
23807
- const dir = path45.join(tmpdir3(), `agentv-exec-${randomUUID10()}`);
24143
+ const dir = path47.join(tmpdir3(), `agentv-exec-${randomUUID10()}`);
23808
24144
  await mkdir16(dir, { recursive: true });
23809
- const stdinPath = path45.join(dir, "stdin.txt");
23810
- const stdoutPath = path45.join(dir, "stdout.txt");
23811
- const stderrPath = path45.join(dir, "stderr.txt");
24145
+ const stdinPath = path47.join(dir, "stdin.txt");
24146
+ const stdoutPath = path47.join(dir, "stdout.txt");
24147
+ const stderrPath = path47.join(dir, "stderr.txt");
23812
24148
  await writeFile9(stdinPath, stdinPayload, "utf8");
23813
24149
  const wrappedCommand = process.platform === "win32" ? `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}` : `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}`;
23814
24150
  const { spawn: spawn5 } = await import("node:child_process");
@@ -23838,8 +24174,8 @@ async function execShellWithStdin(command, stdinPayload, options = {}) {
23838
24174
  resolve2(code ?? 0);
23839
24175
  });
23840
24176
  });
23841
- const stdout = (await readFile12(stdoutPath, "utf8")).replace(/\r\n/g, "\n");
23842
- const stderr = (await readFile12(stderrPath, "utf8")).replace(/\r\n/g, "\n");
24177
+ const stdout = (await readFile14(stdoutPath, "utf8")).replace(/\r\n/g, "\n");
24178
+ const stderr = (await readFile14(stderrPath, "utf8")).replace(/\r\n/g, "\n");
23843
24179
  return { stdout, stderr, exitCode };
23844
24180
  } finally {
23845
24181
  await rm6(dir, { recursive: true, force: true });
@@ -25125,8 +25461,8 @@ function calculateScoreRangeResult(result, rubrics) {
25125
25461
  };
25126
25462
  }
25127
25463
  function resolveSandboxed(basePath, relativePath) {
25128
- const resolved = path33.resolve(basePath, relativePath);
25129
- if (!resolved.startsWith(basePath + path33.sep) && resolved !== basePath) {
25464
+ const resolved = path35.resolve(basePath, relativePath);
25465
+ if (!resolved.startsWith(basePath + path35.sep) && resolved !== basePath) {
25130
25466
  throw new Error(`Path '${relativePath}' is outside the workspace`);
25131
25467
  }
25132
25468
  return resolved;
@@ -25159,11 +25495,11 @@ function createFilesystemTools(workspacePath) {
25159
25495
  execute: async (input) => {
25160
25496
  try {
25161
25497
  const resolved = resolveSandboxed(workspacePath, input.path);
25162
- const stat8 = await fs2.stat(resolved);
25163
- if (stat8.isDirectory()) {
25498
+ const stat9 = await fs2.stat(resolved);
25499
+ if (stat9.isDirectory()) {
25164
25500
  return { error: `'${input.path}' is a directory, not a file` };
25165
25501
  }
25166
- const buffer = Buffer.alloc(Math.min(stat8.size, MAX_FILE_SIZE));
25502
+ const buffer = Buffer.alloc(Math.min(stat9.size, MAX_FILE_SIZE));
25167
25503
  const fd = await fs2.open(resolved, "r");
25168
25504
  try {
25169
25505
  await fd.read(buffer, 0, buffer.length, 0);
@@ -25171,8 +25507,8 @@ function createFilesystemTools(workspacePath) {
25171
25507
  await fd.close();
25172
25508
  }
25173
25509
  const content = buffer.toString("utf-8");
25174
- const truncated = stat8.size > MAX_FILE_SIZE;
25175
- return { content, truncated, size: stat8.size };
25510
+ const truncated = stat9.size > MAX_FILE_SIZE;
25511
+ return { content, truncated, size: stat9.size };
25176
25512
  } catch (error) {
25177
25513
  return { error: error instanceof Error ? error.message : String(error) };
25178
25514
  }
@@ -25216,15 +25552,15 @@ async function searchDirectory(dirPath, workspacePath, regex, matches) {
25216
25552
  for (const entry of entries) {
25217
25553
  if (matches.length >= MAX_SEARCH_MATCHES) return;
25218
25554
  if (SEARCH_SKIP_DIRS.has(entry.name)) continue;
25219
- const fullPath = path33.join(dirPath, entry.name);
25555
+ const fullPath = path35.join(dirPath, entry.name);
25220
25556
  if (entry.isDirectory()) {
25221
25557
  await searchDirectory(fullPath, workspacePath, regex, matches);
25222
25558
  } else if (entry.isFile()) {
25223
- const ext = path33.extname(entry.name).toLowerCase();
25559
+ const ext = path35.extname(entry.name).toLowerCase();
25224
25560
  if (BINARY_EXTENSIONS.has(ext)) continue;
25225
25561
  try {
25226
- const stat8 = await fs2.stat(fullPath);
25227
- if (stat8.size > MAX_FILE_SIZE) continue;
25562
+ const stat9 = await fs2.stat(fullPath);
25563
+ if (stat9.size > MAX_FILE_SIZE) continue;
25228
25564
  const content = await fs2.readFile(fullPath, "utf-8");
25229
25565
  const lines = content.split("\n");
25230
25566
  for (let i = 0; i < lines.length; i++) {
@@ -25232,7 +25568,7 @@ async function searchDirectory(dirPath, workspacePath, regex, matches) {
25232
25568
  regex.lastIndex = 0;
25233
25569
  if (regex.test(lines[i])) {
25234
25570
  matches.push({
25235
- file: path33.relative(workspacePath, fullPath),
25571
+ file: path35.relative(workspacePath, fullPath),
25236
25572
  line: i + 1,
25237
25573
  text: lines[i].substring(0, 200)
25238
25574
  });
@@ -25857,115 +26193,115 @@ var FieldAccuracyEvaluator = class {
25857
26193
  * Evaluate a single field against the expected value.
25858
26194
  */
25859
26195
  evaluateField(fieldConfig, candidateData, expectedData) {
25860
- const { path: path45, match, required = true, weight = 1 } = fieldConfig;
25861
- const candidateValue = resolvePath(candidateData, path45);
25862
- const expectedValue = resolvePath(expectedData, path45);
26196
+ const { path: path47, match, required = true, weight = 1 } = fieldConfig;
26197
+ const candidateValue = resolvePath(candidateData, path47);
26198
+ const expectedValue = resolvePath(expectedData, path47);
25863
26199
  if (expectedValue === void 0) {
25864
26200
  return {
25865
- path: path45,
26201
+ path: path47,
25866
26202
  score: 1,
25867
26203
  // No expected value means no comparison needed
25868
26204
  weight,
25869
26205
  hit: true,
25870
- message: `${path45}: no expected value`
26206
+ message: `${path47}: no expected value`
25871
26207
  };
25872
26208
  }
25873
26209
  if (candidateValue === void 0) {
25874
26210
  if (required) {
25875
26211
  return {
25876
- path: path45,
26212
+ path: path47,
25877
26213
  score: 0,
25878
26214
  weight,
25879
26215
  hit: false,
25880
- message: `${path45} (required, missing)`
26216
+ message: `${path47} (required, missing)`
25881
26217
  };
25882
26218
  }
25883
26219
  return {
25884
- path: path45,
26220
+ path: path47,
25885
26221
  score: 1,
25886
26222
  // Don't penalize missing optional fields
25887
26223
  weight: 0,
25888
26224
  // Zero weight means it won't affect the score
25889
26225
  hit: true,
25890
- message: `${path45}: optional field missing`
26226
+ message: `${path47}: optional field missing`
25891
26227
  };
25892
26228
  }
25893
26229
  switch (match) {
25894
26230
  case "exact":
25895
- return this.compareExact(path45, candidateValue, expectedValue, weight);
26231
+ return this.compareExact(path47, candidateValue, expectedValue, weight);
25896
26232
  case "numeric_tolerance":
25897
26233
  return this.compareNumericTolerance(
25898
- path45,
26234
+ path47,
25899
26235
  candidateValue,
25900
26236
  expectedValue,
25901
26237
  fieldConfig,
25902
26238
  weight
25903
26239
  );
25904
26240
  case "date":
25905
- return this.compareDate(path45, candidateValue, expectedValue, fieldConfig, weight);
26241
+ return this.compareDate(path47, candidateValue, expectedValue, fieldConfig, weight);
25906
26242
  default:
25907
26243
  return {
25908
- path: path45,
26244
+ path: path47,
25909
26245
  score: 0,
25910
26246
  weight,
25911
26247
  hit: false,
25912
- message: `${path45}: unknown match type "${match}"`
26248
+ message: `${path47}: unknown match type "${match}"`
25913
26249
  };
25914
26250
  }
25915
26251
  }
25916
26252
  /**
25917
26253
  * Exact equality comparison.
25918
26254
  */
25919
- compareExact(path45, candidateValue, expectedValue, weight) {
26255
+ compareExact(path47, candidateValue, expectedValue, weight) {
25920
26256
  if (deepEqual(candidateValue, expectedValue)) {
25921
26257
  return {
25922
- path: path45,
26258
+ path: path47,
25923
26259
  score: 1,
25924
26260
  weight,
25925
26261
  hit: true,
25926
- message: path45
26262
+ message: path47
25927
26263
  };
25928
26264
  }
25929
26265
  if (typeof candidateValue !== typeof expectedValue) {
25930
26266
  return {
25931
- path: path45,
26267
+ path: path47,
25932
26268
  score: 0,
25933
26269
  weight,
25934
26270
  hit: false,
25935
- message: `${path45} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
26271
+ message: `${path47} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
25936
26272
  };
25937
26273
  }
25938
26274
  return {
25939
- path: path45,
26275
+ path: path47,
25940
26276
  score: 0,
25941
26277
  weight,
25942
26278
  hit: false,
25943
- message: `${path45} (value mismatch)`
26279
+ message: `${path47} (value mismatch)`
25944
26280
  };
25945
26281
  }
25946
26282
  /**
25947
26283
  * Numeric comparison with absolute or relative tolerance.
25948
26284
  */
25949
- compareNumericTolerance(path45, candidateValue, expectedValue, fieldConfig, weight) {
26285
+ compareNumericTolerance(path47, candidateValue, expectedValue, fieldConfig, weight) {
25950
26286
  const { tolerance = 0, relative = false } = fieldConfig;
25951
26287
  const candidateNum = toNumber(candidateValue);
25952
26288
  const expectedNum = toNumber(expectedValue);
25953
26289
  if (candidateNum === null || expectedNum === null) {
25954
26290
  return {
25955
- path: path45,
26291
+ path: path47,
25956
26292
  score: 0,
25957
26293
  weight,
25958
26294
  hit: false,
25959
- message: `${path45} (non-numeric value)`
26295
+ message: `${path47} (non-numeric value)`
25960
26296
  };
25961
26297
  }
25962
26298
  if (!Number.isFinite(candidateNum) || !Number.isFinite(expectedNum)) {
25963
26299
  return {
25964
- path: path45,
26300
+ path: path47,
25965
26301
  score: 0,
25966
26302
  weight,
25967
26303
  hit: false,
25968
- message: `${path45} (invalid numeric value)`
26304
+ message: `${path47} (invalid numeric value)`
25969
26305
  };
25970
26306
  }
25971
26307
  const diff = Math.abs(candidateNum - expectedNum);
@@ -25978,61 +26314,61 @@ var FieldAccuracyEvaluator = class {
25978
26314
  }
25979
26315
  if (withinTolerance) {
25980
26316
  return {
25981
- path: path45,
26317
+ path: path47,
25982
26318
  score: 1,
25983
26319
  weight,
25984
26320
  hit: true,
25985
- message: `${path45} (within tolerance: diff=${diff.toFixed(2)})`
26321
+ message: `${path47} (within tolerance: diff=${diff.toFixed(2)})`
25986
26322
  };
25987
26323
  }
25988
26324
  return {
25989
- path: path45,
26325
+ path: path47,
25990
26326
  score: 0,
25991
26327
  weight,
25992
26328
  hit: false,
25993
- message: `${path45} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
26329
+ message: `${path47} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
25994
26330
  };
25995
26331
  }
25996
26332
  /**
25997
26333
  * Date comparison with format normalization.
25998
26334
  */
25999
- compareDate(path45, candidateValue, expectedValue, fieldConfig, weight) {
26335
+ compareDate(path47, candidateValue, expectedValue, fieldConfig, weight) {
26000
26336
  const formats = fieldConfig.formats ?? DEFAULT_DATE_FORMATS;
26001
26337
  const candidateDate = parseDate(String(candidateValue), formats);
26002
26338
  const expectedDate = parseDate(String(expectedValue), formats);
26003
26339
  if (candidateDate === null) {
26004
26340
  return {
26005
- path: path45,
26341
+ path: path47,
26006
26342
  score: 0,
26007
26343
  weight,
26008
26344
  hit: false,
26009
- message: `${path45} (unparseable candidate date)`
26345
+ message: `${path47} (unparseable candidate date)`
26010
26346
  };
26011
26347
  }
26012
26348
  if (expectedDate === null) {
26013
26349
  return {
26014
- path: path45,
26350
+ path: path47,
26015
26351
  score: 0,
26016
26352
  weight,
26017
26353
  hit: false,
26018
- message: `${path45} (unparseable expected date)`
26354
+ message: `${path47} (unparseable expected date)`
26019
26355
  };
26020
26356
  }
26021
26357
  if (candidateDate.getFullYear() === expectedDate.getFullYear() && candidateDate.getMonth() === expectedDate.getMonth() && candidateDate.getDate() === expectedDate.getDate()) {
26022
26358
  return {
26023
- path: path45,
26359
+ path: path47,
26024
26360
  score: 1,
26025
26361
  weight,
26026
26362
  hit: true,
26027
- message: path45
26363
+ message: path47
26028
26364
  };
26029
26365
  }
26030
26366
  return {
26031
- path: path45,
26367
+ path: path47,
26032
26368
  score: 0,
26033
26369
  weight,
26034
26370
  hit: false,
26035
- message: `${path45} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
26371
+ message: `${path47} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
26036
26372
  };
26037
26373
  }
26038
26374
  /**
@@ -26065,11 +26401,11 @@ var FieldAccuracyEvaluator = class {
26065
26401
  };
26066
26402
  }
26067
26403
  };
26068
- function resolvePath(obj, path45) {
26069
- if (!path45 || !obj) {
26404
+ function resolvePath(obj, path47) {
26405
+ if (!path47 || !obj) {
26070
26406
  return void 0;
26071
26407
  }
26072
- const parts = path45.split(/\.|\[|\]/).filter((p) => p.length > 0);
26408
+ const parts = path47.split(/\.|\[|\]/).filter((p) => p.length > 0);
26073
26409
  let current = obj;
26074
26410
  for (const part of parts) {
26075
26411
  if (current === null || current === void 0) {
@@ -26233,6 +26569,7 @@ var PROVIDER_TOOL_SEMANTICS = {
26233
26569
  "pi-coding-agent": PI_CODING_AGENT_MATCHER,
26234
26570
  "pi-cli": PI_CODING_AGENT_MATCHER,
26235
26571
  "copilot-cli": COPILOT_MATCHER,
26572
+ "copilot-log": COPILOT_MATCHER,
26236
26573
  "copilot-sdk": COPILOT_MATCHER,
26237
26574
  vscode: COPILOT_MATCHER,
26238
26575
  "vscode-insiders": COPILOT_MATCHER
@@ -26259,8 +26596,9 @@ var SkillTriggerEvaluator = class {
26259
26596
  let triggered = false;
26260
26597
  let evidence = "";
26261
26598
  for (const toolCall of allToolCalls) {
26599
+ const toolName = toolCall.tool ?? "";
26262
26600
  const input = toolCall.input ?? {};
26263
- if (matcher.skillTools.includes(toolCall.tool)) {
26601
+ if (matcher.skillTools.includes(toolName)) {
26264
26602
  const skillArg = String(input[matcher.skillInputField] ?? "");
26265
26603
  if (skillArg.includes(skillName)) {
26266
26604
  triggered = true;
@@ -26268,12 +26606,12 @@ var SkillTriggerEvaluator = class {
26268
26606
  break;
26269
26607
  }
26270
26608
  } else if (matcher.skillToolPrefixes?.some(
26271
- (prefix) => toolCall.tool.startsWith(prefix) && toolCall.tool.includes(skillName)
26609
+ (prefix) => toolName.startsWith(prefix) && toolName.includes(skillName)
26272
26610
  )) {
26273
26611
  triggered = true;
26274
- evidence = `Skill tool invoked via tool name "${toolCall.tool}"`;
26612
+ evidence = `Skill tool invoked via tool name "${toolName}"`;
26275
26613
  break;
26276
- } else if (matcher.readTools.includes(toolCall.tool)) {
26614
+ } else if (matcher.readTools.includes(toolName)) {
26277
26615
  const filePath = this.readPathFromInput(input, matcher);
26278
26616
  if (filePath.includes(skillName)) {
26279
26617
  triggered = true;
@@ -26281,10 +26619,10 @@ var SkillTriggerEvaluator = class {
26281
26619
  break;
26282
26620
  }
26283
26621
  } else if (matcher.readToolPrefixes?.some(
26284
- (prefix) => toolCall.tool.startsWith(prefix) && toolCall.tool.includes(skillName)
26622
+ (prefix) => toolName.startsWith(prefix) && toolName.includes(skillName)
26285
26623
  )) {
26286
26624
  triggered = true;
26287
- evidence = `Read tool loaded skill file via tool name "${toolCall.tool}"`;
26625
+ evidence = `Read tool loaded skill file via tool name "${toolName}"`;
26288
26626
  break;
26289
26627
  }
26290
26628
  }
@@ -26540,8 +26878,8 @@ var TokenUsageEvaluator = class {
26540
26878
  };
26541
26879
  }
26542
26880
  };
26543
- function getNestedValue(obj, path45) {
26544
- const parts = path45.split(".");
26881
+ function getNestedValue(obj, path47) {
26882
+ const parts = path47.split(".");
26545
26883
  let current = obj;
26546
26884
  for (const part of parts) {
26547
26885
  if (current === null || current === void 0 || typeof current !== "object") {
@@ -27404,7 +27742,7 @@ async function executePromptTemplate(script, context2, config, timeoutMs) {
27404
27742
  };
27405
27743
  const inputJson = JSON.stringify(toSnakeCaseDeep(payload), null, 2);
27406
27744
  const scriptPath = script[script.length - 1];
27407
- const cwd = path34.dirname(scriptPath);
27745
+ const cwd = path36.dirname(scriptPath);
27408
27746
  try {
27409
27747
  const stdout = await executeScript(script, inputJson, timeoutMs, cwd);
27410
27748
  const prompt = stdout.trim();
@@ -27675,11 +28013,11 @@ function createBuiltinRegistry() {
27675
28013
  async function discoverAssertions(registry, baseDir) {
27676
28014
  const patterns = ["*.ts", "*.js", "*.mts", "*.mjs"];
27677
28015
  const candidateDirs = [];
27678
- let dir = path35.resolve(baseDir);
27679
- const root = path35.parse(dir).root;
28016
+ let dir = path37.resolve(baseDir);
28017
+ const root = path37.parse(dir).root;
27680
28018
  while (dir !== root) {
27681
- candidateDirs.push(path35.join(dir, ".agentv", "assertions"));
27682
- dir = path35.dirname(dir);
28019
+ candidateDirs.push(path37.join(dir, ".agentv", "assertions"));
28020
+ dir = path37.dirname(dir);
27683
28021
  }
27684
28022
  let files = [];
27685
28023
  for (const assertionsDir of candidateDirs) {
@@ -27695,7 +28033,7 @@ async function discoverAssertions(registry, baseDir) {
27695
28033
  }
27696
28034
  const discoveredTypes = [];
27697
28035
  for (const filePath of files) {
27698
- const basename = path35.basename(filePath);
28036
+ const basename = path37.basename(filePath);
27699
28037
  const typeName = basename.replace(/\.(ts|js|mts|mjs)$/, "");
27700
28038
  if (registry.has(typeName)) {
27701
28039
  continue;
@@ -27714,12 +28052,12 @@ async function discoverAssertions(registry, baseDir) {
27714
28052
  async function discoverGraders(registry, baseDir) {
27715
28053
  const patterns = ["*.ts", "*.js", "*.mts", "*.mjs"];
27716
28054
  const candidateDirs = [];
27717
- let dir = path36.resolve(baseDir);
27718
- const root = path36.parse(dir).root;
28055
+ let dir = path38.resolve(baseDir);
28056
+ const root = path38.parse(dir).root;
27719
28057
  while (dir !== root) {
27720
- candidateDirs.push(path36.join(dir, ".agentv", "graders"));
27721
- candidateDirs.push(path36.join(dir, ".agentv", "judges"));
27722
- dir = path36.dirname(dir);
28058
+ candidateDirs.push(path38.join(dir, ".agentv", "graders"));
28059
+ candidateDirs.push(path38.join(dir, ".agentv", "judges"));
28060
+ dir = path38.dirname(dir);
27723
28061
  }
27724
28062
  let files = [];
27725
28063
  for (const gradersDir of candidateDirs) {
@@ -27735,7 +28073,7 @@ async function discoverGraders(registry, baseDir) {
27735
28073
  }
27736
28074
  const discoveredTypes = [];
27737
28075
  for (const filePath of files) {
27738
- const basename = path36.basename(filePath);
28076
+ const basename = path38.basename(filePath);
27739
28077
  const typeName = basename.replace(/\.(ts|js|mts|mjs)$/, "");
27740
28078
  if (registry.has(typeName)) {
27741
28079
  continue;
@@ -27921,10 +28259,10 @@ async function stageNestedRepoChanges(workspacePath) {
27921
28259
  }
27922
28260
  for (const entry of entries) {
27923
28261
  if (entry === ".git" || entry === "node_modules") continue;
27924
- const childPath = path37.join(workspacePath, entry);
28262
+ const childPath = path39.join(workspacePath, entry);
27925
28263
  try {
27926
28264
  if (!statSync(childPath).isDirectory()) continue;
27927
- if (!statSync(path37.join(childPath, ".git")).isDirectory()) continue;
28265
+ if (!statSync(path39.join(childPath, ".git")).isDirectory()) continue;
27928
28266
  } catch {
27929
28267
  continue;
27930
28268
  }
@@ -27953,7 +28291,7 @@ var WorkspaceCreationError = class extends Error {
27953
28291
  };
27954
28292
  async function isDirectory(filePath) {
27955
28293
  try {
27956
- const stats = await stat5(filePath);
28294
+ const stats = await stat6(filePath);
27957
28295
  return stats.isDirectory();
27958
28296
  } catch {
27959
28297
  return false;
@@ -27961,14 +28299,14 @@ async function isDirectory(filePath) {
27961
28299
  }
27962
28300
  function getWorkspacePath(evalRunId, caseId, workspaceRoot) {
27963
28301
  const root = workspaceRoot ?? getWorkspacesRoot();
27964
- return path38.join(root, evalRunId, caseId);
28302
+ return path40.join(root, evalRunId, caseId);
27965
28303
  }
27966
28304
  async function copyDirectoryRecursive(src, dest) {
27967
28305
  await mkdir12(dest, { recursive: true });
27968
- const entries = await readdir3(src, { withFileTypes: true });
28306
+ const entries = await readdir4(src, { withFileTypes: true });
27969
28307
  for (const entry of entries) {
27970
- const srcPath = path38.join(src, entry.name);
27971
- const destPath = path38.join(dest, entry.name);
28308
+ const srcPath = path40.join(src, entry.name);
28309
+ const destPath = path40.join(dest, entry.name);
27972
28310
  if (entry.name === ".git") {
27973
28311
  continue;
27974
28312
  }
@@ -27980,7 +28318,7 @@ async function copyDirectoryRecursive(src, dest) {
27980
28318
  }
27981
28319
  }
27982
28320
  async function createTempWorkspace(templatePath, evalRunId, caseId, workspaceRoot) {
27983
- const resolvedTemplatePath = path38.resolve(templatePath);
28321
+ const resolvedTemplatePath = path40.resolve(templatePath);
27984
28322
  if (!await fileExists(resolvedTemplatePath)) {
27985
28323
  throw new TemplateNotFoundError(resolvedTemplatePath);
27986
28324
  }
@@ -28029,7 +28367,7 @@ async function cleanupWorkspace(workspacePath) {
28029
28367
  }
28030
28368
  async function cleanupEvalWorkspaces(evalRunId, workspaceRoot) {
28031
28369
  const root = workspaceRoot ?? getWorkspacesRoot();
28032
- const evalDir = path38.join(root, evalRunId);
28370
+ const evalDir = path40.join(root, evalRunId);
28033
28371
  if (await fileExists(evalDir)) {
28034
28372
  await rm4(evalDir, { recursive: true, force: true });
28035
28373
  }
@@ -28084,10 +28422,10 @@ function computeWorkspaceFingerprint(repos) {
28084
28422
  }
28085
28423
  async function copyDirectoryRecursive2(src, dest, skipDirs) {
28086
28424
  await mkdir13(dest, { recursive: true });
28087
- const entries = await readdir4(src, { withFileTypes: true });
28425
+ const entries = await readdir5(src, { withFileTypes: true });
28088
28426
  for (const entry of entries) {
28089
- const srcPath = path39.join(src, entry.name);
28090
- const destPath = path39.join(dest, entry.name);
28427
+ const srcPath = path41.join(src, entry.name);
28428
+ const destPath = path41.join(dest, entry.name);
28091
28429
  if (entry.name === ".git") {
28092
28430
  continue;
28093
28431
  }
@@ -28120,7 +28458,7 @@ var WorkspacePoolManager = class {
28120
28458
  async acquireWorkspace(options) {
28121
28459
  const { templatePath, repos, maxSlots, repoManager, poolReset } = options;
28122
28460
  const fingerprint = computeWorkspaceFingerprint(repos);
28123
- const poolDir = path39.join(this.poolRoot, fingerprint);
28461
+ const poolDir = path41.join(this.poolRoot, fingerprint);
28124
28462
  await mkdir13(poolDir, { recursive: true });
28125
28463
  const drifted = await this.checkDrift(poolDir, fingerprint);
28126
28464
  if (drifted) {
@@ -28130,7 +28468,7 @@ var WorkspacePoolManager = class {
28130
28468
  await this.removeAllSlots(poolDir);
28131
28469
  }
28132
28470
  for (let i = 0; i < maxSlots; i++) {
28133
- const slotPath = path39.join(poolDir, `slot-${i}`);
28471
+ const slotPath = path41.join(poolDir, `slot-${i}`);
28134
28472
  const lockPath = `${slotPath}.lock`;
28135
28473
  const locked = await this.tryLock(lockPath);
28136
28474
  if (!locked) {
@@ -28192,7 +28530,7 @@ var WorkspacePoolManager = class {
28192
28530
  throw err;
28193
28531
  }
28194
28532
  try {
28195
- const pidStr = await readFile10(lockPath, "utf-8");
28533
+ const pidStr = await readFile12(lockPath, "utf-8");
28196
28534
  const pid = Number.parseInt(pidStr.trim(), 10);
28197
28535
  if (!Number.isNaN(pid)) {
28198
28536
  try {
@@ -28217,9 +28555,9 @@ var WorkspacePoolManager = class {
28217
28555
  * Returns false (no drift) if metadata.json doesn't exist (first use).
28218
28556
  */
28219
28557
  async checkDrift(poolDir, fingerprint) {
28220
- const metadataPath = path39.join(poolDir, "metadata.json");
28558
+ const metadataPath = path41.join(poolDir, "metadata.json");
28221
28559
  try {
28222
- const raw = await readFile10(metadataPath, "utf-8");
28560
+ const raw = await readFile12(metadataPath, "utf-8");
28223
28561
  const metadata = JSON.parse(raw);
28224
28562
  return metadata.fingerprint !== fingerprint;
28225
28563
  } catch {
@@ -28234,17 +28572,17 @@ var WorkspacePoolManager = class {
28234
28572
  repos,
28235
28573
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
28236
28574
  };
28237
- await writeFile7(path39.join(poolDir, "metadata.json"), JSON.stringify(metadata, null, 2));
28575
+ await writeFile7(path41.join(poolDir, "metadata.json"), JSON.stringify(metadata, null, 2));
28238
28576
  }
28239
28577
  /** Remove all slot directories and their lock files from a pool directory. */
28240
28578
  async removeAllSlots(poolDir) {
28241
- const entries = await readdir4(poolDir);
28579
+ const entries = await readdir5(poolDir);
28242
28580
  for (const entry of entries) {
28243
28581
  if (entry.startsWith("slot-") && !entry.endsWith(".lock")) {
28244
- const lockPath = path39.join(poolDir, `${entry}.lock`);
28582
+ const lockPath = path41.join(poolDir, `${entry}.lock`);
28245
28583
  if (existsSync2(lockPath)) {
28246
28584
  try {
28247
- const pidStr = await readFile10(lockPath, "utf-8");
28585
+ const pidStr = await readFile12(lockPath, "utf-8");
28248
28586
  const pid = Number.parseInt(pidStr.trim(), 10);
28249
28587
  if (!Number.isNaN(pid)) {
28250
28588
  try {
@@ -28257,12 +28595,12 @@ var WorkspacePoolManager = class {
28257
28595
  } catch {
28258
28596
  }
28259
28597
  }
28260
- await rm5(path39.join(poolDir, entry), { recursive: true, force: true });
28598
+ await rm5(path41.join(poolDir, entry), { recursive: true, force: true });
28261
28599
  await rm5(lockPath, { force: true }).catch(() => {
28262
28600
  });
28263
28601
  }
28264
28602
  }
28265
- await rm5(path39.join(poolDir, "metadata.json"), { force: true }).catch(() => {
28603
+ await rm5(path41.join(poolDir, "metadata.json"), { force: true }).catch(() => {
28266
28604
  });
28267
28605
  }
28268
28606
  /**
@@ -28272,7 +28610,7 @@ var WorkspacePoolManager = class {
28272
28610
  */
28273
28611
  async resetSlot(slotPath, templatePath, repos, poolReset = "fast") {
28274
28612
  for (const repo of repos) {
28275
- const repoDir = path39.join(slotPath, repo.path);
28613
+ const repoDir = path41.join(slotPath, repo.path);
28276
28614
  if (!existsSync2(repoDir)) {
28277
28615
  continue;
28278
28616
  }
@@ -28393,7 +28731,7 @@ ${lines.join("\n")}`;
28393
28731
  * Handles checkout, ref resolution, ancestor walking, shallow clone, sparse checkout.
28394
28732
  */
28395
28733
  async materialize(repo, workspacePath) {
28396
- const targetDir = path40.join(workspacePath, repo.path);
28734
+ const targetDir = path422.join(workspacePath, repo.path);
28397
28735
  const sourceUrl = getSourceUrl(repo.source);
28398
28736
  const startedAt = Date.now();
28399
28737
  if (this.verbose) {
@@ -28484,7 +28822,7 @@ ${lines.join("\n")}`;
28484
28822
  async reset(repos, workspacePath, reset) {
28485
28823
  const cleanFlag = reset === "strict" ? "-fdx" : "-fd";
28486
28824
  for (const repo of repos) {
28487
- const targetDir = path40.join(workspacePath, repo.path);
28825
+ const targetDir = path422.join(workspacePath, repo.path);
28488
28826
  await this.runGit(["reset", "--hard", "HEAD"], { cwd: targetDir });
28489
28827
  await this.runGit(["clean", cleanFlag], { cwd: targetDir });
28490
28828
  }
@@ -28494,30 +28832,30 @@ async function resolveWorkspaceTemplate(templatePath) {
28494
28832
  if (!templatePath) {
28495
28833
  return void 0;
28496
28834
  }
28497
- const resolved = path41.resolve(templatePath);
28498
- const stats = await stat6(resolved);
28835
+ const resolved = path43.resolve(templatePath);
28836
+ const stats = await stat7(resolved);
28499
28837
  if (stats.isFile()) {
28500
28838
  return {
28501
- dir: path41.dirname(resolved),
28839
+ dir: path43.dirname(resolved),
28502
28840
  workspaceFile: resolved
28503
28841
  };
28504
28842
  }
28505
28843
  if (!stats.isDirectory()) {
28506
28844
  throw new Error(`workspace template is neither a file nor a directory: ${resolved}`);
28507
28845
  }
28508
- const entries = await readdir5(resolved);
28846
+ const entries = await readdir6(resolved);
28509
28847
  const workspaceFiles = entries.filter((e) => e.endsWith(".code-workspace"));
28510
28848
  if (workspaceFiles.length === 1) {
28511
28849
  return {
28512
28850
  dir: resolved,
28513
- workspaceFile: path41.join(resolved, workspaceFiles[0])
28851
+ workspaceFile: path43.join(resolved, workspaceFiles[0])
28514
28852
  };
28515
28853
  }
28516
28854
  if (workspaceFiles.length > 1) {
28517
28855
  const conventionFile = workspaceFiles.find((f) => f === "template.code-workspace");
28518
28856
  return {
28519
28857
  dir: resolved,
28520
- workspaceFile: conventionFile ? path41.join(resolved, conventionFile) : void 0
28858
+ workspaceFile: conventionFile ? path43.join(resolved, conventionFile) : void 0
28521
28859
  };
28522
28860
  }
28523
28861
  return { dir: resolved };
@@ -28729,7 +29067,7 @@ async function runEvaluation(options) {
28729
29067
  ];
28730
29068
  const evaluatorRegistry = buildEvaluatorRegistry(evaluators, resolveGraderProvider);
28731
29069
  const typeRegistry = createBuiltinRegistry();
28732
- const discoveryBaseDir = evalFilePath ? path422.dirname(path422.resolve(evalFilePath)) : process.cwd();
29070
+ const discoveryBaseDir = evalFilePath ? path44.dirname(path44.resolve(evalFilePath)) : process.cwd();
28733
29071
  const evalDir = discoveryBaseDir;
28734
29072
  await discoverAssertions(typeRegistry, discoveryBaseDir);
28735
29073
  await discoverGraders(typeRegistry, discoveryBaseDir);
@@ -28869,11 +29207,11 @@ async function runEvaluation(options) {
28869
29207
  let staticMaterialised = false;
28870
29208
  if (useStaticWorkspace && configuredStaticPath) {
28871
29209
  const isYamlConfiguredPath = !cliWorkspacePath && !!yamlWorkspacePath;
28872
- const dirExists = await stat7(configuredStaticPath).then(
29210
+ const dirExists = await stat8(configuredStaticPath).then(
28873
29211
  (s) => s.isDirectory(),
28874
29212
  () => false
28875
29213
  );
28876
- const isEmpty = dirExists ? (await readdir6(configuredStaticPath)).length === 0 : false;
29214
+ const isEmpty = dirExists ? (await readdir7(configuredStaticPath)).length === 0 : false;
28877
29215
  if (isYamlConfiguredPath && (!dirExists || isEmpty)) {
28878
29216
  if (!dirExists) {
28879
29217
  await mkdir14(configuredStaticPath, { recursive: true });
@@ -28926,9 +29264,9 @@ async function runEvaluation(options) {
28926
29264
  }
28927
29265
  try {
28928
29266
  if (suiteWorkspaceFile && sharedWorkspacePath) {
28929
- const copiedWorkspaceFile = path422.join(sharedWorkspacePath, path422.basename(suiteWorkspaceFile));
29267
+ const copiedWorkspaceFile = path44.join(sharedWorkspacePath, path44.basename(suiteWorkspaceFile));
28930
29268
  try {
28931
- await stat7(copiedWorkspaceFile);
29269
+ await stat8(copiedWorkspaceFile);
28932
29270
  suiteWorkspaceFile = copiedWorkspaceFile;
28933
29271
  } catch {
28934
29272
  }
@@ -29508,9 +29846,9 @@ async function runEvalCase(options) {
29508
29846
  );
29509
29847
  }
29510
29848
  if (caseWorkspaceFile && workspacePath) {
29511
- const copiedFile = path422.join(workspacePath, path422.basename(caseWorkspaceFile));
29849
+ const copiedFile = path44.join(workspacePath, path44.basename(caseWorkspaceFile));
29512
29850
  try {
29513
- await stat7(copiedFile);
29851
+ await stat8(copiedFile);
29514
29852
  caseWorkspaceFile = copiedFile;
29515
29853
  } catch {
29516
29854
  }
@@ -29570,10 +29908,10 @@ async function runEvalCase(options) {
29570
29908
  const files = evalCase.metadata.agent_skills_files;
29571
29909
  if (baseDir && files.length > 0) {
29572
29910
  for (const relPath of files) {
29573
- const srcPath = path422.resolve(baseDir, relPath);
29574
- const destPath = path422.resolve(workspacePath, relPath);
29911
+ const srcPath = path44.resolve(baseDir, relPath);
29912
+ const destPath = path44.resolve(workspacePath, relPath);
29575
29913
  try {
29576
- await mkdir14(path422.dirname(destPath), { recursive: true });
29914
+ await mkdir14(path44.dirname(destPath), { recursive: true });
29577
29915
  await copyFile2(srcPath, destPath);
29578
29916
  } catch (error) {
29579
29917
  const message = error instanceof Error ? error.message : String(error);
@@ -30219,7 +30557,7 @@ async function runEvaluatorList(options) {
30219
30557
  fileChanges,
30220
30558
  workspacePath
30221
30559
  };
30222
- const evalFileDir = evalCase.file_paths[0] ? path422.dirname(evalCase.file_paths[0]) : process.cwd();
30560
+ const evalFileDir = evalCase.file_paths[0] ? path44.dirname(evalCase.file_paths[0]) : process.cwd();
30223
30561
  const dispatchContext = {
30224
30562
  graderProvider,
30225
30563
  targetResolver,
@@ -30582,7 +30920,7 @@ async function evaluate(config) {
30582
30920
  }
30583
30921
  const gitRoot = await findGitRoot(process.cwd());
30584
30922
  const repoRoot = gitRoot ?? process.cwd();
30585
- const testFilePath = config.specFile ? path43.resolve(config.specFile) : path43.join(process.cwd(), "__programmatic__.yaml");
30923
+ const testFilePath = config.specFile ? path45.resolve(config.specFile) : path45.join(process.cwd(), "__programmatic__.yaml");
30586
30924
  await loadEnvHierarchy(repoRoot, testFilePath);
30587
30925
  let resolvedTarget;
30588
30926
  let taskProvider;
@@ -30703,10 +31041,10 @@ function computeSummary(results, durationMs) {
30703
31041
  var TARGET_FILE_CANDIDATES = [".agentv/targets.yaml", ".agentv/targets.yml"];
30704
31042
  async function discoverDefaultTarget(repoRoot) {
30705
31043
  const cwd = process.cwd();
30706
- const chain = buildDirectoryChain(path43.join(cwd, "_placeholder"), repoRoot);
31044
+ const chain = buildDirectoryChain(path45.join(cwd, "_placeholder"), repoRoot);
30707
31045
  for (const dir of chain) {
30708
31046
  for (const candidate of TARGET_FILE_CANDIDATES) {
30709
- const targetsPath = path43.join(dir, candidate);
31047
+ const targetsPath = path45.join(dir, candidate);
30710
31048
  if (!existsSync4(targetsPath)) continue;
30711
31049
  try {
30712
31050
  const definitions = await readTargetDefinitions(targetsPath);
@@ -30723,7 +31061,7 @@ async function loadEnvHierarchy(repoRoot, startPath) {
30723
31061
  const chain = buildDirectoryChain(startPath, repoRoot);
30724
31062
  const envFiles = [];
30725
31063
  for (const dir of chain) {
30726
- const envPath = path43.join(dir, ".env");
31064
+ const envPath = path45.join(dir, ".env");
30727
31065
  if (existsSync4(envPath)) envFiles.push(envPath);
30728
31066
  }
30729
31067
  for (let i = 0; i < envFiles.length; i++) {
@@ -30902,7 +31240,7 @@ var ResponseCache = class {
30902
31240
  async get(key) {
30903
31241
  const filePath = this.keyToPath(key);
30904
31242
  try {
30905
- const data = await readFile11(filePath, "utf8");
31243
+ const data = await readFile13(filePath, "utf8");
30906
31244
  return JSON.parse(data);
30907
31245
  } catch {
30908
31246
  return void 0;
@@ -30910,13 +31248,13 @@ var ResponseCache = class {
30910
31248
  }
30911
31249
  async set(key, value) {
30912
31250
  const filePath = this.keyToPath(key);
30913
- const dir = path44.dirname(filePath);
31251
+ const dir = path46.dirname(filePath);
30914
31252
  await mkdir15(dir, { recursive: true });
30915
31253
  await writeFile8(filePath, JSON.stringify(value, null, 2), "utf8");
30916
31254
  }
30917
31255
  keyToPath(key) {
30918
31256
  const prefix = key.slice(0, 2);
30919
- return path44.join(this.cachePath, prefix, `${key}.json`);
31257
+ return path46.join(this.cachePath, prefix, `${key}.json`);
30920
31258
  }
30921
31259
  };
30922
31260
  function shouldEnableCache(params) {
@@ -31530,6 +31868,7 @@ export {
31530
31868
  subscribeToCodexLogEntries,
31531
31869
  consumeCopilotCliLogEntries,
31532
31870
  subscribeToCopilotCliLogEntries,
31871
+ discoverCopilotSessions,
31533
31872
  consumeCopilotSdkLogEntries,
31534
31873
  subscribeToCopilotSdkLogEntries,
31535
31874
  consumePiLogEntries,
@@ -31622,4 +31961,4 @@ export {
31622
31961
  OtelStreamingObserver,
31623
31962
  createAgentKernel
31624
31963
  };
31625
- //# sourceMappingURL=chunk-D3LNJUUB.js.map
31964
+ //# sourceMappingURL=chunk-3TBDSUYD.js.map