open-agents-ai 0.136.0 → 0.138.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.
Files changed (2) hide show
  1. package/dist/index.js +566 -353
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -9371,6 +9371,164 @@ ${lines.join("\n")}`,
9371
9371
  }
9372
9372
  });
9373
9373
 
9374
+ // packages/execution/dist/tools/image-generate.js
9375
+ import { writeFile as writeFile13, mkdir as mkdir9 } from "node:fs/promises";
9376
+ import { join as join24 } from "node:path";
9377
+ var ImageGenerateTool;
9378
+ var init_image_generate = __esm({
9379
+ "packages/execution/dist/tools/image-generate.js"() {
9380
+ "use strict";
9381
+ ImageGenerateTool = class {
9382
+ name = "generate_image";
9383
+ description = "Generate an image from a text prompt using a local Ollama diffusion model (e.g., x/z-image-turbo, x/flux2-klein). Saves the generated image as a PNG file and returns the file path. Requires an image gen model to be pulled in Ollama.";
9384
+ parameters = {
9385
+ type: "object",
9386
+ properties: {
9387
+ prompt: {
9388
+ type: "string",
9389
+ description: "Text description of the image to generate"
9390
+ },
9391
+ width: {
9392
+ type: "number",
9393
+ description: "Image width in pixels (default: 1024)"
9394
+ },
9395
+ height: {
9396
+ type: "number",
9397
+ description: "Image height in pixels (default: 1024)"
9398
+ },
9399
+ steps: {
9400
+ type: "number",
9401
+ description: "Number of diffusion steps (default: model default, ~20-30)"
9402
+ },
9403
+ model: {
9404
+ type: "string",
9405
+ description: "Specific image gen model to use (default: auto-detect best available)"
9406
+ }
9407
+ },
9408
+ required: ["prompt"]
9409
+ };
9410
+ cwd;
9411
+ ollamaUrl;
9412
+ cachedImageModel = null;
9413
+ constructor(cwd4, ollamaUrl = "http://localhost:11434") {
9414
+ this.cwd = cwd4;
9415
+ this.ollamaUrl = ollamaUrl;
9416
+ }
9417
+ async execute(args) {
9418
+ const prompt = String(args.prompt ?? "");
9419
+ const width = Number(args.width ?? 1024);
9420
+ const height = Number(args.height ?? 1024);
9421
+ const steps = args.steps ? Number(args.steps) : void 0;
9422
+ const requestedModel = args.model ? String(args.model) : void 0;
9423
+ const start = performance.now();
9424
+ if (!prompt.trim()) {
9425
+ return { success: false, output: "No prompt provided", error: "Empty prompt", durationMs: 0 };
9426
+ }
9427
+ try {
9428
+ const model = requestedModel ?? await this.findImageGenModel();
9429
+ if (!model) {
9430
+ return {
9431
+ success: false,
9432
+ output: "No image generation model available.\nPull one with: ollama pull x/z-image-turbo\nOr: ollama pull x/flux2-klein",
9433
+ error: "No image gen model",
9434
+ durationMs: performance.now() - start
9435
+ };
9436
+ }
9437
+ const body = {
9438
+ model,
9439
+ prompt,
9440
+ width,
9441
+ height,
9442
+ stream: false
9443
+ };
9444
+ if (steps)
9445
+ body.steps = steps;
9446
+ const resp = await fetch(`${this.ollamaUrl}/api/generate`, {
9447
+ method: "POST",
9448
+ headers: { "Content-Type": "application/json" },
9449
+ body: JSON.stringify(body),
9450
+ signal: AbortSignal.timeout(3e5)
9451
+ // 5 min timeout for image gen
9452
+ });
9453
+ if (!resp.ok) {
9454
+ const errText = await resp.text().catch(() => "");
9455
+ return {
9456
+ success: false,
9457
+ output: `Image generation failed: HTTP ${resp.status}
9458
+ ${errText.slice(0, 200)}`,
9459
+ durationMs: performance.now() - start
9460
+ };
9461
+ }
9462
+ const data = await resp.json();
9463
+ if (!data.image) {
9464
+ return {
9465
+ success: false,
9466
+ output: "No image data in response \u2014 model may not support image generation",
9467
+ durationMs: performance.now() - start
9468
+ };
9469
+ }
9470
+ const imgDir = join24(this.cwd, ".oa", "images");
9471
+ await mkdir9(imgDir, { recursive: true });
9472
+ const filename = `img-${Date.now()}.png`;
9473
+ const filepath = join24(imgDir, filename);
9474
+ const imgBuffer = Buffer.from(data.image, "base64");
9475
+ await writeFile13(filepath, imgBuffer);
9476
+ const sizeKB = Math.round(imgBuffer.length / 1024);
9477
+ return {
9478
+ success: true,
9479
+ output: `Image generated: ${filepath}
9480
+ Model: ${model}
9481
+ Size: ${width}x${height} (${sizeKB}KB)
9482
+ Prompt: "${prompt.slice(0, 80)}${prompt.length > 80 ? "..." : ""}"`,
9483
+ durationMs: performance.now() - start
9484
+ };
9485
+ } catch (err) {
9486
+ return {
9487
+ success: false,
9488
+ output: `Image generation error: ${err instanceof Error ? err.message : String(err)}`,
9489
+ durationMs: performance.now() - start
9490
+ };
9491
+ }
9492
+ }
9493
+ /** Find the best available image gen model on Ollama */
9494
+ async findImageGenModel() {
9495
+ if (this.cachedImageModel)
9496
+ return this.cachedImageModel;
9497
+ try {
9498
+ const resp = await fetch(`${this.ollamaUrl}/api/tags`, {
9499
+ signal: AbortSignal.timeout(5e3)
9500
+ });
9501
+ if (!resp.ok)
9502
+ return null;
9503
+ const data = await resp.json();
9504
+ const models = data.models ?? [];
9505
+ for (const m of models) {
9506
+ try {
9507
+ const showResp = await fetch(`${this.ollamaUrl}/api/show`, {
9508
+ method: "POST",
9509
+ headers: { "Content-Type": "application/json" },
9510
+ body: JSON.stringify({ model: m.name }),
9511
+ signal: AbortSignal.timeout(3e3)
9512
+ });
9513
+ if (!showResp.ok)
9514
+ continue;
9515
+ const showData = await showResp.json();
9516
+ if (showData.capabilities?.includes("image")) {
9517
+ this.cachedImageModel = m.name;
9518
+ return m.name;
9519
+ }
9520
+ } catch {
9521
+ continue;
9522
+ }
9523
+ }
9524
+ } catch {
9525
+ }
9526
+ return null;
9527
+ }
9528
+ };
9529
+ }
9530
+ });
9531
+
9374
9532
  // packages/execution/dist/tools/structured-read.js
9375
9533
  import { readFile as readFile13, stat as stat2 } from "node:fs/promises";
9376
9534
  import { resolve as resolve15, extname as extname5 } from "node:path";
@@ -9709,7 +9867,7 @@ ${parts.join("\n\n")}`,
9709
9867
  // packages/execution/dist/tools/vision.js
9710
9868
  import { readFileSync as readFileSync11, existsSync as existsSync14, statSync as statSync5 } from "node:fs";
9711
9869
  import { execSync as execSync10, spawn as spawn7 } from "node:child_process";
9712
- import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname6, join as join24 } from "node:path";
9870
+ import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname6, join as join25 } from "node:path";
9713
9871
  import { fileURLToPath as fileURLToPath2 } from "node:url";
9714
9872
  async function probeStation(endpoint) {
9715
9873
  try {
@@ -9724,7 +9882,7 @@ async function probeStation(endpoint) {
9724
9882
  }
9725
9883
  }
9726
9884
  function findStationBinary() {
9727
- const oaVenvPython = join24(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
9885
+ const oaVenvPython = join25(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
9728
9886
  if (existsSync14(oaVenvPython)) {
9729
9887
  try {
9730
9888
  execSync10(`${JSON.stringify(oaVenvPython)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
@@ -9732,7 +9890,7 @@ function findStationBinary() {
9732
9890
  } catch {
9733
9891
  }
9734
9892
  }
9735
- const oaVenvBin = join24(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "moondream-station");
9893
+ const oaVenvBin = join25(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "moondream-station");
9736
9894
  if (existsSync14(oaVenvBin))
9737
9895
  return oaVenvBin;
9738
9896
  const thisDir = dirname6(fileURLToPath2(import.meta.url));
@@ -10084,7 +10242,7 @@ ${response}`, durationMs: performance.now() - start };
10084
10242
  import { readFileSync as readFileSync12, existsSync as existsSync15 } from "node:fs";
10085
10243
  import { execSync as execSync11 } from "node:child_process";
10086
10244
  import { tmpdir as tmpdir4 } from "node:os";
10087
- import { join as join25, dirname as dirname7 } from "node:path";
10245
+ import { join as join26, dirname as dirname7 } from "node:path";
10088
10246
  import { fileURLToPath as fileURLToPath3 } from "node:url";
10089
10247
  function hasCommand2(cmd) {
10090
10248
  try {
@@ -10208,7 +10366,7 @@ for i in range(${clicks}):
10208
10366
  } catch {
10209
10367
  }
10210
10368
  try {
10211
- const venvPy = join25(__dirname2, "../../../../.moondream-venv/bin/python");
10369
+ const venvPy = join26(__dirname2, "../../../../.moondream-venv/bin/python");
10212
10370
  execSync11(`DISPLAY=:0 ${JSON.stringify(venvPy)} -c "${pyScript}"`, { stdio: "pipe", timeout: 5e3 });
10213
10371
  return;
10214
10372
  } catch {
@@ -10300,7 +10458,7 @@ var init_desktop_click = __esm({
10300
10458
  if (delayMs > 0) {
10301
10459
  await new Promise((r) => setTimeout(r, delayMs));
10302
10460
  }
10303
- const screenshotPath = join25(tmpdir4(), `oa-desktop-click-${Date.now()}.png`);
10461
+ const screenshotPath = join26(tmpdir4(), `oa-desktop-click-${Date.now()}.png`);
10304
10462
  captureScreenshot(screenshotPath);
10305
10463
  const dims = getImageDimensions2(screenshotPath);
10306
10464
  if (!dims) {
@@ -10475,7 +10633,7 @@ Screenshot: ${screenshotPath}`,
10475
10633
  if (delayMs > 0) {
10476
10634
  await new Promise((r) => setTimeout(r, delayMs));
10477
10635
  }
10478
- const screenshotPath = join25(tmpdir4(), `oa-desktop-describe-${Date.now()}.png`);
10636
+ const screenshotPath = join26(tmpdir4(), `oa-desktop-describe-${Date.now()}.png`);
10479
10637
  captureScreenshot(screenshotPath);
10480
10638
  const dims = getImageDimensions2(screenshotPath);
10481
10639
  const imageBuffer = readFileSync12(screenshotPath);
@@ -10714,7 +10872,7 @@ Language: ${language}
10714
10872
 
10715
10873
  // packages/execution/dist/tools/pdf-to-text.js
10716
10874
  import { existsSync as existsSync17, statSync as statSync7, readFileSync as readFileSync13, unlinkSync as unlinkSync3 } from "node:fs";
10717
- import { resolve as resolve18, basename as basename7, join as join26 } from "node:path";
10875
+ import { resolve as resolve18, basename as basename7, join as join27 } from "node:path";
10718
10876
  import { execSync as execSync13 } from "node:child_process";
10719
10877
  import { tmpdir as tmpdir5 } from "node:os";
10720
10878
  var PdfToTextTool;
@@ -10868,7 +11026,7 @@ ${text}`,
10868
11026
  if (!ocrCheck.available || !tesCheck.available || !gsCheck.available) {
10869
11027
  return null;
10870
11028
  }
10871
- const tmpPdf = join26(tmpdir5(), `oa-ocr-${Date.now()}.pdf`);
11029
+ const tmpPdf = join27(tmpdir5(), `oa-ocr-${Date.now()}.pdf`);
10872
11030
  try {
10873
11031
  const ocrCmd = `ocrmypdf -l ${language} --skip-text ${JSON.stringify(inputPath)} ${JSON.stringify(tmpPdf)}`;
10874
11032
  execSync13(ocrCmd, { stdio: "pipe", timeout: 6e5 });
@@ -10899,7 +11057,7 @@ ${text}`,
10899
11057
 
10900
11058
  // packages/execution/dist/tools/ocr-image-advanced.js
10901
11059
  import { existsSync as existsSync18, statSync as statSync8 } from "node:fs";
10902
- import { resolve as resolve19, basename as basename8, dirname as dirname8, join as join27 } from "node:path";
11060
+ import { resolve as resolve19, basename as basename8, dirname as dirname8, join as join28 } from "node:path";
10903
11061
  import { execSync as execSync14 } from "node:child_process";
10904
11062
  import { fileURLToPath as fileURLToPath4 } from "node:url";
10905
11063
  import { homedir as homedir7, tmpdir as tmpdir6 } from "node:os";
@@ -10917,7 +11075,7 @@ function findOcrScript() {
10917
11075
  return null;
10918
11076
  }
10919
11077
  function findPython() {
10920
- const venvPython = join27(homedir7(), ".open-agents", "venv", "bin", "python");
11078
+ const venvPython = join28(homedir7(), ".open-agents", "venv", "bin", "python");
10921
11079
  if (existsSync18(venvPython)) {
10922
11080
  try {
10923
11081
  execSync14(`${JSON.stringify(venvPython)} -c "import cv2, pytesseract, numpy, PIL"`, {
@@ -11063,7 +11221,7 @@ var init_ocr_image_advanced = __esm({
11063
11221
  cmdParts.push("--output-dir", JSON.stringify(resolve19(this.workingDir, outputDir)));
11064
11222
  let debugDir;
11065
11223
  if (debug) {
11066
- debugDir = join27(tmpdir6(), `oa-ocr-debug-${Date.now()}`);
11224
+ debugDir = join28(tmpdir6(), `oa-ocr-debug-${Date.now()}`);
11067
11225
  cmdParts.push("--debug-dir", debugDir);
11068
11226
  }
11069
11227
  try {
@@ -11162,7 +11320,7 @@ var init_ocr_image_advanced = __esm({
11162
11320
  if (region) {
11163
11321
  try {
11164
11322
  const [x, y, w, h] = region.split(",").map(Number);
11165
- const croppedPath = join27(tmpdir6(), `oa-ocr-crop-${Date.now()}.png`);
11323
+ const croppedPath = join28(tmpdir6(), `oa-ocr-crop-${Date.now()}.png`);
11166
11324
  execSync14(`convert ${JSON.stringify(imagePath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
11167
11325
  inputPath = croppedPath;
11168
11326
  } catch {
@@ -11203,18 +11361,18 @@ Note: Advanced Python pipeline not available \u2014 install pytesseract, opencv-
11203
11361
  // packages/execution/dist/tools/browser-action.js
11204
11362
  import { execSync as execSync15, spawn as spawn8 } from "node:child_process";
11205
11363
  import { existsSync as existsSync19, readFileSync as readFileSync14 } from "node:fs";
11206
- import { join as join28, dirname as dirname9 } from "node:path";
11364
+ import { join as join29, dirname as dirname9 } from "node:path";
11207
11365
  import { fileURLToPath as fileURLToPath5 } from "node:url";
11208
11366
  function findScrapeScript() {
11209
11367
  const candidates = [
11210
11368
  // Published npm package: dist/scripts/web_scrape.py
11211
- join28(__dirname3, "scripts", "web_scrape.py"),
11369
+ join29(__dirname3, "scripts", "web_scrape.py"),
11212
11370
  // Published npm package (from node_modules): node_modules/open-agents-ai/dist/scripts/
11213
- join28(__dirname3, "..", "node_modules", "open-agents-ai", "dist", "scripts", "web_scrape.py"),
11371
+ join29(__dirname3, "..", "node_modules", "open-agents-ai", "dist", "scripts", "web_scrape.py"),
11214
11372
  // Dev monorepo: packages/execution/src/tools/../../scripts/
11215
- join28(__dirname3, "..", "..", "scripts", "web_scrape.py"),
11373
+ join29(__dirname3, "..", "..", "scripts", "web_scrape.py"),
11216
11374
  // Dev monorepo alt: packages/execution/scripts/
11217
- join28(__dirname3, "..", "scripts", "web_scrape.py")
11375
+ join29(__dirname3, "..", "scripts", "web_scrape.py")
11218
11376
  ];
11219
11377
  return candidates.find((p) => existsSync19(p)) || candidates[0];
11220
11378
  }
@@ -11469,7 +11627,7 @@ var init_browser_action = __esm({
11469
11627
  // packages/execution/dist/tools/autoresearch.js
11470
11628
  import { execSync as execSync16, spawn as spawn9 } from "node:child_process";
11471
11629
  import { existsSync as existsSync20, readFileSync as readFileSync15, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6, appendFileSync, copyFileSync } from "node:fs";
11472
- import { join as join29, resolve as resolve20, dirname as dirname10 } from "node:path";
11630
+ import { join as join30, resolve as resolve20, dirname as dirname10 } from "node:path";
11473
11631
  import { fileURLToPath as fileURLToPath6 } from "node:url";
11474
11632
  function findAutoresearchScript(scriptName) {
11475
11633
  const thisDir = dirname10(fileURLToPath6(import.meta.url));
@@ -11571,7 +11729,7 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
11571
11729
  async execute(args) {
11572
11730
  const start = Date.now();
11573
11731
  const action = String(args["action"] ?? "status");
11574
- const workspacePath = String(args["workspace"] ?? join29(this.repoRoot, ".oa", "autoresearch"));
11732
+ const workspacePath = String(args["workspace"] ?? join30(this.repoRoot, ".oa", "autoresearch"));
11575
11733
  try {
11576
11734
  switch (action) {
11577
11735
  case "setup":
@@ -11612,13 +11770,13 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
11612
11770
  const prepareScript = findAutoresearchScript("autoresearch-prepare.py");
11613
11771
  const trainScript = findAutoresearchScript("autoresearch-train.py");
11614
11772
  if (prepareScript) {
11615
- copyFileSync(prepareScript, join29(workspace, "prepare.py"));
11773
+ copyFileSync(prepareScript, join30(workspace, "prepare.py"));
11616
11774
  output.push("Copied prepare.py template");
11617
11775
  } else {
11618
11776
  return { success: false, output: output.join("\n"), error: "autoresearch-prepare.py template not found in distribution", durationMs: Date.now() - start };
11619
11777
  }
11620
11778
  if (trainScript) {
11621
- copyFileSync(trainScript, join29(workspace, "train.py"));
11779
+ copyFileSync(trainScript, join30(workspace, "train.py"));
11622
11780
  output.push("Copied train.py template");
11623
11781
  } else {
11624
11782
  return { success: false, output: output.join("\n"), error: "autoresearch-train.py template not found in distribution", durationMs: Date.now() - start };
@@ -11650,7 +11808,7 @@ name = "pytorch-cu128"
11650
11808
  url = "https://download.pytorch.org/whl/cu128"
11651
11809
  explicit = true
11652
11810
  `;
11653
- writeFileSync6(join29(workspace, "pyproject.toml"), pyprojectContent, "utf-8");
11811
+ writeFileSync6(join30(workspace, "pyproject.toml"), pyprojectContent, "utf-8");
11654
11812
  output.push("Created pyproject.toml");
11655
11813
  try {
11656
11814
  execSync16("git rev-parse --git-dir", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
@@ -11692,7 +11850,7 @@ explicit = true
11692
11850
  const e = err;
11693
11851
  output.push(`Data prep warning: ${(e.stderr ?? e.stdout ?? "failed").slice(0, 500)}`);
11694
11852
  }
11695
- const tsvPath = join29(workspace, "results.tsv");
11853
+ const tsvPath = join30(workspace, "results.tsv");
11696
11854
  if (!existsSync20(tsvPath)) {
11697
11855
  writeFileSync6(tsvPath, "commit val_bpb memory_gb status description\n", "utf-8");
11698
11856
  output.push("Created results.tsv");
@@ -11714,10 +11872,10 @@ Next steps:
11714
11872
  }
11715
11873
  // ── Run experiment ─────────────────────────────────────────────────────
11716
11874
  async run(workspace, args, start) {
11717
- if (!existsSync20(join29(workspace, "train.py"))) {
11875
+ if (!existsSync20(join30(workspace, "train.py"))) {
11718
11876
  return { success: false, output: "", error: `No train.py found in ${workspace}. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
11719
11877
  }
11720
- if (!existsSync20(join29(workspace, ".venv")) && existsSync20(join29(workspace, "pyproject.toml"))) {
11878
+ if (!existsSync20(join30(workspace, ".venv")) && existsSync20(join30(workspace, "pyproject.toml"))) {
11721
11879
  try {
11722
11880
  execSync16("uv sync 2>&1", { cwd: workspace, encoding: "utf-8", timeout: 3e5 });
11723
11881
  } catch {
@@ -11725,7 +11883,7 @@ Next steps:
11725
11883
  }
11726
11884
  const timeoutMin = Number(args["timeout_minutes"] ?? 10);
11727
11885
  const timeoutMs = timeoutMin * 60 * 1e3;
11728
- const logPath = join29(workspace, "run.log");
11886
+ const logPath = join30(workspace, "run.log");
11729
11887
  return new Promise((resolveResult) => {
11730
11888
  const proc = spawn9("uv", ["run", "train.py"], {
11731
11889
  cwd: workspace,
@@ -11796,7 +11954,7 @@ ${fullLog.slice(-2e3)}`,
11796
11954
  return;
11797
11955
  }
11798
11956
  try {
11799
- writeFileSync6(join29(workspace, ".last-result.json"), JSON.stringify(result, null, 2), "utf-8");
11957
+ writeFileSync6(join30(workspace, ".last-result.json"), JSON.stringify(result, null, 2), "utf-8");
11800
11958
  } catch {
11801
11959
  }
11802
11960
  const memGB = (result.peak_vram_mb / 1024).toFixed(1);
@@ -11832,7 +11990,7 @@ ${fullLog.slice(-2e3)}`,
11832
11990
  }
11833
11991
  // ── Results ────────────────────────────────────────────────────────────
11834
11992
  getResults(workspace, start) {
11835
- const tsvPath = join29(workspace, "results.tsv");
11993
+ const tsvPath = join30(workspace, "results.tsv");
11836
11994
  if (!existsSync20(tsvPath)) {
11837
11995
  return { success: false, output: "", error: `No results.tsv found. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
11838
11996
  }
@@ -11859,7 +12017,7 @@ ${fullLog.slice(-2e3)}`,
11859
12017
  // ── Status ─────────────────────────────────────────────────────────────
11860
12018
  getStatus(workspace, start) {
11861
12019
  const output = [];
11862
- if (!existsSync20(join29(workspace, "train.py"))) {
12020
+ if (!existsSync20(join30(workspace, "train.py"))) {
11863
12021
  return {
11864
12022
  success: true,
11865
12023
  output: `Autoresearch workspace not initialized at ${workspace}.
@@ -11882,7 +12040,7 @@ Run autoresearch(action="setup") to begin.`,
11882
12040
  } catch {
11883
12041
  output.push("GPU: not detected");
11884
12042
  }
11885
- const lastResultPath = join29(workspace, ".last-result.json");
12043
+ const lastResultPath = join30(workspace, ".last-result.json");
11886
12044
  if (existsSync20(lastResultPath)) {
11887
12045
  try {
11888
12046
  const last = JSON.parse(readFileSync15(lastResultPath, "utf-8"));
@@ -11890,20 +12048,20 @@ Run autoresearch(action="setup") to begin.`,
11890
12048
  } catch {
11891
12049
  }
11892
12050
  }
11893
- const tsvPath = join29(workspace, "results.tsv");
12051
+ const tsvPath = join30(workspace, "results.tsv");
11894
12052
  if (existsSync20(tsvPath)) {
11895
12053
  const lines = readFileSync15(tsvPath, "utf-8").trim().split("\n");
11896
12054
  output.push(`Experiments recorded: ${lines.length - 1}`);
11897
12055
  }
11898
- const cacheDir = join29(process.env["HOME"] ?? "~", ".cache", "autoresearch");
12056
+ const cacheDir = join30(process.env["HOME"] ?? "~", ".cache", "autoresearch");
11899
12057
  output.push(`Data cache: ${existsSync20(cacheDir) ? "present" : "not found"} (${cacheDir})`);
11900
12058
  return { success: true, output: output.join("\n"), durationMs: Date.now() - start };
11901
12059
  }
11902
12060
  // ── Keep / Discard ─────────────────────────────────────────────────────
11903
12061
  keepExperiment(workspace, args, start) {
11904
12062
  const desc = String(args["description"] ?? "experiment");
11905
- const tsvPath = join29(workspace, "results.tsv");
11906
- const lastResultPath = join29(workspace, ".last-result.json");
12063
+ const tsvPath = join30(workspace, "results.tsv");
12064
+ const lastResultPath = join30(workspace, ".last-result.json");
11907
12065
  let valBpb = args["val_bpb"];
11908
12066
  let memGb = args["memory_gb"];
11909
12067
  if ((valBpb === void 0 || memGb === void 0) && existsSync20(lastResultPath)) {
@@ -11941,8 +12099,8 @@ Branch advanced. Ready for next experiment.`,
11941
12099
  }
11942
12100
  discardExperiment(workspace, args, start) {
11943
12101
  const desc = String(args["description"] ?? "experiment");
11944
- const tsvPath = join29(workspace, "results.tsv");
11945
- const lastResultPath = join29(workspace, ".last-result.json");
12102
+ const tsvPath = join30(workspace, "results.tsv");
12103
+ const lastResultPath = join30(workspace, ".last-result.json");
11946
12104
  let valBpb = args["val_bpb"];
11947
12105
  let memGb = args["memory_gb"];
11948
12106
  if ((valBpb === void 0 || memGb === void 0) && existsSync20(lastResultPath)) {
@@ -11988,8 +12146,8 @@ train.py reverted to last kept state. Ready for next experiment.`,
11988
12146
 
11989
12147
  // packages/execution/dist/tools/scheduler.js
11990
12148
  import { execSync as execSync17, exec as execCb } from "node:child_process";
11991
- import { readFile as readFile14, writeFile as writeFile13, mkdir as mkdir9 } from "node:fs/promises";
11992
- import { resolve as resolve21, join as join30 } from "node:path";
12149
+ import { readFile as readFile14, writeFile as writeFile14, mkdir as mkdir10 } from "node:fs/promises";
12150
+ import { resolve as resolve21, join as join31 } from "node:path";
11993
12151
  import { randomBytes as randomBytes3 } from "node:crypto";
11994
12152
  function isValidCron(expr) {
11995
12153
  const parts = expr.trim().split(/\s+/);
@@ -12073,7 +12231,7 @@ function installCronJob(task, workingDir) {
12073
12231
  const lines = getCurrentCrontab();
12074
12232
  const oaBin = findOaBinary();
12075
12233
  const logDir = resolve21(workingDir, ".oa", "scheduled", "logs");
12076
- const logFile = join30(logDir, `${task.id}.log`);
12234
+ const logFile = join31(logDir, `${task.id}.log`);
12077
12235
  const storeFile = resolve21(workingDir, ".oa", "scheduled", "tasks.json");
12078
12236
  const taskEscaped = task.task.replace(/'/g, "'\\''");
12079
12237
  const taskId = task.id;
@@ -12114,10 +12272,10 @@ async function loadStore(workingDir) {
12114
12272
  }
12115
12273
  async function saveStore(workingDir, store) {
12116
12274
  const dir = resolve21(workingDir, ".oa", "scheduled");
12117
- await mkdir9(dir, { recursive: true });
12118
- await mkdir9(join30(dir, "logs"), { recursive: true });
12275
+ await mkdir10(dir, { recursive: true });
12276
+ await mkdir10(join31(dir, "logs"), { recursive: true });
12119
12277
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
12120
- await writeFile13(join30(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
12278
+ await writeFile14(join31(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
12121
12279
  }
12122
12280
  var SCHEDULE_PRESETS, CRON_MARKER, SchedulerTool;
12123
12281
  var init_scheduler = __esm({
@@ -12350,8 +12508,8 @@ ${truncated}`, durationMs: performance.now() - start };
12350
12508
  });
12351
12509
 
12352
12510
  // packages/execution/dist/tools/reminder.js
12353
- import { readFile as readFile15, writeFile as writeFile14, mkdir as mkdir10 } from "node:fs/promises";
12354
- import { resolve as resolve22, join as join31 } from "node:path";
12511
+ import { readFile as readFile15, writeFile as writeFile15, mkdir as mkdir11 } from "node:fs/promises";
12512
+ import { resolve as resolve22, join as join32 } from "node:path";
12355
12513
  import { randomBytes as randomBytes4 } from "node:crypto";
12356
12514
  function parseDueTime(due) {
12357
12515
  const lower = due.toLowerCase().trim();
@@ -12402,8 +12560,8 @@ function parseDueTime(due) {
12402
12560
  }
12403
12561
  async function getStorePath(workingDir) {
12404
12562
  const dir = resolve22(workingDir, ".oa", "scheduled");
12405
- await mkdir10(dir, { recursive: true });
12406
- return join31(dir, STORE_FILE);
12563
+ await mkdir11(dir, { recursive: true });
12564
+ return join32(dir, STORE_FILE);
12407
12565
  }
12408
12566
  async function loadReminderStore(workingDir) {
12409
12567
  const storePath = await getStorePath(workingDir);
@@ -12417,7 +12575,7 @@ async function loadReminderStore(workingDir) {
12417
12575
  async function saveReminderStore(workingDir, store) {
12418
12576
  const storePath = await getStorePath(workingDir);
12419
12577
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
12420
- await writeFile14(storePath, JSON.stringify(store, null, 2), "utf-8");
12578
+ await writeFile15(storePath, JSON.stringify(store, null, 2), "utf-8");
12421
12579
  }
12422
12580
  async function getDueReminders(workingDir) {
12423
12581
  const store = await loadReminderStore(workingDir);
@@ -12663,8 +12821,8 @@ var init_reminder = __esm({
12663
12821
  });
12664
12822
 
12665
12823
  // packages/execution/dist/tools/agenda.js
12666
- import { readFile as readFile16, writeFile as writeFile15, mkdir as mkdir11 } from "node:fs/promises";
12667
- import { resolve as resolve23, join as join32 } from "node:path";
12824
+ import { readFile as readFile16, writeFile as writeFile16, mkdir as mkdir12 } from "node:fs/promises";
12825
+ import { resolve as resolve23, join as join33 } from "node:path";
12668
12826
  import { randomBytes as randomBytes5 } from "node:crypto";
12669
12827
  async function loadAttentionStore(workingDir) {
12670
12828
  const storePath = resolve23(workingDir, ".oa", "scheduled", "attention.json");
@@ -12677,9 +12835,9 @@ async function loadAttentionStore(workingDir) {
12677
12835
  }
12678
12836
  async function saveAttentionStore(workingDir, store) {
12679
12837
  const dir = resolve23(workingDir, ".oa", "scheduled");
12680
- await mkdir11(dir, { recursive: true });
12838
+ await mkdir12(dir, { recursive: true });
12681
12839
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
12682
- await writeFile15(join32(dir, "attention.json"), JSON.stringify(store, null, 2), "utf-8");
12840
+ await writeFile16(join33(dir, "attention.json"), JSON.stringify(store, null, 2), "utf-8");
12683
12841
  }
12684
12842
  async function getActiveAttentionItems(workingDir) {
12685
12843
  const store = await loadAttentionStore(workingDir);
@@ -12989,7 +13147,7 @@ ${sections.join("\n")}`,
12989
13147
  // packages/execution/dist/tools/opencode.js
12990
13148
  import { execSync as execSync18, spawn as spawn10 } from "node:child_process";
12991
13149
  import { existsSync as existsSync21 } from "node:fs";
12992
- import { join as join33, resolve as resolve24 } from "node:path";
13150
+ import { join as join34, resolve as resolve24 } from "node:path";
12993
13151
  function findOpencode() {
12994
13152
  for (const cmd of ["opencode"]) {
12995
13153
  try {
@@ -13001,8 +13159,8 @@ function findOpencode() {
13001
13159
  }
13002
13160
  const homeDir = process.env.HOME || process.env.USERPROFILE || "";
13003
13161
  const candidates = [
13004
- join33(homeDir, ".opencode", "bin", "opencode"),
13005
- join33(homeDir, "bin", "opencode"),
13162
+ join34(homeDir, ".opencode", "bin", "opencode"),
13163
+ join34(homeDir, "bin", "opencode"),
13006
13164
  "/usr/local/bin/opencode"
13007
13165
  ];
13008
13166
  for (const p of candidates) {
@@ -13263,7 +13421,7 @@ var init_opencode = __esm({
13263
13421
  // packages/execution/dist/tools/factory.js
13264
13422
  import { execSync as execSync19, spawn as spawn11 } from "node:child_process";
13265
13423
  import { existsSync as existsSync22 } from "node:fs";
13266
- import { join as join34 } from "node:path";
13424
+ import { join as join35 } from "node:path";
13267
13425
  function findDroid() {
13268
13426
  for (const cmd of ["droid"]) {
13269
13427
  try {
@@ -13275,8 +13433,8 @@ function findDroid() {
13275
13433
  }
13276
13434
  const homeDir = process.env.HOME || process.env.USERPROFILE || "";
13277
13435
  const candidates = [
13278
- join34(homeDir, ".factory", "bin", "droid"),
13279
- join34(homeDir, "bin", "droid"),
13436
+ join35(homeDir, ".factory", "bin", "droid"),
13437
+ join35(homeDir, "bin", "droid"),
13280
13438
  "/usr/local/bin/droid"
13281
13439
  ];
13282
13440
  for (const p of candidates) {
@@ -13571,8 +13729,8 @@ var init_factory = __esm({
13571
13729
 
13572
13730
  // packages/execution/dist/tools/cron-agent.js
13573
13731
  import { execSync as execSync20 } from "node:child_process";
13574
- import { readFile as readFile17, writeFile as writeFile16, mkdir as mkdir12 } from "node:fs/promises";
13575
- import { resolve as resolve25, join as join35 } from "node:path";
13732
+ import { readFile as readFile17, writeFile as writeFile17, mkdir as mkdir13 } from "node:fs/promises";
13733
+ import { resolve as resolve25, join as join36 } from "node:path";
13576
13734
  import { randomBytes as randomBytes6 } from "node:crypto";
13577
13735
  function isValidCron2(expr) {
13578
13736
  const parts = expr.trim().split(/\s+/);
@@ -13658,7 +13816,7 @@ function installCronAgentJob(job, workingDir) {
13658
13816
  const lines = getCurrentCrontab2();
13659
13817
  const oaBin = findOaBinary2();
13660
13818
  const logDir = resolve25(workingDir, ".oa", "cron-agents", "logs");
13661
- const logFile = join35(logDir, `${job.id}.log`);
13819
+ const logFile = join36(logDir, `${job.id}.log`);
13662
13820
  const storeFile = resolve25(workingDir, ".oa", "cron-agents", "store.json");
13663
13821
  const taskEscaped = job.task.replace(/'/g, "'\\''");
13664
13822
  const jobId = job.id;
@@ -13696,10 +13854,10 @@ async function loadStore2(workingDir) {
13696
13854
  }
13697
13855
  async function saveStore2(workingDir, store) {
13698
13856
  const dir = resolve25(workingDir, ".oa", "cron-agents");
13699
- await mkdir12(dir, { recursive: true });
13700
- await mkdir12(join35(dir, "logs"), { recursive: true });
13857
+ await mkdir13(dir, { recursive: true });
13858
+ await mkdir13(join36(dir, "logs"), { recursive: true });
13701
13859
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
13702
- await writeFile16(join35(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
13860
+ await writeFile17(join36(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
13703
13861
  }
13704
13862
  var LONG_HORIZON_PRESETS, CRON_AGENT_MARKER, CronAgentTool;
13705
13863
  var init_cron_agent = __esm({
@@ -14035,9 +14193,9 @@ ${truncated}`, durationMs: performance.now() - start };
14035
14193
  });
14036
14194
 
14037
14195
  // packages/execution/dist/tools/nexus.js
14038
- import { readFile as readFile18, writeFile as writeFile17, mkdir as mkdir13, chmod, unlink, readdir as readdir4, open as fsOpen } from "node:fs/promises";
14196
+ import { readFile as readFile18, writeFile as writeFile18, mkdir as mkdir14, chmod, unlink, readdir as readdir4, open as fsOpen } from "node:fs/promises";
14039
14197
  import { existsSync as existsSync23, readFileSync as readFileSync16, watch as fsWatchLocal } from "node:fs";
14040
- import { resolve as resolve26, join as join36 } from "node:path";
14198
+ import { resolve as resolve26, join as join37 } from "node:path";
14041
14199
  import { randomBytes as randomBytes7, createCipheriv, createDecipheriv, scryptSync, createHash } from "node:crypto";
14042
14200
  import { execSync as execSync21, spawn as spawn12 } from "node:child_process";
14043
14201
  import { hostname, userInfo } from "node:os";
@@ -16011,7 +16169,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16011
16169
  }
16012
16170
  async ensureDir() {
16013
16171
  if (!existsSync23(this.nexusDir)) {
16014
- await mkdir13(this.nexusDir, { recursive: true });
16172
+ await mkdir14(this.nexusDir, { recursive: true });
16015
16173
  }
16016
16174
  }
16017
16175
  async execute(args) {
@@ -16134,7 +16292,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16134
16292
  // Daemon management
16135
16293
  // =========================================================================
16136
16294
  getDaemonPid() {
16137
- const pidFile = join36(this.nexusDir, "daemon.pid");
16295
+ const pidFile = join37(this.nexusDir, "daemon.pid");
16138
16296
  if (!existsSync23(pidFile))
16139
16297
  return null;
16140
16298
  try {
@@ -16160,12 +16318,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16160
16318
  throw new Error("Nexus daemon not running. Use action 'connect' first.");
16161
16319
  }
16162
16320
  const cmdId = randomBytes7(8).toString("hex");
16163
- const cmdFile = join36(this.nexusDir, "cmd.json");
16164
- const respFile = join36(this.nexusDir, "resp.json");
16321
+ const cmdFile = join37(this.nexusDir, "cmd.json");
16322
+ const respFile = join37(this.nexusDir, "resp.json");
16165
16323
  if (existsSync23(respFile))
16166
16324
  await unlink(respFile).catch(() => {
16167
16325
  });
16168
- await writeFile17(cmdFile, JSON.stringify({ id: cmdId, action, args }, null, 2));
16326
+ await writeFile18(cmdFile, JSON.stringify({ id: cmdId, action, args }, null, 2));
16169
16327
  const pollMs = 50;
16170
16328
  const polls = Math.ceil(timeoutMs / pollMs);
16171
16329
  let resolved = false;
@@ -16245,7 +16403,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16245
16403
  const currentScriptHash = createHash("sha256").update(DAEMON_SCRIPT).digest("hex").slice(0, 16);
16246
16404
  const existingPid = this.getDaemonPid();
16247
16405
  if (existingPid) {
16248
- const daemonPath2 = join36(this.nexusDir, "nexus-daemon.mjs");
16406
+ const daemonPath2 = join37(this.nexusDir, "nexus-daemon.mjs");
16249
16407
  let needsRestart = true;
16250
16408
  if (existsSync23(daemonPath2)) {
16251
16409
  try {
@@ -16269,13 +16427,13 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16269
16427
  } catch {
16270
16428
  }
16271
16429
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
16272
- const p = join36(this.nexusDir, f);
16430
+ const p = join37(this.nexusDir, f);
16273
16431
  if (existsSync23(p))
16274
16432
  await unlink(p).catch(() => {
16275
16433
  });
16276
16434
  }
16277
16435
  } else {
16278
- const statusFile2 = join36(this.nexusDir, "status.json");
16436
+ const statusFile2 = join37(this.nexusDir, "status.json");
16279
16437
  if (existsSync23(statusFile2)) {
16280
16438
  try {
16281
16439
  const status = JSON.parse(await readFile18(statusFile2, "utf8"));
@@ -16294,7 +16452,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16294
16452
  }
16295
16453
  }
16296
16454
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
16297
- const p = join36(this.nexusDir, f);
16455
+ const p = join37(this.nexusDir, f);
16298
16456
  if (existsSync23(p))
16299
16457
  await unlink(p).catch(() => {
16300
16458
  });
@@ -16332,7 +16490,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16332
16490
  });
16333
16491
  });
16334
16492
  try {
16335
- const nexusPkg = join36(nodeModulesDir, "open-agents-nexus", "package.json");
16493
+ const nexusPkg = join37(nodeModulesDir, "open-agents-nexus", "package.json");
16336
16494
  if (existsSync23(nexusPkg)) {
16337
16495
  nexusResolved = true;
16338
16496
  try {
@@ -16343,7 +16501,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16343
16501
  } else {
16344
16502
  try {
16345
16503
  const globalDir = await execAsync2("npm root -g", { timeout: 5e3 });
16346
- const globalPkg = join36(globalDir, "open-agents-nexus", "package.json");
16504
+ const globalPkg = join37(globalDir, "open-agents-nexus", "package.json");
16347
16505
  if (existsSync23(globalPkg)) {
16348
16506
  nexusResolved = true;
16349
16507
  try {
@@ -16388,8 +16546,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16388
16546
  }
16389
16547
  }
16390
16548
  await this.ensureWallet();
16391
- const daemonPath = join36(this.nexusDir, "nexus-daemon.mjs");
16392
- await writeFile17(daemonPath, DAEMON_SCRIPT);
16549
+ const daemonPath = join37(this.nexusDir, "nexus-daemon.mjs");
16550
+ await writeFile18(daemonPath, DAEMON_SCRIPT);
16393
16551
  const agentName = args.agent_name || "oa-" + hostname().slice(0, 12) + "-" + process.pid;
16394
16552
  const agentType = args.agent_type || "general";
16395
16553
  const nodePaths = [nodeModulesDir];
@@ -16399,8 +16557,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16399
16557
  } catch {
16400
16558
  }
16401
16559
  const { openSync: openSync2, closeSync: closeSync2 } = await import("node:fs");
16402
- const daemonLogPath = join36(this.nexusDir, "daemon.log");
16403
- const daemonErrPath = join36(this.nexusDir, "daemon.err");
16560
+ const daemonLogPath = join37(this.nexusDir, "daemon.log");
16561
+ const daemonErrPath = join37(this.nexusDir, "daemon.err");
16404
16562
  const outFd = openSync2(daemonLogPath, "w");
16405
16563
  const errFd = openSync2(daemonErrPath, "w");
16406
16564
  const child = spawn12("node", [daemonPath, this.nexusDir, agentName, agentType], {
@@ -16418,7 +16576,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16418
16576
  closeSync2(errFd);
16419
16577
  } catch {
16420
16578
  }
16421
- const statusFile = join36(this.nexusDir, "status.json");
16579
+ const statusFile = join37(this.nexusDir, "status.json");
16422
16580
  for (let i = 0; i < 40; i++) {
16423
16581
  await new Promise((r) => setTimeout(r, 500));
16424
16582
  if (existsSync23(statusFile)) {
@@ -16477,7 +16635,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16477
16635
  } catch {
16478
16636
  }
16479
16637
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
16480
- const p = join36(this.nexusDir, f);
16638
+ const p = join37(this.nexusDir, f);
16481
16639
  if (existsSync23(p))
16482
16640
  await unlink(p).catch(() => {
16483
16641
  });
@@ -16488,7 +16646,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16488
16646
  const pid = this.getDaemonPid();
16489
16647
  if (!pid)
16490
16648
  return "Nexus daemon not running. Use action 'connect' to start.";
16491
- const statusFile = join36(this.nexusDir, "status.json");
16649
+ const statusFile = join37(this.nexusDir, "status.json");
16492
16650
  if (!existsSync23(statusFile))
16493
16651
  return `Daemon running (pid: ${pid}) but no status yet.`;
16494
16652
  try {
@@ -16503,7 +16661,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16503
16661
  ` Capabilities: ${(status.capabilities || []).length ? (status.capabilities || []).join(", ") : "none"}`,
16504
16662
  ` Blocked peers: ${(status.blockedPeers || []).length || 0}`
16505
16663
  ];
16506
- const walletPath = join36(this.nexusDir, "wallet.enc");
16664
+ const walletPath = join37(this.nexusDir, "wallet.enc");
16507
16665
  if (existsSync23(walletPath)) {
16508
16666
  try {
16509
16667
  const w = JSON.parse(await readFile18(walletPath, "utf8"));
@@ -16514,14 +16672,14 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16514
16672
  } else {
16515
16673
  lines.push(` Wallet: not configured`);
16516
16674
  }
16517
- const inboxDir = join36(this.nexusDir, "inbox");
16675
+ const inboxDir = join37(this.nexusDir, "inbox");
16518
16676
  if (existsSync23(inboxDir)) {
16519
16677
  try {
16520
16678
  const roomDirs = await readdir4(inboxDir);
16521
16679
  let totalMsgs = 0;
16522
16680
  for (const rd of roomDirs) {
16523
16681
  try {
16524
- totalMsgs += (await readdir4(join36(inboxDir, rd))).length;
16682
+ totalMsgs += (await readdir4(join37(inboxDir, rd))).length;
16525
16683
  } catch {
16526
16684
  }
16527
16685
  }
@@ -16568,9 +16726,9 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16568
16726
  }
16569
16727
  async doReadMessages(args) {
16570
16728
  const roomId = args.room_id;
16571
- const inboxDir = join36(this.nexusDir, "inbox");
16729
+ const inboxDir = join37(this.nexusDir, "inbox");
16572
16730
  if (roomId) {
16573
- const roomInbox = join36(inboxDir, roomId);
16731
+ const roomInbox = join37(inboxDir, roomId);
16574
16732
  if (!existsSync23(roomInbox))
16575
16733
  return `No messages in room: ${roomId}`;
16576
16734
  const files = (await readdir4(roomInbox)).sort().slice(-20);
@@ -16579,7 +16737,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16579
16737
  const messages = [`Messages in ${roomId} (last ${files.length}):`];
16580
16738
  for (const f of files) {
16581
16739
  try {
16582
- const msg = JSON.parse(await readFile18(join36(roomInbox, f), "utf8"));
16740
+ const msg = JSON.parse(await readFile18(join37(roomInbox, f), "utf8"));
16583
16741
  const sender = (msg.sender || "unknown").slice(0, 12);
16584
16742
  messages.push(` [${new Date(msg.timestamp).toLocaleTimeString()}] ${sender}...: ${msg.content}`);
16585
16743
  } catch {
@@ -16595,7 +16753,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16595
16753
  const lines = ["Inbox:"];
16596
16754
  for (const rd of roomDirs) {
16597
16755
  try {
16598
- const count = (await readdir4(join36(inboxDir, rd))).length;
16756
+ const count = (await readdir4(join37(inboxDir, rd))).length;
16599
16757
  lines.push(` ${rd}: ${count} message(s)`);
16600
16758
  } catch {
16601
16759
  }
@@ -16607,7 +16765,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16607
16765
  // ---------------------------------------------------------------------------
16608
16766
  async doWalletStatus() {
16609
16767
  await this.ensureDir();
16610
- const walletPath = join36(this.nexusDir, "wallet.enc");
16768
+ const walletPath = join37(this.nexusDir, "wallet.enc");
16611
16769
  if (!existsSync23(walletPath)) {
16612
16770
  return "No wallet configured. Use wallet_create to set one up.";
16613
16771
  }
@@ -16646,7 +16804,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16646
16804
  }
16647
16805
  async doWalletCreate(args) {
16648
16806
  await this.ensureDir();
16649
- const walletPath = join36(this.nexusDir, "wallet.enc");
16807
+ const walletPath = join37(this.nexusDir, "wallet.enc");
16650
16808
  if (existsSync23(walletPath))
16651
16809
  return "Wallet already exists. Delete wallet.enc to create a new one.";
16652
16810
  const userAddress = args.wallet_address;
@@ -16692,7 +16850,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16692
16850
  const cipher = createCipheriv("aes-256-gcm", key, iv);
16693
16851
  let enc = cipher.update(privKeyHex, "utf8", "hex");
16694
16852
  enc += cipher.final("hex");
16695
- const x402KeyPath = join36(this.nexusDir, "x402-wallet.key");
16853
+ const x402KeyPath = join37(this.nexusDir, "x402-wallet.key");
16696
16854
  const x402Fh = await fsOpen(x402KeyPath, "w", 384);
16697
16855
  await x402Fh.writeFile("0x" + privKeyHex);
16698
16856
  await x402Fh.close();
@@ -16730,7 +16888,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16730
16888
  * Silent — no user output, just ensures the files exist.
16731
16889
  */
16732
16890
  async ensureWallet() {
16733
- const walletPath = join36(this.nexusDir, "wallet.enc");
16891
+ const walletPath = join37(this.nexusDir, "wallet.enc");
16734
16892
  if (existsSync23(walletPath))
16735
16893
  return;
16736
16894
  let address;
@@ -16754,7 +16912,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16754
16912
  const cipher = createCipheriv("aes-256-gcm", key, iv);
16755
16913
  let enc = cipher.update(privKeyHex, "utf8", "hex");
16756
16914
  enc += cipher.final("hex");
16757
- const x402KeyPath = join36(this.nexusDir, "x402-wallet.key");
16915
+ const x402KeyPath = join37(this.nexusDir, "x402-wallet.key");
16758
16916
  const x402Fh = await fsOpen(x402KeyPath, "w", 384);
16759
16917
  await x402Fh.writeFile("0x" + privKeyHex);
16760
16918
  await x402Fh.close();
@@ -16814,7 +16972,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16814
16972
  // ---------------------------------------------------------------------------
16815
16973
  async doLedgerStatus() {
16816
16974
  await this.ensureDir();
16817
- const ledgerPath = join36(this.nexusDir, "ledger.jsonl");
16975
+ const ledgerPath = join37(this.nexusDir, "ledger.jsonl");
16818
16976
  if (!existsSync23(ledgerPath)) {
16819
16977
  return "No ledger entries. Earnings and spending will be tracked here after x402 transactions.";
16820
16978
  }
@@ -16856,7 +17014,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16856
17014
  }
16857
17015
  }
16858
17016
  async getLedgerSummary() {
16859
- const ledgerPath = join36(this.nexusDir, "ledger.jsonl");
17017
+ const ledgerPath = join37(this.nexusDir, "ledger.jsonl");
16860
17018
  if (!existsSync23(ledgerPath))
16861
17019
  return null;
16862
17020
  try {
@@ -16881,15 +17039,15 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16881
17039
  }
16882
17040
  async appendLedger(entry) {
16883
17041
  await this.ensureDir();
16884
- const ledgerPath = join36(this.nexusDir, "ledger.jsonl");
17042
+ const ledgerPath = join37(this.nexusDir, "ledger.jsonl");
16885
17043
  const line = JSON.stringify(entry) + "\n";
16886
- await writeFile17(ledgerPath, existsSync23(ledgerPath) ? await readFile18(ledgerPath, "utf8") + line : line);
17044
+ await writeFile18(ledgerPath, existsSync23(ledgerPath) ? await readFile18(ledgerPath, "utf8") + line : line);
16887
17045
  }
16888
17046
  // ---------------------------------------------------------------------------
16889
17047
  // Step 4: Budget Policy — Spending limits and auto-approve thresholds
16890
17048
  // ---------------------------------------------------------------------------
16891
17049
  async loadBudget() {
16892
- const budgetPath = join36(this.nexusDir, "budget.json");
17050
+ const budgetPath = join37(this.nexusDir, "budget.json");
16893
17051
  if (!existsSync23(budgetPath))
16894
17052
  return null;
16895
17053
  try {
@@ -16899,7 +17057,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16899
17057
  }
16900
17058
  }
16901
17059
  async ensureDefaultBudget() {
16902
- const budgetPath = join36(this.nexusDir, "budget.json");
17060
+ const budgetPath = join37(this.nexusDir, "budget.json");
16903
17061
  if (existsSync23(budgetPath))
16904
17062
  return;
16905
17063
  const defaultBudget = {
@@ -16920,7 +17078,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16920
17078
  deniedPeers: []
16921
17079
  };
16922
17080
  await this.ensureDir();
16923
- await writeFile17(budgetPath, JSON.stringify(defaultBudget, null, 2));
17081
+ await writeFile18(budgetPath, JSON.stringify(defaultBudget, null, 2));
16924
17082
  }
16925
17083
  async doBudgetStatus() {
16926
17084
  await this.ensureDir();
@@ -16969,12 +17127,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16969
17127
  if (changes.length === 0) {
16970
17128
  return "No budget parameters provided. Use daily_limit, per_invoke_max, or auto_approve_below.";
16971
17129
  }
16972
- const budgetPath = join36(this.nexusDir, "budget.json");
16973
- await writeFile17(budgetPath, JSON.stringify(budget, null, 2));
17130
+ const budgetPath = join37(this.nexusDir, "budget.json");
17131
+ await writeFile18(budgetPath, JSON.stringify(budget, null, 2));
16974
17132
  return `Budget updated: ${changes.join(", ")}`;
16975
17133
  }
16976
17134
  async getTodaySpending() {
16977
- const ledgerPath = join36(this.nexusDir, "ledger.jsonl");
17135
+ const ledgerPath = join37(this.nexusDir, "ledger.jsonl");
16978
17136
  if (!existsSync23(ledgerPath))
16979
17137
  return 0;
16980
17138
  try {
@@ -17018,7 +17176,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
17018
17176
  if (todaySpent + amountUsdc > budget.dailyLimitUsdc) {
17019
17177
  return { allowed: false, reason: `Would exceed daily limit ($${((todaySpent + amountUsdc) / 1e6).toFixed(6)} > $${(budget.dailyLimitUsdc / 1e6).toFixed(6)})` };
17020
17178
  }
17021
- const walletPath = join36(this.nexusDir, "wallet.enc");
17179
+ const walletPath = join37(this.nexusDir, "wallet.enc");
17022
17180
  if (existsSync23(walletPath)) {
17023
17181
  try {
17024
17182
  const w = JSON.parse(await readFile18(walletPath, "utf8"));
@@ -17049,7 +17207,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
17049
17207
  const budgetResult = await this.checkBudget(amountSmallest, "transfer:direct", targetAddress);
17050
17208
  if (!budgetResult.allowed)
17051
17209
  return `BLOCKED by budget policy: ${budgetResult.reason}`;
17052
- const walletPath = join36(this.nexusDir, "wallet.enc");
17210
+ const walletPath = join37(this.nexusDir, "wallet.enc");
17053
17211
  if (!existsSync23(walletPath))
17054
17212
  throw new Error("No wallet. Use wallet_create first.");
17055
17213
  const w = JSON.parse(await readFile18(walletPath, "utf8"));
@@ -17110,7 +17268,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
17110
17268
  capability: "transfer:direct",
17111
17269
  note: "signed, awaiting submission"
17112
17270
  });
17113
- const proofFile = join36(this.nexusDir, "pending-transfer.json");
17271
+ const proofFile = join37(this.nexusDir, "pending-transfer.json");
17114
17272
  const proof = {
17115
17273
  from: account.address,
17116
17274
  to: targetAddress,
@@ -17123,7 +17281,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
17123
17281
  usdcContract: USDC_ADDRESS,
17124
17282
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
17125
17283
  };
17126
- await writeFile17(proofFile, JSON.stringify(proof, null, 2));
17284
+ await writeFile18(proofFile, JSON.stringify(proof, null, 2));
17127
17285
  return [
17128
17286
  `Transfer signed (EIP-3009 TransferWithAuthorization):`,
17129
17287
  ` From: ${account.address}`,
@@ -17152,7 +17310,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
17152
17310
  throw new Error("prompt is required");
17153
17311
  const estimatedTokens = Math.ceil(prompt.length / 4) + 1e3;
17154
17312
  let estimatedCostSmallest = 0;
17155
- const pricingPath = join36(this.nexusDir, "pricing.json");
17313
+ const pricingPath = join37(this.nexusDir, "pricing.json");
17156
17314
  if (existsSync23(pricingPath)) {
17157
17315
  try {
17158
17316
  const pricing = JSON.parse(await readFile18(pricingPath, "utf8"));
@@ -17272,7 +17430,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
17272
17430
  const bar = (s) => "\u2588".repeat(Math.round(s / 5)) + "\u2591".repeat(20 - Math.round(s / 5));
17273
17431
  const mem = vramMb > 24e3 ? 95 : vramMb > 16e3 ? 80 : vramMb > 8e3 ? 60 : vramMb > 0 ? 40 : 20;
17274
17432
  await this.ensureDir();
17275
- await writeFile17(join36(this.nexusDir, "inference-proof.json"), JSON.stringify({
17433
+ await writeFile18(join37(this.nexusDir, "inference-proof.json"), JSON.stringify({
17276
17434
  modelName,
17277
17435
  gpuName,
17278
17436
  vramMb,
@@ -17991,6 +18149,7 @@ __export(dist_exports, {
17991
18149
  GlobFindTool: () => GlobFindTool,
17992
18150
  GrepSearchTool: () => GrepSearchTool,
17993
18151
  IdentityKernelTool: () => IdentityKernelTool,
18152
+ ImageGenerateTool: () => ImageGenerateTool,
17994
18153
  ImageReadTool: () => ImageReadTool,
17995
18154
  ListDirectoryTool: () => ListDirectoryTool,
17996
18155
  ManageToolsTool: () => ManageToolsTool,
@@ -18097,6 +18256,7 @@ var init_dist2 = __esm({
18097
18256
  init_reflection_integrity();
18098
18257
  init_exploration_culture();
18099
18258
  init_embedding_store();
18259
+ init_image_generate();
18100
18260
  init_structured_read();
18101
18261
  init_vision();
18102
18262
  init_desktop_click();
@@ -18797,12 +18957,12 @@ var init_dist3 = __esm({
18797
18957
 
18798
18958
  // packages/orchestrator/dist/promptLoader.js
18799
18959
  import { readFileSync as readFileSync18, existsSync as existsSync25 } from "node:fs";
18800
- import { join as join37, dirname as dirname12 } from "node:path";
18960
+ import { join as join38, dirname as dirname12 } from "node:path";
18801
18961
  import { fileURLToPath as fileURLToPath7 } from "node:url";
18802
18962
  function loadPrompt(promptPath, vars) {
18803
18963
  let content = cache.get(promptPath);
18804
18964
  if (content === void 0) {
18805
- const fullPath = join37(PROMPTS_DIR, promptPath);
18965
+ const fullPath = join38(PROMPTS_DIR, promptPath);
18806
18966
  if (!existsSync25(fullPath)) {
18807
18967
  throw new Error(`Prompt file not found: ${fullPath}`);
18808
18968
  }
@@ -18819,7 +18979,7 @@ var init_promptLoader = __esm({
18819
18979
  "use strict";
18820
18980
  __filename = fileURLToPath7(import.meta.url);
18821
18981
  __dirname4 = dirname12(__filename);
18822
- PROMPTS_DIR = join37(__dirname4, "..", "prompts");
18982
+ PROMPTS_DIR = join38(__dirname4, "..", "prompts");
18823
18983
  cache = /* @__PURE__ */ new Map();
18824
18984
  }
18825
18985
  });
@@ -19199,7 +19359,7 @@ var init_code_retriever = __esm({
19199
19359
  import { execFile as execFile5 } from "node:child_process";
19200
19360
  import { promisify as promisify4 } from "node:util";
19201
19361
  import { readFile as readFile19, readdir as readdir5, stat as stat3 } from "node:fs/promises";
19202
- import { join as join38, extname as extname7 } from "node:path";
19362
+ import { join as join39, extname as extname7 } from "node:path";
19203
19363
  async function searchByPath(pathPattern, options) {
19204
19364
  const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
19205
19365
  const pattern = options.caseInsensitive ? pathPattern.toLowerCase() : pathPattern;
@@ -19341,7 +19501,7 @@ async function walkForFiles(rootDir, dir, excludeGlobs, results) {
19341
19501
  continue;
19342
19502
  if (excludeGlobs.some((g) => entry.name === g || matchesGlob(entry.name, g)))
19343
19503
  continue;
19344
- const absPath = join38(dir, entry.name);
19504
+ const absPath = join39(dir, entry.name);
19345
19505
  if (entry.isDirectory()) {
19346
19506
  await walkForFiles(rootDir, absPath, excludeGlobs, results);
19347
19507
  } else if (entry.isFile()) {
@@ -19648,7 +19808,7 @@ var init_graphExpand = __esm({
19648
19808
 
19649
19809
  // packages/retrieval/dist/snippetPacker.js
19650
19810
  import { readFile as readFile20 } from "node:fs/promises";
19651
- import { join as join39 } from "node:path";
19811
+ import { join as join40 } from "node:path";
19652
19812
  async function packSnippets(requests, opts = {}) {
19653
19813
  const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
19654
19814
  const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
@@ -19674,7 +19834,7 @@ async function packSnippets(requests, opts = {}) {
19674
19834
  return { packed, dropped, totalTokens };
19675
19835
  }
19676
19836
  async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
19677
- const absPath = req.filePath.startsWith("/") ? req.filePath : join39(repoRoot, req.filePath);
19837
+ const absPath = req.filePath.startsWith("/") ? req.filePath : join40(repoRoot, req.filePath);
19678
19838
  let content;
19679
19839
  try {
19680
19840
  content = await readFile20(absPath, "utf-8");
@@ -21422,6 +21582,57 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
21422
21582
  this.emit({ type: "error", content: `Model not available. Use /model to select a different model.`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
21423
21583
  break;
21424
21584
  }
21585
+ if (/does not support tools|HTTP 400.*tools/i.test(errMsg)) {
21586
+ this.emit({
21587
+ type: "status",
21588
+ content: `Model lacks native tool support \u2014 switching to prompt-injected tool mode`,
21589
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
21590
+ });
21591
+ const toolDescriptions = Array.from(this.tools.values()).map((t) => `- ${t.name}: ${t.description}`).join("\n");
21592
+ const toolInjectMsg = [
21593
+ "\n\n[TOOL MODE \u2014 PROMPT INJECTION]",
21594
+ "This model does not have native tool-calling. To use tools, output a JSON block:",
21595
+ "```json",
21596
+ '{"tool": "tool_name", "args": {"param": "value"}}',
21597
+ "```",
21598
+ "\nAvailable tools:",
21599
+ toolDescriptions,
21600
+ "\nOutput EXACTLY ONE tool call per response in the JSON format above.",
21601
+ "After seeing the tool result, continue or call another tool.",
21602
+ 'When done, output: {"tool": "task_complete", "args": {"summary": "what you did"}}'
21603
+ ].join("\n");
21604
+ messages.push({ role: "system", content: toolInjectMsg });
21605
+ chatRequest.tools = [];
21606
+ try {
21607
+ response = this.options.streamEnabled && this.hasStreamingSupport() ? await this.streamingRequest(chatRequest, turn) : await this.backend.chatCompletion(chatRequest);
21608
+ const content = response.choices?.[0]?.message?.content ?? "";
21609
+ const jsonMatch = content.match(/```json\s*\n?([\s\S]*?)```/);
21610
+ if (jsonMatch) {
21611
+ try {
21612
+ const parsed = JSON.parse(jsonMatch[1]);
21613
+ if (parsed.tool && this.tools.has(parsed.tool)) {
21614
+ const tool = this.tools.get(parsed.tool);
21615
+ const result = await tool.execute(parsed.args ?? {});
21616
+ messages.push({ role: "assistant", content });
21617
+ messages.push({ role: "user", content: `Tool result (${parsed.tool}): ${result.output.slice(0, 2e3)}` });
21618
+ if (parsed.tool === "task_complete") {
21619
+ completed = true;
21620
+ summary = String(parsed.args?.summary ?? content);
21621
+ }
21622
+ toolCallCount++;
21623
+ continue;
21624
+ }
21625
+ } catch {
21626
+ }
21627
+ }
21628
+ messages.push({ role: "assistant", content });
21629
+ continue;
21630
+ } catch (retryErr2) {
21631
+ const msg2 = retryErr2 instanceof Error ? retryErr2.message : String(retryErr2);
21632
+ this.emit({ type: "error", content: `Prompt-injected tool mode also failed: ${msg2}`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
21633
+ break;
21634
+ }
21635
+ }
21425
21636
  messages.push({ role: "user", content: "[System: backend request failed, retrying on next turn. The previous request was lost.]" });
21426
21637
  continue;
21427
21638
  }
@@ -22272,8 +22483,8 @@ ${marker}` : marker);
22272
22483
  return;
22273
22484
  try {
22274
22485
  const { mkdirSync: mkdirSync21, writeFileSync: writeFileSync20 } = __require("node:fs");
22275
- const { join: join63 } = __require("node:path");
22276
- const sessionDir = join63(this._workingDirectory, ".oa", "session", this._sessionId);
22486
+ const { join: join64 } = __require("node:path");
22487
+ const sessionDir = join64(this._workingDirectory, ".oa", "session", this._sessionId);
22277
22488
  mkdirSync21(sessionDir, { recursive: true });
22278
22489
  const checkpoint = {
22279
22490
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -22286,7 +22497,7 @@ ${marker}` : marker);
22286
22497
  memexEntryCount: this._memexArchive.size,
22287
22498
  fileRegistrySize: this._fileRegistry.size
22288
22499
  };
22289
- writeFileSync20(join63(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
22500
+ writeFileSync20(join64(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
22290
22501
  } catch {
22291
22502
  }
22292
22503
  }
@@ -23554,7 +23765,7 @@ ${transcript}`
23554
23765
  // packages/orchestrator/dist/nexusBackend.js
23555
23766
  import { existsSync as existsSync26, statSync as statSync9, openSync, readSync, closeSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync8 } from "node:fs";
23556
23767
  import { watch as fsWatch } from "node:fs";
23557
- import { join as join40 } from "node:path";
23768
+ import { join as join41 } from "node:path";
23558
23769
  import { tmpdir as tmpdir7 } from "node:os";
23559
23770
  import { randomBytes as randomBytes8 } from "node:crypto";
23560
23771
  var NexusAgenticBackend;
@@ -23704,7 +23915,7 @@ var init_nexusBackend = __esm({
23704
23915
  * Falls back to unary + word-split if streaming setup fails.
23705
23916
  */
23706
23917
  async *chatCompletionStream(request) {
23707
- const streamFile = join40(tmpdir7(), `nexus-stream-${randomBytes8(6).toString("hex")}.jsonl`);
23918
+ const streamFile = join41(tmpdir7(), `nexus-stream-${randomBytes8(6).toString("hex")}.jsonl`);
23708
23919
  writeFileSync8(streamFile, "", "utf8");
23709
23920
  const daemonArgs = {
23710
23921
  model: this.model,
@@ -24741,7 +24952,7 @@ __export(listen_exports, {
24741
24952
  });
24742
24953
  import { spawn as spawn15, execSync as execSync22 } from "node:child_process";
24743
24954
  import { existsSync as existsSync27, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, readdirSync as readdirSync6 } from "node:fs";
24744
- import { join as join41, dirname as dirname13 } from "node:path";
24955
+ import { join as join42, dirname as dirname13 } from "node:path";
24745
24956
  import { homedir as homedir8 } from "node:os";
24746
24957
  import { fileURLToPath as fileURLToPath8 } from "node:url";
24747
24958
  import { EventEmitter } from "node:events";
@@ -24827,12 +25038,12 @@ function findMicCaptureCommand() {
24827
25038
  function findLiveWhisperScript() {
24828
25039
  const thisDir = dirname13(fileURLToPath8(import.meta.url));
24829
25040
  const candidates = [
24830
- join41(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
24831
- join41(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
24832
- join41(thisDir, "../../execution/scripts/live-whisper.py"),
25041
+ join42(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
25042
+ join42(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
25043
+ join42(thisDir, "../../execution/scripts/live-whisper.py"),
24833
25044
  // npm install layout — scripts bundled alongside dist
24834
- join41(thisDir, "../scripts/live-whisper.py"),
24835
- join41(thisDir, "../../scripts/live-whisper.py")
25045
+ join42(thisDir, "../scripts/live-whisper.py"),
25046
+ join42(thisDir, "../../scripts/live-whisper.py")
24836
25047
  ];
24837
25048
  for (const p of candidates) {
24838
25049
  if (existsSync27(p))
@@ -24845,8 +25056,8 @@ function findLiveWhisperScript() {
24845
25056
  stdio: ["pipe", "pipe", "pipe"]
24846
25057
  }).trim();
24847
25058
  const candidates2 = [
24848
- join41(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
24849
- join41(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
25059
+ join42(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
25060
+ join42(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
24850
25061
  ];
24851
25062
  for (const p of candidates2) {
24852
25063
  if (existsSync27(p))
@@ -24854,11 +25065,11 @@ function findLiveWhisperScript() {
24854
25065
  }
24855
25066
  } catch {
24856
25067
  }
24857
- const nvmBase = join41(homedir8(), ".nvm", "versions", "node");
25068
+ const nvmBase = join42(homedir8(), ".nvm", "versions", "node");
24858
25069
  if (existsSync27(nvmBase)) {
24859
25070
  try {
24860
25071
  for (const ver of readdirSync6(nvmBase)) {
24861
- const p = join41(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
25072
+ const p = join42(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
24862
25073
  if (existsSync27(p))
24863
25074
  return p;
24864
25075
  }
@@ -24877,7 +25088,7 @@ function ensureTranscribeCliBackground() {
24877
25088
  timeout: 5e3,
24878
25089
  stdio: ["pipe", "pipe", "pipe"]
24879
25090
  }).trim();
24880
- if (existsSync27(join41(globalRoot, "transcribe-cli", "dist", "index.js"))) {
25091
+ if (existsSync27(join42(globalRoot, "transcribe-cli", "dist", "index.js"))) {
24881
25092
  return true;
24882
25093
  }
24883
25094
  } catch {
@@ -25100,24 +25311,24 @@ var init_listen = __esm({
25100
25311
  timeout: 5e3,
25101
25312
  stdio: ["pipe", "pipe", "pipe"]
25102
25313
  }).trim();
25103
- const tcPath = join41(globalRoot, "transcribe-cli");
25104
- if (existsSync27(join41(tcPath, "dist", "index.js"))) {
25314
+ const tcPath = join42(globalRoot, "transcribe-cli");
25315
+ if (existsSync27(join42(tcPath, "dist", "index.js"))) {
25105
25316
  const { createRequire: createRequire4 } = await import("node:module");
25106
25317
  const req = createRequire4(import.meta.url);
25107
- return req(join41(tcPath, "dist", "index.js"));
25318
+ return req(join42(tcPath, "dist", "index.js"));
25108
25319
  }
25109
25320
  } catch {
25110
25321
  }
25111
- const nvmBase = join41(homedir8(), ".nvm", "versions", "node");
25322
+ const nvmBase = join42(homedir8(), ".nvm", "versions", "node");
25112
25323
  if (existsSync27(nvmBase)) {
25113
25324
  try {
25114
25325
  const { readdirSync: readdirSync17 } = await import("node:fs");
25115
25326
  for (const ver of readdirSync17(nvmBase)) {
25116
- const tcPath = join41(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
25117
- if (existsSync27(join41(tcPath, "dist", "index.js"))) {
25327
+ const tcPath = join42(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
25328
+ if (existsSync27(join42(tcPath, "dist", "index.js"))) {
25118
25329
  const { createRequire: createRequire4 } = await import("node:module");
25119
25330
  const req = createRequire4(import.meta.url);
25120
- return req(join41(tcPath, "dist", "index.js"));
25331
+ return req(join42(tcPath, "dist", "index.js"));
25121
25332
  }
25122
25333
  }
25123
25334
  } catch {
@@ -25399,9 +25610,9 @@ transcribe-cli error: ${transcribeCliError}` : "";
25399
25610
  });
25400
25611
  if (outputDir) {
25401
25612
  const { basename: basename16 } = await import("node:path");
25402
- const transcriptDir = join41(outputDir, ".oa", "transcripts");
25613
+ const transcriptDir = join42(outputDir, ".oa", "transcripts");
25403
25614
  mkdirSync8(transcriptDir, { recursive: true });
25404
- const outFile = join41(transcriptDir, `${basename16(filePath)}.txt`);
25615
+ const outFile = join42(transcriptDir, `${basename16(filePath)}.txt`);
25405
25616
  writeFileSync9(outFile, result.text, "utf-8");
25406
25617
  }
25407
25618
  return {
@@ -30760,7 +30971,7 @@ import { randomBytes as randomBytes9 } from "node:crypto";
30760
30971
  import { URL as URL2 } from "node:url";
30761
30972
  import { loadavg, cpus, totalmem, freemem } from "node:os";
30762
30973
  import { existsSync as existsSync28, readFileSync as readFileSync19, writeFileSync as writeFileSync10, unlinkSync as unlinkSync5, mkdirSync as mkdirSync9, readdirSync as readdirSync7, statSync as statSync10 } from "node:fs";
30763
- import { join as join42 } from "node:path";
30974
+ import { join as join43 } from "node:path";
30764
30975
  function cleanForwardHeaders(raw, targetHost) {
30765
30976
  const out = {};
30766
30977
  for (const [key, value] of Object.entries(raw)) {
@@ -30788,7 +30999,7 @@ function fmtTokens(n) {
30788
30999
  }
30789
31000
  function readExposeState(stateDir) {
30790
31001
  try {
30791
- const path = join42(stateDir, STATE_FILE_NAME);
31002
+ const path = join43(stateDir, STATE_FILE_NAME);
30792
31003
  if (!existsSync28(path))
30793
31004
  return null;
30794
31005
  const raw = readFileSync19(path, "utf8");
@@ -30803,13 +31014,13 @@ function readExposeState(stateDir) {
30803
31014
  function writeExposeState(stateDir, state) {
30804
31015
  try {
30805
31016
  mkdirSync9(stateDir, { recursive: true });
30806
- writeFileSync10(join42(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
31017
+ writeFileSync10(join43(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
30807
31018
  } catch {
30808
31019
  }
30809
31020
  }
30810
31021
  function removeExposeState(stateDir) {
30811
31022
  try {
30812
- unlinkSync5(join42(stateDir, STATE_FILE_NAME));
31023
+ unlinkSync5(join43(stateDir, STATE_FILE_NAME));
30813
31024
  } catch {
30814
31025
  }
30815
31026
  }
@@ -30898,7 +31109,7 @@ async function collectSystemMetricsAsync() {
30898
31109
  }
30899
31110
  function readP2PExposeState(stateDir) {
30900
31111
  try {
30901
- const path = join42(stateDir, P2P_STATE_FILE_NAME);
31112
+ const path = join43(stateDir, P2P_STATE_FILE_NAME);
30902
31113
  if (!existsSync28(path))
30903
31114
  return null;
30904
31115
  const raw = readFileSync19(path, "utf8");
@@ -30913,13 +31124,13 @@ function readP2PExposeState(stateDir) {
30913
31124
  function writeP2PExposeState(stateDir, state) {
30914
31125
  try {
30915
31126
  mkdirSync9(stateDir, { recursive: true });
30916
- writeFileSync10(join42(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
31127
+ writeFileSync10(join43(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
30917
31128
  } catch {
30918
31129
  }
30919
31130
  }
30920
31131
  function removeP2PExposeState(stateDir) {
30921
31132
  try {
30922
- unlinkSync5(join42(stateDir, P2P_STATE_FILE_NAME));
31133
+ unlinkSync5(join43(stateDir, P2P_STATE_FILE_NAME));
30923
31134
  } catch {
30924
31135
  }
30925
31136
  }
@@ -31767,7 +31978,7 @@ ${this.formatConnectionInfo()}`);
31767
31978
  throw new Error(`Expose failed: ${exposeResult.error}`);
31768
31979
  }
31769
31980
  const nexusDir = this._nexusTool.getNexusDir();
31770
- const statusPath = join42(nexusDir, "status.json");
31981
+ const statusPath = join43(nexusDir, "status.json");
31771
31982
  for (let i = 0; i < 80; i++) {
31772
31983
  try {
31773
31984
  const raw = readFileSync19(statusPath, "utf8");
@@ -31801,7 +32012,7 @@ ${this.formatConnectionInfo()}`);
31801
32012
  });
31802
32013
  }
31803
32014
  try {
31804
- const invocDir = join42(nexusDir, "invocations");
32015
+ const invocDir = join43(nexusDir, "invocations");
31805
32016
  if (existsSync28(invocDir)) {
31806
32017
  this._prevInvocCount = readdirSync7(invocDir).filter((f) => f.endsWith(".json")).length;
31807
32018
  this._stats.totalRequests = this._prevInvocCount;
@@ -31831,7 +32042,7 @@ ${this.formatConnectionInfo()}`);
31831
32042
  if (!state)
31832
32043
  return null;
31833
32044
  const nexusDir = nexusTool.getNexusDir();
31834
- const statusPath = join42(nexusDir, "status.json");
32045
+ const statusPath = join43(nexusDir, "status.json");
31835
32046
  try {
31836
32047
  if (!existsSync28(statusPath)) {
31837
32048
  removeP2PExposeState(stateDir);
@@ -31890,7 +32101,7 @@ ${this.formatConnectionInfo()}`);
31890
32101
  let lastMeteringLineCount = 0;
31891
32102
  this._activityPollTimer = setInterval(() => {
31892
32103
  try {
31893
- const invocDir = join42(nexusDir, "invocations");
32104
+ const invocDir = join43(nexusDir, "invocations");
31894
32105
  if (!existsSync28(invocDir))
31895
32106
  return;
31896
32107
  const files = readdirSync7(invocDir).filter((f) => f.endsWith(".json"));
@@ -31906,13 +32117,13 @@ ${this.formatConnectionInfo()}`);
31906
32117
  let recentActive = 0;
31907
32118
  for (const f of files.slice(-10)) {
31908
32119
  try {
31909
- const st = statSync10(join42(invocDir, f));
32120
+ const st = statSync10(join43(invocDir, f));
31910
32121
  if (now - st.mtimeMs < 1e4)
31911
32122
  recentActive++;
31912
32123
  } catch {
31913
32124
  }
31914
32125
  }
31915
- const meteringFile = join42(nexusDir, "metering.jsonl");
32126
+ const meteringFile = join43(nexusDir, "metering.jsonl");
31916
32127
  let meteringLines = lastMeteringLineCount;
31917
32128
  try {
31918
32129
  if (existsSync28(meteringFile)) {
@@ -31942,7 +32153,7 @@ ${this.formatConnectionInfo()}`);
31942
32153
  this._activityPollTimer.unref();
31943
32154
  this._pollTimer = setInterval(() => {
31944
32155
  try {
31945
- const statusPath = join42(nexusDir, "status.json");
32156
+ const statusPath = join43(nexusDir, "status.json");
31946
32157
  if (existsSync28(statusPath)) {
31947
32158
  const status = JSON.parse(readFileSync19(statusPath, "utf8"));
31948
32159
  if (status.peerId && !this._peerId) {
@@ -31953,7 +32164,7 @@ ${this.formatConnectionInfo()}`);
31953
32164
  } catch {
31954
32165
  }
31955
32166
  try {
31956
- const invocDir = join42(nexusDir, "invocations");
32167
+ const invocDir = join43(nexusDir, "invocations");
31957
32168
  if (existsSync28(invocDir)) {
31958
32169
  const files = readdirSync7(invocDir);
31959
32170
  const invocCount = files.filter((f) => f.endsWith(".json")).length;
@@ -31965,7 +32176,7 @@ ${this.formatConnectionInfo()}`);
31965
32176
  } catch {
31966
32177
  }
31967
32178
  try {
31968
- const meteringFile = join42(nexusDir, "metering.jsonl");
32179
+ const meteringFile = join43(nexusDir, "metering.jsonl");
31969
32180
  if (existsSync28(meteringFile)) {
31970
32181
  const content = readFileSync19(meteringFile, "utf8");
31971
32182
  if (content.length > lastMeteringSize) {
@@ -32177,7 +32388,7 @@ var init_types = __esm({
32177
32388
  // packages/cli/dist/tui/p2p/secret-vault.js
32178
32389
  import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes10, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
32179
32390
  import { readFileSync as readFileSync20, writeFileSync as writeFileSync11, existsSync as existsSync29, mkdirSync as mkdirSync10 } from "node:fs";
32180
- import { join as join43, dirname as dirname14 } from "node:path";
32391
+ import { join as join44, dirname as dirname14 } from "node:path";
32181
32392
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
32182
32393
  var init_secret_vault = __esm({
32183
32394
  "packages/cli/dist/tui/p2p/secret-vault.js"() {
@@ -33522,13 +33733,13 @@ async function fetchPeerModels(peerId, authKey) {
33522
33733
  try {
33523
33734
  const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
33524
33735
  const { existsSync: existsSync45, readFileSync: readFileSync33 } = await import("node:fs");
33525
- const { join: join63 } = await import("node:path");
33736
+ const { join: join64 } = await import("node:path");
33526
33737
  const cwd4 = process.cwd();
33527
33738
  const nexusTool = new NexusTool2(cwd4);
33528
33739
  const nexusDir = nexusTool.getNexusDir();
33529
33740
  let isLocalPeer = false;
33530
33741
  try {
33531
- const statusPath = join63(nexusDir, "status.json");
33742
+ const statusPath = join64(nexusDir, "status.json");
33532
33743
  if (existsSync45(statusPath)) {
33533
33744
  const status = JSON.parse(readFileSync33(statusPath, "utf8"));
33534
33745
  if (status.peerId === peerId)
@@ -33537,7 +33748,7 @@ async function fetchPeerModels(peerId, authKey) {
33537
33748
  } catch {
33538
33749
  }
33539
33750
  if (isLocalPeer) {
33540
- const pricingPath = join63(nexusDir, "pricing.json");
33751
+ const pricingPath = join64(nexusDir, "pricing.json");
33541
33752
  if (existsSync45(pricingPath)) {
33542
33753
  try {
33543
33754
  const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
@@ -33554,7 +33765,7 @@ async function fetchPeerModels(peerId, authKey) {
33554
33765
  }
33555
33766
  }
33556
33767
  }
33557
- const cachePath = join63(nexusDir, "peer-models-cache.json");
33768
+ const cachePath = join64(nexusDir, "peer-models-cache.json");
33558
33769
  if (existsSync45(cachePath)) {
33559
33770
  try {
33560
33771
  const cache4 = JSON.parse(readFileSync33(cachePath, "utf8"));
@@ -33672,7 +33883,7 @@ async function fetchPeerModels(peerId, authKey) {
33672
33883
  } catch {
33673
33884
  }
33674
33885
  if (isLocalPeer) {
33675
- const pricingPath = join63(nexusDir, "pricing.json");
33886
+ const pricingPath = join64(nexusDir, "pricing.json");
33676
33887
  if (existsSync45(pricingPath)) {
33677
33888
  try {
33678
33889
  const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
@@ -33956,12 +34167,12 @@ var init_render2 = __esm({
33956
34167
 
33957
34168
  // packages/prompts/dist/promptLoader.js
33958
34169
  import { readFileSync as readFileSync21, existsSync as existsSync30 } from "node:fs";
33959
- import { join as join44, dirname as dirname15 } from "node:path";
34170
+ import { join as join45, dirname as dirname15 } from "node:path";
33960
34171
  import { fileURLToPath as fileURLToPath9 } from "node:url";
33961
34172
  function loadPrompt2(promptPath, vars) {
33962
34173
  let content = cache2.get(promptPath);
33963
34174
  if (content === void 0) {
33964
- const fullPath = join44(PROMPTS_DIR2, promptPath);
34175
+ const fullPath = join45(PROMPTS_DIR2, promptPath);
33965
34176
  if (!existsSync30(fullPath)) {
33966
34177
  throw new Error(`Prompt file not found: ${fullPath}`);
33967
34178
  }
@@ -33978,8 +34189,8 @@ var init_promptLoader2 = __esm({
33978
34189
  "use strict";
33979
34190
  __filename2 = fileURLToPath9(import.meta.url);
33980
34191
  __dirname5 = dirname15(__filename2);
33981
- devPath = join44(__dirname5, "..", "templates");
33982
- publishedPath = join44(__dirname5, "..", "prompts", "templates");
34192
+ devPath = join45(__dirname5, "..", "templates");
34193
+ publishedPath = join45(__dirname5, "..", "prompts", "templates");
33983
34194
  PROMPTS_DIR2 = existsSync30(devPath) ? devPath : publishedPath;
33984
34195
  cache2 = /* @__PURE__ */ new Map();
33985
34196
  }
@@ -34091,7 +34302,7 @@ var init_task_templates = __esm({
34091
34302
  });
34092
34303
 
34093
34304
  // packages/prompts/dist/index.js
34094
- import { join as join45, dirname as dirname16 } from "node:path";
34305
+ import { join as join46, dirname as dirname16 } from "node:path";
34095
34306
  import { fileURLToPath as fileURLToPath10 } from "node:url";
34096
34307
  var _dir, _packageRoot;
34097
34308
  var init_dist6 = __esm({
@@ -34102,21 +34313,21 @@ var init_dist6 = __esm({
34102
34313
  init_task_templates();
34103
34314
  init_render2();
34104
34315
  _dir = dirname16(fileURLToPath10(import.meta.url));
34105
- _packageRoot = join45(_dir, "..");
34316
+ _packageRoot = join46(_dir, "..");
34106
34317
  }
34107
34318
  });
34108
34319
 
34109
34320
  // packages/cli/dist/tui/oa-directory.js
34110
34321
  import { existsSync as existsSync31, mkdirSync as mkdirSync11, readFileSync as readFileSync22, writeFileSync as writeFileSync12, readdirSync as readdirSync8, statSync as statSync11, unlinkSync as unlinkSync6 } from "node:fs";
34111
- import { join as join46, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
34322
+ import { join as join47, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
34112
34323
  import { homedir as homedir9 } from "node:os";
34113
34324
  function initOaDirectory(repoRoot) {
34114
- const oaPath = join46(repoRoot, OA_DIR);
34325
+ const oaPath = join47(repoRoot, OA_DIR);
34115
34326
  for (const sub of SUBDIRS) {
34116
- mkdirSync11(join46(oaPath, sub), { recursive: true });
34327
+ mkdirSync11(join47(oaPath, sub), { recursive: true });
34117
34328
  }
34118
34329
  try {
34119
- const gitignorePath = join46(repoRoot, ".gitignore");
34330
+ const gitignorePath = join47(repoRoot, ".gitignore");
34120
34331
  const settingsPattern = ".oa/settings.json";
34121
34332
  if (existsSync31(gitignorePath)) {
34122
34333
  const content = readFileSync22(gitignorePath, "utf-8");
@@ -34129,10 +34340,10 @@ function initOaDirectory(repoRoot) {
34129
34340
  return oaPath;
34130
34341
  }
34131
34342
  function hasOaDirectory(repoRoot) {
34132
- return existsSync31(join46(repoRoot, OA_DIR, "index"));
34343
+ return existsSync31(join47(repoRoot, OA_DIR, "index"));
34133
34344
  }
34134
34345
  function loadProjectSettings(repoRoot) {
34135
- const settingsPath = join46(repoRoot, OA_DIR, "settings.json");
34346
+ const settingsPath = join47(repoRoot, OA_DIR, "settings.json");
34136
34347
  try {
34137
34348
  if (existsSync31(settingsPath)) {
34138
34349
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
@@ -34142,14 +34353,14 @@ function loadProjectSettings(repoRoot) {
34142
34353
  return {};
34143
34354
  }
34144
34355
  function saveProjectSettings(repoRoot, settings) {
34145
- const oaPath = join46(repoRoot, OA_DIR);
34356
+ const oaPath = join47(repoRoot, OA_DIR);
34146
34357
  mkdirSync11(oaPath, { recursive: true });
34147
34358
  const existing = loadProjectSettings(repoRoot);
34148
34359
  const merged = { ...existing, ...settings };
34149
- writeFileSync12(join46(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
34360
+ writeFileSync12(join47(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
34150
34361
  }
34151
34362
  function loadGlobalSettings() {
34152
- const settingsPath = join46(homedir9(), ".open-agents", "settings.json");
34363
+ const settingsPath = join47(homedir9(), ".open-agents", "settings.json");
34153
34364
  try {
34154
34365
  if (existsSync31(settingsPath)) {
34155
34366
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
@@ -34159,11 +34370,11 @@ function loadGlobalSettings() {
34159
34370
  return {};
34160
34371
  }
34161
34372
  function saveGlobalSettings(settings) {
34162
- const dir = join46(homedir9(), ".open-agents");
34373
+ const dir = join47(homedir9(), ".open-agents");
34163
34374
  mkdirSync11(dir, { recursive: true });
34164
34375
  const existing = loadGlobalSettings();
34165
34376
  const merged = { ...existing, ...settings };
34166
- writeFileSync12(join46(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
34377
+ writeFileSync12(join47(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
34167
34378
  }
34168
34379
  function resolveSettings(repoRoot) {
34169
34380
  const global = loadGlobalSettings();
@@ -34178,7 +34389,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
34178
34389
  while (dir && !visited.has(dir)) {
34179
34390
  visited.add(dir);
34180
34391
  for (const name of CONTEXT_FILES) {
34181
- const filePath = join46(dir, name);
34392
+ const filePath = join47(dir, name);
34182
34393
  const normalizedName = name.toLowerCase();
34183
34394
  if (existsSync31(filePath) && !seen.has(filePath)) {
34184
34395
  seen.add(filePath);
@@ -34197,7 +34408,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
34197
34408
  }
34198
34409
  }
34199
34410
  }
34200
- const projectMap = join46(dir, OA_DIR, "context", "project-map.md");
34411
+ const projectMap = join47(dir, OA_DIR, "context", "project-map.md");
34201
34412
  if (existsSync31(projectMap) && !seen.has(projectMap)) {
34202
34413
  seen.add(projectMap);
34203
34414
  try {
@@ -34213,7 +34424,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
34213
34424
  } catch {
34214
34425
  }
34215
34426
  }
34216
- const parent = join46(dir, "..");
34427
+ const parent = join47(dir, "..");
34217
34428
  if (parent === dir)
34218
34429
  break;
34219
34430
  dir = parent;
@@ -34231,7 +34442,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
34231
34442
  return found;
34232
34443
  }
34233
34444
  function readIndexMeta(repoRoot) {
34234
- const metaPath = join46(repoRoot, OA_DIR, "index", "meta.json");
34445
+ const metaPath = join47(repoRoot, OA_DIR, "index", "meta.json");
34235
34446
  try {
34236
34447
  return JSON.parse(readFileSync22(metaPath, "utf-8"));
34237
34448
  } catch {
@@ -34284,28 +34495,28 @@ ${tree}\`\`\`
34284
34495
  sections.push("");
34285
34496
  }
34286
34497
  const content = sections.join("\n");
34287
- const contextDir = join46(repoRoot, OA_DIR, "context");
34498
+ const contextDir = join47(repoRoot, OA_DIR, "context");
34288
34499
  mkdirSync11(contextDir, { recursive: true });
34289
- writeFileSync12(join46(contextDir, "project-map.md"), content, "utf-8");
34500
+ writeFileSync12(join47(contextDir, "project-map.md"), content, "utf-8");
34290
34501
  return content;
34291
34502
  }
34292
34503
  function saveSession(repoRoot, session) {
34293
- const historyDir = join46(repoRoot, OA_DIR, "history");
34504
+ const historyDir = join47(repoRoot, OA_DIR, "history");
34294
34505
  mkdirSync11(historyDir, { recursive: true });
34295
- writeFileSync12(join46(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
34506
+ writeFileSync12(join47(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
34296
34507
  }
34297
34508
  function loadRecentSessions(repoRoot, limit = 5) {
34298
- const historyDir = join46(repoRoot, OA_DIR, "history");
34509
+ const historyDir = join47(repoRoot, OA_DIR, "history");
34299
34510
  if (!existsSync31(historyDir))
34300
34511
  return [];
34301
34512
  try {
34302
34513
  const files = readdirSync8(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
34303
- const stat5 = statSync11(join46(historyDir, f));
34514
+ const stat5 = statSync11(join47(historyDir, f));
34304
34515
  return { file: f, mtime: stat5.mtimeMs };
34305
34516
  }).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
34306
34517
  return files.map((f) => {
34307
34518
  try {
34308
- return JSON.parse(readFileSync22(join46(historyDir, f.file), "utf-8"));
34519
+ return JSON.parse(readFileSync22(join47(historyDir, f.file), "utf-8"));
34309
34520
  } catch {
34310
34521
  return null;
34311
34522
  }
@@ -34315,12 +34526,12 @@ function loadRecentSessions(repoRoot, limit = 5) {
34315
34526
  }
34316
34527
  }
34317
34528
  function savePendingTask(repoRoot, task) {
34318
- const historyDir = join46(repoRoot, OA_DIR, "history");
34529
+ const historyDir = join47(repoRoot, OA_DIR, "history");
34319
34530
  mkdirSync11(historyDir, { recursive: true });
34320
- writeFileSync12(join46(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
34531
+ writeFileSync12(join47(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
34321
34532
  }
34322
34533
  function loadPendingTask(repoRoot) {
34323
- const filePath = join46(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
34534
+ const filePath = join47(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
34324
34535
  try {
34325
34536
  if (!existsSync31(filePath))
34326
34537
  return null;
@@ -34335,9 +34546,9 @@ function loadPendingTask(repoRoot) {
34335
34546
  }
34336
34547
  }
34337
34548
  function saveSessionContext(repoRoot, entry) {
34338
- const contextDir = join46(repoRoot, OA_DIR, "context");
34549
+ const contextDir = join47(repoRoot, OA_DIR, "context");
34339
34550
  mkdirSync11(contextDir, { recursive: true });
34340
- const filePath = join46(contextDir, CONTEXT_SAVE_FILE);
34551
+ const filePath = join47(contextDir, CONTEXT_SAVE_FILE);
34341
34552
  let ctx;
34342
34553
  try {
34343
34554
  if (existsSync31(filePath)) {
@@ -34356,7 +34567,7 @@ function saveSessionContext(repoRoot, entry) {
34356
34567
  writeFileSync12(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
34357
34568
  }
34358
34569
  function loadSessionContext(repoRoot) {
34359
- const filePath = join46(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
34570
+ const filePath = join47(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
34360
34571
  try {
34361
34572
  if (!existsSync31(filePath))
34362
34573
  return null;
@@ -34407,7 +34618,7 @@ function detectManifests(repoRoot) {
34407
34618
  { file: "docker-compose.yaml", type: "Docker Compose" }
34408
34619
  ];
34409
34620
  for (const check of checks) {
34410
- const filePath = join46(repoRoot, check.file);
34621
+ const filePath = join47(repoRoot, check.file);
34411
34622
  if (existsSync31(filePath)) {
34412
34623
  let name;
34413
34624
  if (check.nameField) {
@@ -34441,7 +34652,7 @@ function findKeyFiles(repoRoot) {
34441
34652
  { pattern: "CLAUDE.md", description: "Claude Code context" }
34442
34653
  ];
34443
34654
  for (const check of checks) {
34444
- if (existsSync31(join46(repoRoot, check.pattern))) {
34655
+ if (existsSync31(join47(repoRoot, check.pattern))) {
34445
34656
  keyFiles.push({ path: check.pattern, description: check.description });
34446
34657
  }
34447
34658
  }
@@ -34467,12 +34678,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
34467
34678
  if (entry.isDirectory()) {
34468
34679
  let fileCount = 0;
34469
34680
  try {
34470
- fileCount = readdirSync8(join46(root, entry.name)).filter((f) => !f.startsWith(".")).length;
34681
+ fileCount = readdirSync8(join47(root, entry.name)).filter((f) => !f.startsWith(".")).length;
34471
34682
  } catch {
34472
34683
  }
34473
34684
  result += `${prefix}${connector}${entry.name}/ (${fileCount})
34474
34685
  `;
34475
- result += buildDirTree(join46(root, entry.name), maxDepth, childPrefix, depth + 1);
34686
+ result += buildDirTree(join47(root, entry.name), maxDepth, childPrefix, depth + 1);
34476
34687
  } else if (depth < maxDepth) {
34477
34688
  result += `${prefix}${connector}${entry.name}
34478
34689
  `;
@@ -34492,7 +34703,7 @@ function loadUsageFile(filePath) {
34492
34703
  return { records: [] };
34493
34704
  }
34494
34705
  function saveUsageFile(filePath, data) {
34495
- const dir = join46(filePath, "..");
34706
+ const dir = join47(filePath, "..");
34496
34707
  mkdirSync11(dir, { recursive: true });
34497
34708
  writeFileSync12(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
34498
34709
  }
@@ -34522,15 +34733,15 @@ function recordUsage(kind, value, opts) {
34522
34733
  }
34523
34734
  saveUsageFile(filePath, data);
34524
34735
  };
34525
- update(join46(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34736
+ update(join47(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34526
34737
  if (opts?.repoRoot) {
34527
- update(join46(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34738
+ update(join47(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34528
34739
  }
34529
34740
  }
34530
34741
  function loadUsageHistory(kind, repoRoot) {
34531
- const globalPath = join46(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
34742
+ const globalPath = join47(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
34532
34743
  const globalData = loadUsageFile(globalPath);
34533
- const localData = repoRoot ? loadUsageFile(join46(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
34744
+ const localData = repoRoot ? loadUsageFile(join47(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
34534
34745
  const map = /* @__PURE__ */ new Map();
34535
34746
  for (const r of globalData.records) {
34536
34747
  if (r.kind !== kind)
@@ -34561,9 +34772,9 @@ function deleteUsageRecord(kind, value, repoRoot) {
34561
34772
  saveUsageFile(filePath, data);
34562
34773
  }
34563
34774
  };
34564
- remove(join46(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34775
+ remove(join47(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34565
34776
  if (repoRoot) {
34566
- remove(join46(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34777
+ remove(join47(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34567
34778
  }
34568
34779
  }
34569
34780
  var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
@@ -34614,7 +34825,7 @@ import * as readline from "node:readline";
34614
34825
  import { execSync as execSync24, spawn as spawn18, exec as exec2 } from "node:child_process";
34615
34826
  import { promisify as promisify5 } from "node:util";
34616
34827
  import { existsSync as existsSync32, writeFileSync as writeFileSync13, readFileSync as readFileSync23, appendFileSync as appendFileSync2, mkdirSync as mkdirSync12 } from "node:fs";
34617
- import { join as join47 } from "node:path";
34828
+ import { join as join48 } from "node:path";
34618
34829
  import { homedir as homedir10, platform } from "node:os";
34619
34830
  function detectSystemSpecs() {
34620
34831
  let totalRamGB = 0;
@@ -35655,9 +35866,9 @@ async function doSetup(config, rl) {
35655
35866
  `PARAMETER num_predict ${numPredict}`,
35656
35867
  `PARAMETER stop "<|endoftext|>"`
35657
35868
  ].join("\n");
35658
- const modelDir2 = join47(homedir10(), ".open-agents", "models");
35869
+ const modelDir2 = join48(homedir10(), ".open-agents", "models");
35659
35870
  mkdirSync12(modelDir2, { recursive: true });
35660
- const modelfilePath = join47(modelDir2, `Modelfile.${customName}`);
35871
+ const modelfilePath = join48(modelDir2, `Modelfile.${customName}`);
35661
35872
  writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
35662
35873
  process.stdout.write(` ${c2.dim("Creating model...")} `);
35663
35874
  execSync24(`ollama create ${customName} -f ${modelfilePath}`, {
@@ -35703,7 +35914,7 @@ async function isModelAvailable(config) {
35703
35914
  }
35704
35915
  function isFirstRun() {
35705
35916
  try {
35706
- return !existsSync32(join47(homedir10(), ".open-agents", "config.json"));
35917
+ return !existsSync32(join48(homedir10(), ".open-agents", "config.json"));
35707
35918
  } catch {
35708
35919
  return true;
35709
35920
  }
@@ -35740,7 +35951,7 @@ function detectPkgManager() {
35740
35951
  return null;
35741
35952
  }
35742
35953
  function getVenvDir() {
35743
- return join47(homedir10(), ".open-agents", "venv");
35954
+ return join48(homedir10(), ".open-agents", "venv");
35744
35955
  }
35745
35956
  function hasVenvModule() {
35746
35957
  try {
@@ -35752,7 +35963,7 @@ function hasVenvModule() {
35752
35963
  }
35753
35964
  function ensureVenv(log) {
35754
35965
  const venvDir = getVenvDir();
35755
- const venvPip = join47(venvDir, "bin", "pip");
35966
+ const venvPip = join48(venvDir, "bin", "pip");
35756
35967
  if (existsSync32(venvPip))
35757
35968
  return venvDir;
35758
35969
  log("Creating Python venv for vision deps...");
@@ -35765,9 +35976,9 @@ function ensureVenv(log) {
35765
35976
  return null;
35766
35977
  }
35767
35978
  try {
35768
- mkdirSync12(join47(homedir10(), ".open-agents"), { recursive: true });
35979
+ mkdirSync12(join48(homedir10(), ".open-agents"), { recursive: true });
35769
35980
  execSync24(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
35770
- execSync24(`"${join47(venvDir, "bin", "pip")}" install --upgrade pip`, {
35981
+ execSync24(`"${join48(venvDir, "bin", "pip")}" install --upgrade pip`, {
35771
35982
  stdio: "pipe",
35772
35983
  timeout: 6e4
35773
35984
  });
@@ -35958,11 +36169,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
35958
36169
  }
35959
36170
  }
35960
36171
  const venvDir = getVenvDir();
35961
- const venvBin = join47(venvDir, "bin");
35962
- const venvMoondream = join47(venvBin, "moondream-station");
36172
+ const venvBin = join48(venvDir, "bin");
36173
+ const venvMoondream = join48(venvBin, "moondream-station");
35963
36174
  const venv = ensureVenv(log);
35964
36175
  if (venv && !hasCmd("moondream-station") && !existsSync32(venvMoondream)) {
35965
- const venvPip = join47(venvBin, "pip");
36176
+ const venvPip = join48(venvBin, "pip");
35966
36177
  log("Installing moondream-station in ~/.open-agents/venv...");
35967
36178
  try {
35968
36179
  execSync24(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
@@ -35983,8 +36194,8 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
35983
36194
  }
35984
36195
  }
35985
36196
  if (venv) {
35986
- const venvPython = join47(venvBin, "python");
35987
- const venvPip2 = join47(venvBin, "pip");
36197
+ const venvPython = join48(venvBin, "python");
36198
+ const venvPip2 = join48(venvBin, "pip");
35988
36199
  let ocrStackInstalled = false;
35989
36200
  try {
35990
36201
  execSync24(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
@@ -36128,9 +36339,9 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
36128
36339
  `PARAMETER num_predict ${numPredict}`,
36129
36340
  `PARAMETER stop "<|endoftext|>"`
36130
36341
  ].join("\n");
36131
- const modelDir2 = join47(homedir10(), ".open-agents", "models");
36342
+ const modelDir2 = join48(homedir10(), ".open-agents", "models");
36132
36343
  mkdirSync12(modelDir2, { recursive: true });
36133
- const modelfilePath = join47(modelDir2, `Modelfile.${customName}`);
36344
+ const modelfilePath = join48(modelDir2, `Modelfile.${customName}`);
36134
36345
  writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
36135
36346
  await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
36136
36347
  timeout: 12e4
@@ -36205,8 +36416,8 @@ async function ensureNeovim() {
36205
36416
  const platform5 = process.platform;
36206
36417
  const arch = process.arch;
36207
36418
  if (platform5 === "linux") {
36208
- const binDir = join47(homedir10(), ".local", "bin");
36209
- const nvimDest = join47(binDir, "nvim");
36419
+ const binDir = join48(homedir10(), ".local", "bin");
36420
+ const nvimDest = join48(binDir, "nvim");
36210
36421
  try {
36211
36422
  mkdirSync12(binDir, { recursive: true });
36212
36423
  } catch {
@@ -36277,7 +36488,7 @@ async function ensureNeovim() {
36277
36488
  }
36278
36489
  function ensurePathInShellRc(binDir) {
36279
36490
  const shell = process.env.SHELL ?? "";
36280
- const rcFile = shell.includes("zsh") ? join47(homedir10(), ".zshrc") : join47(homedir10(), ".bashrc");
36491
+ const rcFile = shell.includes("zsh") ? join48(homedir10(), ".zshrc") : join48(homedir10(), ".bashrc");
36281
36492
  try {
36282
36493
  const rcContent = existsSync32(rcFile) ? readFileSync23(rcFile, "utf8") : "";
36283
36494
  if (rcContent.includes(binDir))
@@ -37049,7 +37260,7 @@ var init_drop_panel = __esm({
37049
37260
  // packages/cli/dist/tui/neovim-mode.js
37050
37261
  import { existsSync as existsSync34, unlinkSync as unlinkSync7 } from "node:fs";
37051
37262
  import { tmpdir as tmpdir8 } from "node:os";
37052
- import { join as join48 } from "node:path";
37263
+ import { join as join49 } from "node:path";
37053
37264
  import { execSync as execSync25 } from "node:child_process";
37054
37265
  function isNeovimActive() {
37055
37266
  return _state !== null && !_state.cleanedUp;
@@ -37097,7 +37308,7 @@ async function startNeovimMode(opts) {
37097
37308
  );
37098
37309
  } catch {
37099
37310
  }
37100
- const socketPath = join48(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
37311
+ const socketPath = join49(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
37101
37312
  try {
37102
37313
  if (existsSync34(socketPath))
37103
37314
  unlinkSync7(socketPath);
@@ -37449,7 +37660,7 @@ __export(voice_exports, {
37449
37660
  resetNarrationContext: () => resetNarrationContext
37450
37661
  });
37451
37662
  import { existsSync as existsSync35, mkdirSync as mkdirSync13, writeFileSync as writeFileSync14, readFileSync as readFileSync24, unlinkSync as unlinkSync8, readdirSync as readdirSync9, renameSync, statSync as statSync12 } from "node:fs";
37452
- import { join as join49 } from "node:path";
37663
+ import { join as join50 } from "node:path";
37453
37664
  import { homedir as homedir11, tmpdir as tmpdir9, platform as platform2 } from "node:os";
37454
37665
  import { execSync as execSync26, spawn as nodeSpawn } from "node:child_process";
37455
37666
  import { createRequire } from "node:module";
@@ -37471,34 +37682,34 @@ function listVoiceModels() {
37471
37682
  }));
37472
37683
  }
37473
37684
  function voiceDir() {
37474
- return join49(homedir11(), ".open-agents", "voice");
37685
+ return join50(homedir11(), ".open-agents", "voice");
37475
37686
  }
37476
37687
  function modelsDir() {
37477
- return join49(voiceDir(), "models");
37688
+ return join50(voiceDir(), "models");
37478
37689
  }
37479
37690
  function modelDir(id) {
37480
- return join49(modelsDir(), id);
37691
+ return join50(modelsDir(), id);
37481
37692
  }
37482
37693
  function modelOnnxPath(id) {
37483
- return join49(modelDir(id), "model.onnx");
37694
+ return join50(modelDir(id), "model.onnx");
37484
37695
  }
37485
37696
  function modelConfigPath(id) {
37486
- return join49(modelDir(id), "config.json");
37697
+ return join50(modelDir(id), "config.json");
37487
37698
  }
37488
37699
  function luxttsVenvDir() {
37489
- return join49(voiceDir(), "luxtts-venv");
37700
+ return join50(voiceDir(), "luxtts-venv");
37490
37701
  }
37491
37702
  function luxttsVenvPy() {
37492
- return platform2() === "win32" ? join49(luxttsVenvDir(), "Scripts", "python.exe") : join49(luxttsVenvDir(), "bin", "python3");
37703
+ return platform2() === "win32" ? join50(luxttsVenvDir(), "Scripts", "python.exe") : join50(luxttsVenvDir(), "bin", "python3");
37493
37704
  }
37494
37705
  function luxttsRepoDir() {
37495
- return join49(voiceDir(), "LuxTTS");
37706
+ return join50(voiceDir(), "LuxTTS");
37496
37707
  }
37497
37708
  function luxttsCloneRefsDir() {
37498
- return join49(voiceDir(), "clone-refs");
37709
+ return join50(voiceDir(), "clone-refs");
37499
37710
  }
37500
37711
  function luxttsInferScript() {
37501
- return join49(voiceDir(), "luxtts-infer.py");
37712
+ return join50(voiceDir(), "luxtts-infer.py");
37502
37713
  }
37503
37714
  function emotionToPitchBias(emotion, stark = false, autist = false) {
37504
37715
  if (autist)
@@ -38306,7 +38517,7 @@ var init_voice = __esm({
38306
38517
  const refsDir = luxttsCloneRefsDir();
38307
38518
  const targets = ["glados", "overwatch"];
38308
38519
  for (const modelId of targets) {
38309
- const refFile = join49(refsDir, `${modelId}-ref.wav`);
38520
+ const refFile = join50(refsDir, `${modelId}-ref.wav`);
38310
38521
  if (existsSync35(refFile))
38311
38522
  continue;
38312
38523
  try {
@@ -38386,7 +38597,7 @@ var init_voice = __esm({
38386
38597
  }
38387
38598
  p = p.replace(/\\ /g, " ");
38388
38599
  if (p.startsWith("~/") || p === "~") {
38389
- p = join49(homedir11(), p.slice(1));
38600
+ p = join50(homedir11(), p.slice(1));
38390
38601
  }
38391
38602
  if (!existsSync35(p)) {
38392
38603
  return `File not found: ${p}
@@ -38400,7 +38611,7 @@ var init_voice = __esm({
38400
38611
  const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
38401
38612
  const ts = Date.now().toString(36);
38402
38613
  const destFilename = `clone-${srcName}-${ts}.${ext}`;
38403
- const destPath = join49(refsDir, destFilename);
38614
+ const destPath = join50(refsDir, destFilename);
38404
38615
  try {
38405
38616
  const data = readFileSync24(audioPath);
38406
38617
  writeFileSync14(destPath, data);
@@ -38445,7 +38656,7 @@ var init_voice = __esm({
38445
38656
  const refsDir = luxttsCloneRefsDir();
38446
38657
  if (!existsSync35(refsDir))
38447
38658
  mkdirSync13(refsDir, { recursive: true });
38448
- const destPath = join49(refsDir, `${sourceModelId}-ref.wav`);
38659
+ const destPath = join50(refsDir, `${sourceModelId}-ref.wav`);
38449
38660
  const sampleRate = this.config?.audio?.sample_rate ?? 22050;
38450
38661
  this.writeWav(audioData, sampleRate, destPath);
38451
38662
  this.luxttsCloneRef = destPath;
@@ -38461,7 +38672,7 @@ var init_voice = __esm({
38461
38672
  // -------------------------------------------------------------------------
38462
38673
  /** Metadata file for friendly names of clone refs */
38463
38674
  static cloneMetaFile() {
38464
- return join49(luxttsCloneRefsDir(), "meta.json");
38675
+ return join50(luxttsCloneRefsDir(), "meta.json");
38465
38676
  }
38466
38677
  loadCloneMeta() {
38467
38678
  const p = _VoiceEngine.cloneMetaFile();
@@ -38495,7 +38706,7 @@ var init_voice = __esm({
38495
38706
  return _VoiceEngine.AUDIO_EXTS.has(ext);
38496
38707
  });
38497
38708
  return files.map((f) => {
38498
- const p = join49(dir, f);
38709
+ const p = join50(dir, f);
38499
38710
  let size = 0;
38500
38711
  try {
38501
38712
  size = statSync12(p).size;
@@ -38512,7 +38723,7 @@ var init_voice = __esm({
38512
38723
  }
38513
38724
  /** Delete a clone reference file by filename. Returns true if deleted. */
38514
38725
  deleteCloneRef(filename) {
38515
- const p = join49(luxttsCloneRefsDir(), filename);
38726
+ const p = join50(luxttsCloneRefsDir(), filename);
38516
38727
  if (!existsSync35(p))
38517
38728
  return false;
38518
38729
  try {
@@ -38537,7 +38748,7 @@ var init_voice = __esm({
38537
38748
  }
38538
38749
  /** Set the active clone reference by filename. */
38539
38750
  setActiveCloneRef(filename) {
38540
- const p = join49(luxttsCloneRefsDir(), filename);
38751
+ const p = join50(luxttsCloneRefsDir(), filename);
38541
38752
  if (!existsSync35(p))
38542
38753
  return `File not found: ${filename}`;
38543
38754
  this.luxttsCloneRef = p;
@@ -38823,7 +39034,7 @@ var init_voice = __esm({
38823
39034
  }
38824
39035
  this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
38825
39036
  }
38826
- const wavPath = join49(tmpdir9(), `oa-voice-${Date.now()}.wav`);
39037
+ const wavPath = join50(tmpdir9(), `oa-voice-${Date.now()}.wav`);
38827
39038
  this.writeWav(audioData, sampleRate, wavPath);
38828
39039
  await this.playWav(wavPath);
38829
39040
  try {
@@ -39166,7 +39377,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
39166
39377
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
39167
39378
  const mlxVoice = model.mlxVoice ?? "af_heart";
39168
39379
  const mlxLangCode = model.mlxLangCode ?? "a";
39169
- const wavPath = join49(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
39380
+ const wavPath = join50(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
39170
39381
  const pyScript = [
39171
39382
  "import sys, json",
39172
39383
  "from mlx_audio.tts import generate as tts_gen",
@@ -39234,7 +39445,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
39234
39445
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
39235
39446
  const mlxVoice = model.mlxVoice ?? "af_heart";
39236
39447
  const mlxLangCode = model.mlxLangCode ?? "a";
39237
- const wavPath = join49(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
39448
+ const wavPath = join50(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
39238
39449
  const pyScript = [
39239
39450
  "import sys, json",
39240
39451
  "from mlx_audio.tts import generate as tts_gen",
@@ -39345,7 +39556,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
39345
39556
  }
39346
39557
  }
39347
39558
  const repoDir = luxttsRepoDir();
39348
- if (!existsSync35(join49(repoDir, "zipvoice", "luxvoice.py"))) {
39559
+ if (!existsSync35(join50(repoDir, "zipvoice", "luxvoice.py"))) {
39349
39560
  renderInfo(" Cloning LuxTTS repository...");
39350
39561
  try {
39351
39562
  if (existsSync35(repoDir)) {
@@ -39394,7 +39605,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
39394
39605
  if (!existsSync35(refsDir))
39395
39606
  return;
39396
39607
  for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
39397
- const p = join49(refsDir, name);
39608
+ const p = join50(refsDir, name);
39398
39609
  if (existsSync35(p)) {
39399
39610
  this.luxttsCloneRef = p;
39400
39611
  return;
@@ -39591,7 +39802,7 @@ if __name__ == '__main__':
39591
39802
  const ready = await this.ensureLuxttsDaemon();
39592
39803
  if (!ready)
39593
39804
  return;
39594
- const wavPath = join49(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
39805
+ const wavPath = join50(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
39595
39806
  try {
39596
39807
  await this.luxttsRequest({
39597
39808
  action: "synthesize",
@@ -39665,7 +39876,7 @@ if __name__ == '__main__':
39665
39876
  const ready = await this.ensureLuxttsDaemon();
39666
39877
  if (!ready)
39667
39878
  return null;
39668
- const wavPath = join49(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
39879
+ const wavPath = join50(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
39669
39880
  try {
39670
39881
  await this.luxttsRequest({
39671
39882
  action: "synthesize",
@@ -39695,7 +39906,7 @@ if __name__ == '__main__':
39695
39906
  return;
39696
39907
  const arch = process.arch;
39697
39908
  mkdirSync13(voiceDir(), { recursive: true });
39698
- const pkgPath = join49(voiceDir(), "package.json");
39909
+ const pkgPath = join50(voiceDir(), "package.json");
39699
39910
  const expectedDeps = {
39700
39911
  "onnxruntime-node": "^1.21.0",
39701
39912
  "phonemizer": "^1.2.1"
@@ -39717,17 +39928,17 @@ if __name__ == '__main__':
39717
39928
  dependencies: expectedDeps
39718
39929
  }, null, 2));
39719
39930
  }
39720
- const voiceRequire = createRequire(join49(voiceDir(), "index.js"));
39931
+ const voiceRequire = createRequire(join50(voiceDir(), "index.js"));
39721
39932
  const probeOnnx = () => {
39722
39933
  try {
39723
- const result = execSync26(`node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, { cwd: voiceDir(), stdio: "pipe", timeout: 15e3, env: { ...process.env, NODE_PATH: join49(voiceDir(), "node_modules") } });
39934
+ const result = execSync26(`node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, { cwd: voiceDir(), stdio: "pipe", timeout: 15e3, env: { ...process.env, NODE_PATH: join50(voiceDir(), "node_modules") } });
39724
39935
  const output = result.toString().trim();
39725
39936
  return output === "OK";
39726
39937
  } catch {
39727
39938
  return false;
39728
39939
  }
39729
39940
  };
39730
- const onnxNodeModules = join49(voiceDir(), "node_modules", "onnxruntime-node");
39941
+ const onnxNodeModules = join50(voiceDir(), "node_modules", "onnxruntime-node");
39731
39942
  const onnxInstalled = existsSync35(onnxNodeModules);
39732
39943
  if (onnxInstalled && !probeOnnx()) {
39733
39944
  throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch}). This is a known issue with some ARM SoCs where the CPU vendor is not recognized. Voice feedback will be disabled but all other features work normally.`);
@@ -42131,8 +42342,8 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
42131
42342
  if (models.length > 0) {
42132
42343
  try {
42133
42344
  const { writeFileSync: writeFileSync20, mkdirSync: mkdirSync21 } = await import("node:fs");
42134
- const { join: join63, dirname: dirname20 } = await import("node:path");
42135
- const cachePath = join63(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
42345
+ const { join: join64, dirname: dirname20 } = await import("node:path");
42346
+ const cachePath = join64(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
42136
42347
  mkdirSync21(dirname20(cachePath), { recursive: true });
42137
42348
  writeFileSync20(cachePath, JSON.stringify({
42138
42349
  peerId,
@@ -42333,14 +42544,14 @@ async function handleUpdate(subcommand, ctx) {
42333
42544
  try {
42334
42545
  const { createRequire: createRequire4 } = await import("node:module");
42335
42546
  const { fileURLToPath: fileURLToPath14 } = await import("node:url");
42336
- const { dirname: dirname20, join: join63 } = await import("node:path");
42547
+ const { dirname: dirname20, join: join64 } = await import("node:path");
42337
42548
  const { existsSync: existsSync45 } = await import("node:fs");
42338
42549
  const req = createRequire4(import.meta.url);
42339
42550
  const thisDir = dirname20(fileURLToPath14(import.meta.url));
42340
42551
  const candidates = [
42341
- join63(thisDir, "..", "package.json"),
42342
- join63(thisDir, "..", "..", "package.json"),
42343
- join63(thisDir, "..", "..", "..", "package.json")
42552
+ join64(thisDir, "..", "package.json"),
42553
+ join64(thisDir, "..", "..", "package.json"),
42554
+ join64(thisDir, "..", "..", "..", "package.json")
42344
42555
  ];
42345
42556
  for (const pkgPath of candidates) {
42346
42557
  if (existsSync45(pkgPath)) {
@@ -43099,7 +43310,7 @@ var init_commands = __esm({
43099
43310
 
43100
43311
  // packages/cli/dist/tui/project-context.js
43101
43312
  import { existsSync as existsSync36, readFileSync as readFileSync25, readdirSync as readdirSync10 } from "node:fs";
43102
- import { join as join50, basename as basename10 } from "node:path";
43313
+ import { join as join51, basename as basename10 } from "node:path";
43103
43314
  import { execSync as execSync27 } from "node:child_process";
43104
43315
  import { homedir as homedir12, platform as platform3, release } from "node:os";
43105
43316
  function getModelTier(modelName) {
@@ -43134,7 +43345,7 @@ function loadProjectMap(repoRoot) {
43134
43345
  if (!hasOaDirectory(repoRoot)) {
43135
43346
  initOaDirectory(repoRoot);
43136
43347
  }
43137
- const mapPath = join50(repoRoot, OA_DIR, "context", "project-map.md");
43348
+ const mapPath = join51(repoRoot, OA_DIR, "context", "project-map.md");
43138
43349
  if (existsSync36(mapPath)) {
43139
43350
  try {
43140
43351
  const content = readFileSync25(mapPath, "utf-8");
@@ -43178,17 +43389,17 @@ ${log}`);
43178
43389
  }
43179
43390
  function loadMemoryContext(repoRoot) {
43180
43391
  const sections = [];
43181
- const oaMemDir = join50(repoRoot, OA_DIR, "memory");
43392
+ const oaMemDir = join51(repoRoot, OA_DIR, "memory");
43182
43393
  const oaEntries = loadMemoryDir(oaMemDir, "project");
43183
43394
  if (oaEntries)
43184
43395
  sections.push(oaEntries);
43185
- const legacyMemDir = join50(repoRoot, ".open-agents", "memory");
43396
+ const legacyMemDir = join51(repoRoot, ".open-agents", "memory");
43186
43397
  if (legacyMemDir !== oaMemDir && existsSync36(legacyMemDir)) {
43187
43398
  const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
43188
43399
  if (legacyEntries)
43189
43400
  sections.push(legacyEntries);
43190
43401
  }
43191
- const globalMemDir = join50(homedir12(), ".open-agents", "memory");
43402
+ const globalMemDir = join51(homedir12(), ".open-agents", "memory");
43192
43403
  const globalEntries = loadMemoryDir(globalMemDir, "global");
43193
43404
  if (globalEntries)
43194
43405
  sections.push(globalEntries);
@@ -43202,7 +43413,7 @@ function loadMemoryDir(memDir, scope) {
43202
43413
  const files = readdirSync10(memDir).filter((f) => f.endsWith(".json"));
43203
43414
  for (const file of files.slice(0, 10)) {
43204
43415
  try {
43205
- const raw = readFileSync25(join50(memDir, file), "utf-8");
43416
+ const raw = readFileSync25(join51(memDir, file), "utf-8");
43206
43417
  const entries = JSON.parse(raw);
43207
43418
  const topic = basename10(file, ".json");
43208
43419
  const keys = Object.keys(entries);
@@ -44421,9 +44632,9 @@ var init_banner = __esm({
44421
44632
 
44422
44633
  // packages/cli/dist/tui/carousel-descriptors.js
44423
44634
  import { existsSync as existsSync37, readFileSync as readFileSync26, writeFileSync as writeFileSync15, mkdirSync as mkdirSync14, readdirSync as readdirSync11 } from "node:fs";
44424
- import { join as join51, basename as basename11 } from "node:path";
44635
+ import { join as join52, basename as basename11 } from "node:path";
44425
44636
  function loadToolProfile(repoRoot) {
44426
- const filePath = join51(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
44637
+ const filePath = join52(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
44427
44638
  try {
44428
44639
  if (!existsSync37(filePath))
44429
44640
  return null;
@@ -44433,9 +44644,9 @@ function loadToolProfile(repoRoot) {
44433
44644
  }
44434
44645
  }
44435
44646
  function saveToolProfile(repoRoot, profile) {
44436
- const contextDir = join51(repoRoot, OA_DIR, "context");
44647
+ const contextDir = join52(repoRoot, OA_DIR, "context");
44437
44648
  mkdirSync14(contextDir, { recursive: true });
44438
- writeFileSync15(join51(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
44649
+ writeFileSync15(join52(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
44439
44650
  }
44440
44651
  function categorizeToolCall(toolName) {
44441
44652
  for (const cat of TOOL_CATEGORIES) {
@@ -44493,7 +44704,7 @@ function weightedColor(profile) {
44493
44704
  return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
44494
44705
  }
44495
44706
  function loadCachedDescriptors(repoRoot) {
44496
- const filePath = join51(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
44707
+ const filePath = join52(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
44497
44708
  try {
44498
44709
  if (!existsSync37(filePath))
44499
44710
  return null;
@@ -44504,14 +44715,14 @@ function loadCachedDescriptors(repoRoot) {
44504
44715
  }
44505
44716
  }
44506
44717
  function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
44507
- const contextDir = join51(repoRoot, OA_DIR, "context");
44718
+ const contextDir = join52(repoRoot, OA_DIR, "context");
44508
44719
  mkdirSync14(contextDir, { recursive: true });
44509
44720
  const cached = {
44510
44721
  phrases,
44511
44722
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
44512
44723
  sourceHash
44513
44724
  };
44514
- writeFileSync15(join51(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
44725
+ writeFileSync15(join52(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
44515
44726
  }
44516
44727
  function generateDescriptors(repoRoot) {
44517
44728
  const profile = loadToolProfile(repoRoot);
@@ -44559,7 +44770,7 @@ function generateDescriptors(repoRoot) {
44559
44770
  return phrases;
44560
44771
  }
44561
44772
  function extractFromPackageJson(repoRoot, tags) {
44562
- const pkgPath = join51(repoRoot, "package.json");
44773
+ const pkgPath = join52(repoRoot, "package.json");
44563
44774
  try {
44564
44775
  if (!existsSync37(pkgPath))
44565
44776
  return;
@@ -44607,7 +44818,7 @@ function extractFromManifests(repoRoot, tags) {
44607
44818
  { file: ".github/workflows", tag: "ci/cd" }
44608
44819
  ];
44609
44820
  for (const check of manifestChecks) {
44610
- if (existsSync37(join51(repoRoot, check.file))) {
44821
+ if (existsSync37(join52(repoRoot, check.file))) {
44611
44822
  tags.push(check.tag);
44612
44823
  }
44613
44824
  }
@@ -44629,7 +44840,7 @@ function extractFromSessions(repoRoot, tags) {
44629
44840
  }
44630
44841
  }
44631
44842
  function extractFromMemory(repoRoot, tags) {
44632
- const memoryDir = join51(repoRoot, OA_DIR, "memory");
44843
+ const memoryDir = join52(repoRoot, OA_DIR, "memory");
44633
44844
  try {
44634
44845
  if (!existsSync37(memoryDir))
44635
44846
  return;
@@ -44638,7 +44849,7 @@ function extractFromMemory(repoRoot, tags) {
44638
44849
  const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
44639
44850
  tags.push(topic);
44640
44851
  try {
44641
- const data = JSON.parse(readFileSync26(join51(memoryDir, file), "utf-8"));
44852
+ const data = JSON.parse(readFileSync26(join52(memoryDir, file), "utf-8"));
44642
44853
  if (data && typeof data === "object") {
44643
44854
  const keys = Object.keys(data).slice(0, 3);
44644
44855
  for (const key of keys) {
@@ -45261,10 +45472,10 @@ var init_stream_renderer = __esm({
45261
45472
 
45262
45473
  // packages/cli/dist/tui/edit-history.js
45263
45474
  import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync15 } from "node:fs";
45264
- import { join as join52 } from "node:path";
45475
+ import { join as join53 } from "node:path";
45265
45476
  function createEditHistoryLogger(repoRoot, sessionId) {
45266
- const historyDir = join52(repoRoot, ".oa", "history");
45267
- const logPath = join52(historyDir, "edits.jsonl");
45477
+ const historyDir = join53(repoRoot, ".oa", "history");
45478
+ const logPath = join53(historyDir, "edits.jsonl");
45268
45479
  try {
45269
45480
  mkdirSync15(historyDir, { recursive: true });
45270
45481
  } catch {
@@ -45376,12 +45587,12 @@ var init_edit_history = __esm({
45376
45587
 
45377
45588
  // packages/cli/dist/tui/promptLoader.js
45378
45589
  import { readFileSync as readFileSync27, existsSync as existsSync38 } from "node:fs";
45379
- import { join as join53, dirname as dirname17 } from "node:path";
45590
+ import { join as join54, dirname as dirname17 } from "node:path";
45380
45591
  import { fileURLToPath as fileURLToPath11 } from "node:url";
45381
45592
  function loadPrompt3(promptPath, vars) {
45382
45593
  let content = cache3.get(promptPath);
45383
45594
  if (content === void 0) {
45384
- const fullPath = join53(PROMPTS_DIR3, promptPath);
45595
+ const fullPath = join54(PROMPTS_DIR3, promptPath);
45385
45596
  if (!existsSync38(fullPath)) {
45386
45597
  throw new Error(`Prompt file not found: ${fullPath}`);
45387
45598
  }
@@ -45398,8 +45609,8 @@ var init_promptLoader3 = __esm({
45398
45609
  "use strict";
45399
45610
  __filename3 = fileURLToPath11(import.meta.url);
45400
45611
  __dirname6 = dirname17(__filename3);
45401
- devPath2 = join53(__dirname6, "..", "..", "prompts");
45402
- publishedPath2 = join53(__dirname6, "..", "prompts");
45612
+ devPath2 = join54(__dirname6, "..", "..", "prompts");
45613
+ publishedPath2 = join54(__dirname6, "..", "prompts");
45403
45614
  PROMPTS_DIR3 = existsSync38(devPath2) ? devPath2 : publishedPath2;
45404
45615
  cache3 = /* @__PURE__ */ new Map();
45405
45616
  }
@@ -45407,10 +45618,10 @@ var init_promptLoader3 = __esm({
45407
45618
 
45408
45619
  // packages/cli/dist/tui/dream-engine.js
45409
45620
  import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync16, readFileSync as readFileSync28, existsSync as existsSync39, cpSync, rmSync, readdirSync as readdirSync12 } from "node:fs";
45410
- import { join as join54, basename as basename12 } from "node:path";
45621
+ import { join as join55, basename as basename12 } from "node:path";
45411
45622
  import { execSync as execSync28 } from "node:child_process";
45412
45623
  function loadAutoresearchMemory(repoRoot) {
45413
- const memoryPath = join54(repoRoot, ".oa", "memory", "autoresearch.json");
45624
+ const memoryPath = join55(repoRoot, ".oa", "memory", "autoresearch.json");
45414
45625
  if (!existsSync39(memoryPath))
45415
45626
  return "";
45416
45627
  try {
@@ -45604,12 +45815,12 @@ var init_dream_engine = __esm({
45604
45815
  const content = String(args["content"] ?? "");
45605
45816
  if (!rawPath)
45606
45817
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
45607
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join54(this.autoresearchDir, basename12(rawPath)) : join54(this.autoresearchDir, rawPath);
45818
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join55(this.autoresearchDir, basename12(rawPath)) : join55(this.autoresearchDir, rawPath);
45608
45819
  if (!targetPath.startsWith(this.autoresearchDir)) {
45609
45820
  return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
45610
45821
  }
45611
45822
  try {
45612
- const dir = join54(targetPath, "..");
45823
+ const dir = join55(targetPath, "..");
45613
45824
  mkdirSync16(dir, { recursive: true });
45614
45825
  writeFileSync16(targetPath, content, "utf-8");
45615
45826
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -45639,7 +45850,7 @@ var init_dream_engine = __esm({
45639
45850
  const rawPath = String(args["path"] ?? "");
45640
45851
  const oldStr = String(args["old_string"] ?? "");
45641
45852
  const newStr = String(args["new_string"] ?? "");
45642
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join54(this.autoresearchDir, basename12(rawPath)) : join54(this.autoresearchDir, rawPath);
45853
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join55(this.autoresearchDir, basename12(rawPath)) : join55(this.autoresearchDir, rawPath);
45643
45854
  if (!targetPath.startsWith(this.autoresearchDir)) {
45644
45855
  return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
45645
45856
  }
@@ -45693,12 +45904,12 @@ var init_dream_engine = __esm({
45693
45904
  const content = String(args["content"] ?? "");
45694
45905
  if (!rawPath)
45695
45906
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
45696
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join54(this.dreamsDir, basename12(rawPath)) : join54(this.dreamsDir, rawPath);
45907
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join55(this.dreamsDir, basename12(rawPath)) : join55(this.dreamsDir, rawPath);
45697
45908
  if (!targetPath.startsWith(this.dreamsDir)) {
45698
45909
  return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
45699
45910
  }
45700
45911
  try {
45701
- const dir = join54(targetPath, "..");
45912
+ const dir = join55(targetPath, "..");
45702
45913
  mkdirSync16(dir, { recursive: true });
45703
45914
  writeFileSync16(targetPath, content, "utf-8");
45704
45915
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -45728,7 +45939,7 @@ var init_dream_engine = __esm({
45728
45939
  const rawPath = String(args["path"] ?? "");
45729
45940
  const oldStr = String(args["old_string"] ?? "");
45730
45941
  const newStr = String(args["new_string"] ?? "");
45731
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join54(this.dreamsDir, basename12(rawPath)) : join54(this.dreamsDir, rawPath);
45942
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join55(this.dreamsDir, basename12(rawPath)) : join55(this.dreamsDir, rawPath);
45732
45943
  if (!targetPath.startsWith(this.dreamsDir)) {
45733
45944
  return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
45734
45945
  }
@@ -45795,7 +46006,7 @@ var init_dream_engine = __esm({
45795
46006
  constructor(config, repoRoot) {
45796
46007
  this.config = config;
45797
46008
  this.repoRoot = repoRoot;
45798
- this.dreamsDir = join54(repoRoot, ".oa", "dreams");
46009
+ this.dreamsDir = join55(repoRoot, ".oa", "dreams");
45799
46010
  this.state = {
45800
46011
  mode: "default",
45801
46012
  active: false,
@@ -45879,7 +46090,7 @@ ${result.summary}`;
45879
46090
  if (mode !== "default" || cycle === totalCycles) {
45880
46091
  renderDreamContraction(cycle);
45881
46092
  const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
45882
- const summaryPath = join54(this.dreamsDir, `cycle-${cycle}-summary.md`);
46093
+ const summaryPath = join55(this.dreamsDir, `cycle-${cycle}-summary.md`);
45883
46094
  writeFileSync16(summaryPath, cycleSummary, "utf-8");
45884
46095
  }
45885
46096
  if (mode === "lucid" && !this.abortController.signal.aborted) {
@@ -46092,7 +46303,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
46092
46303
  }
46093
46304
  /** Build role-specific tool sets for swarm agents */
46094
46305
  buildSwarmTools(role, _workspace) {
46095
- const autoresearchDir = join54(this.repoRoot, ".oa", "autoresearch");
46306
+ const autoresearchDir = join55(this.repoRoot, ".oa", "autoresearch");
46096
46307
  const taskComplete = this.createSwarmTaskCompleteTool(role);
46097
46308
  switch (role) {
46098
46309
  case "researcher": {
@@ -46456,7 +46667,7 @@ INSTRUCTIONS:
46456
46667
  2. Summarize the key learnings and next steps
46457
46668
 
46458
46669
  Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
46459
- const reportPath = join54(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
46670
+ const reportPath = join55(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
46460
46671
  const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
46461
46672
 
46462
46673
  **Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -46545,7 +46756,7 @@ ${summaryResult}
46545
46756
  }
46546
46757
  /** Save workspace backup for lucid mode */
46547
46758
  saveVersionCheckpoint(cycle) {
46548
- const checkpointDir = join54(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
46759
+ const checkpointDir = join55(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
46549
46760
  try {
46550
46761
  mkdirSync16(checkpointDir, { recursive: true });
46551
46762
  try {
@@ -46564,10 +46775,10 @@ ${summaryResult}
46564
46775
  encoding: "utf-8",
46565
46776
  timeout: 5e3
46566
46777
  }).trim();
46567
- writeFileSync16(join54(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
46568
- writeFileSync16(join54(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
46569
- writeFileSync16(join54(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
46570
- writeFileSync16(join54(checkpointDir, "checkpoint.json"), JSON.stringify({
46778
+ writeFileSync16(join55(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
46779
+ writeFileSync16(join55(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
46780
+ writeFileSync16(join55(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
46781
+ writeFileSync16(join55(checkpointDir, "checkpoint.json"), JSON.stringify({
46571
46782
  cycle,
46572
46783
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
46573
46784
  gitHash,
@@ -46575,7 +46786,7 @@ ${summaryResult}
46575
46786
  }, null, 2), "utf-8");
46576
46787
  renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
46577
46788
  } catch {
46578
- writeFileSync16(join54(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
46789
+ writeFileSync16(join55(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
46579
46790
  renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
46580
46791
  }
46581
46792
  } catch (err) {
@@ -46633,14 +46844,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
46633
46844
  ---
46634
46845
  *Auto-generated by open-agents dream engine*
46635
46846
  `;
46636
- writeFileSync16(join54(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
46847
+ writeFileSync16(join55(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
46637
46848
  } catch {
46638
46849
  }
46639
46850
  }
46640
46851
  /** Save dream state for resume/inspection */
46641
46852
  saveDreamState() {
46642
46853
  try {
46643
- writeFileSync16(join54(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
46854
+ writeFileSync16(join55(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
46644
46855
  } catch {
46645
46856
  }
46646
46857
  }
@@ -47015,7 +47226,7 @@ var init_bless_engine = __esm({
47015
47226
 
47016
47227
  // packages/cli/dist/tui/dmn-engine.js
47017
47228
  import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync17, readdirSync as readdirSync13, unlinkSync as unlinkSync9 } from "node:fs";
47018
- import { join as join55, basename as basename13 } from "node:path";
47229
+ import { join as join56, basename as basename13 } from "node:path";
47019
47230
  function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
47020
47231
  const competenceReport = competence.length > 0 ? competence.map((c3) => {
47021
47232
  const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
@@ -47128,8 +47339,8 @@ var init_dmn_engine = __esm({
47128
47339
  constructor(config, repoRoot) {
47129
47340
  this.config = config;
47130
47341
  this.repoRoot = repoRoot;
47131
- this.stateDir = join55(repoRoot, ".oa", "dmn");
47132
- this.historyDir = join55(repoRoot, ".oa", "dmn", "cycles");
47342
+ this.stateDir = join56(repoRoot, ".oa", "dmn");
47343
+ this.historyDir = join56(repoRoot, ".oa", "dmn", "cycles");
47133
47344
  mkdirSync17(this.historyDir, { recursive: true });
47134
47345
  this.loadState();
47135
47346
  }
@@ -47719,8 +47930,8 @@ OUTPUT: Call task_complete with JSON:
47719
47930
  async gatherMemoryTopics() {
47720
47931
  const topics = [];
47721
47932
  const dirs = [
47722
- join55(this.repoRoot, ".oa", "memory"),
47723
- join55(this.repoRoot, ".open-agents", "memory")
47933
+ join56(this.repoRoot, ".oa", "memory"),
47934
+ join56(this.repoRoot, ".open-agents", "memory")
47724
47935
  ];
47725
47936
  for (const dir of dirs) {
47726
47937
  if (!existsSync40(dir))
@@ -47739,7 +47950,7 @@ OUTPUT: Call task_complete with JSON:
47739
47950
  }
47740
47951
  // ── State persistence ─────────────────────────────────────────────────
47741
47952
  loadState() {
47742
- const path = join55(this.stateDir, "state.json");
47953
+ const path = join56(this.stateDir, "state.json");
47743
47954
  if (existsSync40(path)) {
47744
47955
  try {
47745
47956
  this.state = JSON.parse(readFileSync29(path, "utf-8"));
@@ -47749,19 +47960,19 @@ OUTPUT: Call task_complete with JSON:
47749
47960
  }
47750
47961
  saveState() {
47751
47962
  try {
47752
- writeFileSync17(join55(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
47963
+ writeFileSync17(join56(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
47753
47964
  } catch {
47754
47965
  }
47755
47966
  }
47756
47967
  saveCycleResult(result) {
47757
47968
  try {
47758
47969
  const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
47759
- writeFileSync17(join55(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
47970
+ writeFileSync17(join56(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
47760
47971
  const files = readdirSync13(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
47761
47972
  if (files.length > 50) {
47762
47973
  for (const old of files.slice(0, files.length - 50)) {
47763
47974
  try {
47764
- unlinkSync9(join55(this.historyDir, old));
47975
+ unlinkSync9(join56(this.historyDir, old));
47765
47976
  } catch {
47766
47977
  }
47767
47978
  }
@@ -47775,7 +47986,7 @@ OUTPUT: Call task_complete with JSON:
47775
47986
 
47776
47987
  // packages/cli/dist/tui/snr-engine.js
47777
47988
  import { existsSync as existsSync41, readdirSync as readdirSync14, readFileSync as readFileSync30 } from "node:fs";
47778
- import { join as join56, basename as basename14 } from "node:path";
47989
+ import { join as join57, basename as basename14 } from "node:path";
47779
47990
  function computeDPrime(signalScores, noiseScores) {
47780
47991
  if (signalScores.length === 0 || noiseScores.length === 0)
47781
47992
  return 0;
@@ -48015,8 +48226,8 @@ Call task_complete with the JSON array when done.`, onEvent)
48015
48226
  loadMemoryEntries(topics) {
48016
48227
  const entries = [];
48017
48228
  const dirs = [
48018
- join56(this.repoRoot, ".oa", "memory"),
48019
- join56(this.repoRoot, ".open-agents", "memory")
48229
+ join57(this.repoRoot, ".oa", "memory"),
48230
+ join57(this.repoRoot, ".open-agents", "memory")
48020
48231
  ];
48021
48232
  for (const dir of dirs) {
48022
48233
  if (!existsSync41(dir))
@@ -48028,7 +48239,7 @@ Call task_complete with the JSON array when done.`, onEvent)
48028
48239
  if (topics.length > 0 && !topics.includes(topic))
48029
48240
  continue;
48030
48241
  try {
48031
- const data = JSON.parse(readFileSync30(join56(dir, f), "utf-8"));
48242
+ const data = JSON.parse(readFileSync30(join57(dir, f), "utf-8"));
48032
48243
  for (const [key, val] of Object.entries(data)) {
48033
48244
  const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
48034
48245
  entries.push({ topic, key, value });
@@ -48596,7 +48807,7 @@ var init_tool_policy = __esm({
48596
48807
 
48597
48808
  // packages/cli/dist/tui/telegram-bridge.js
48598
48809
  import { mkdirSync as mkdirSync18, existsSync as existsSync42, unlinkSync as unlinkSync10, readdirSync as readdirSync15, statSync as statSync13 } from "node:fs";
48599
- import { join as join57, resolve as resolve28 } from "node:path";
48810
+ import { join as join58, resolve as resolve28 } from "node:path";
48600
48811
  import { writeFile as writeFileAsync } from "node:fs/promises";
48601
48812
  function convertMarkdownToTelegramHTML(md) {
48602
48813
  let html = md;
@@ -49361,7 +49572,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
49361
49572
  return null;
49362
49573
  const buffer = Buffer.from(await res.arrayBuffer());
49363
49574
  const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
49364
- const localPath = join57(this.mediaCacheDir, fileName);
49575
+ const localPath = join58(this.mediaCacheDir, fileName);
49365
49576
  await writeFileAsync(localPath, buffer);
49366
49577
  return localPath;
49367
49578
  } catch {
@@ -51822,7 +52033,7 @@ var init_status_bar = __esm({
51822
52033
  import * as readline2 from "node:readline";
51823
52034
  import { Writable } from "node:stream";
51824
52035
  import { cwd } from "node:process";
51825
- import { resolve as resolve29, join as join58, dirname as dirname18, extname as extname10 } from "node:path";
52036
+ import { resolve as resolve29, join as join59, dirname as dirname18, extname as extname10 } from "node:path";
51826
52037
  import { createRequire as createRequire2 } from "node:module";
51827
52038
  import { fileURLToPath as fileURLToPath12 } from "node:url";
51828
52039
  import { readFileSync as readFileSync32, writeFileSync as writeFileSync18, appendFileSync as appendFileSync4, rmSync as rmSync2, readdirSync as readdirSync16, mkdirSync as mkdirSync19 } from "node:fs";
@@ -51846,9 +52057,9 @@ function getVersion3() {
51846
52057
  const require2 = createRequire2(import.meta.url);
51847
52058
  const thisDir = dirname18(fileURLToPath12(import.meta.url));
51848
52059
  const candidates = [
51849
- join58(thisDir, "..", "package.json"),
51850
- join58(thisDir, "..", "..", "package.json"),
51851
- join58(thisDir, "..", "..", "..", "package.json")
52060
+ join59(thisDir, "..", "package.json"),
52061
+ join59(thisDir, "..", "..", "package.json"),
52062
+ join59(thisDir, "..", "..", "..", "package.json")
51852
52063
  ];
51853
52064
  for (const pkgPath of candidates) {
51854
52065
  if (existsSync43(pkgPath)) {
@@ -51951,6 +52162,8 @@ function buildTools(repoRoot, config, contextWindowSize) {
51951
52162
  new ExplorationCultureTool(repoRoot),
51952
52163
  // Embedding Store — COHERE Private Brain semantic retrieval
51953
52164
  new EmbeddingStoreTool(repoRoot),
52165
+ // Image Generation — Ollama diffusion models
52166
+ new ImageGenerateTool(repoRoot, config.backendUrl),
51954
52167
  // Structured file reading (CSV, JSON, Markdown, binary detection)
51955
52168
  new StructuredReadTool(repoRoot),
51956
52169
  // Vision tools (Moondream — desktop awareness + point-and-click)
@@ -52070,15 +52283,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
52070
52283
  function gatherMemorySnippets(root) {
52071
52284
  const snippets = [];
52072
52285
  const dirs = [
52073
- join58(root, ".oa", "memory"),
52074
- join58(root, ".open-agents", "memory")
52286
+ join59(root, ".oa", "memory"),
52287
+ join59(root, ".open-agents", "memory")
52075
52288
  ];
52076
52289
  for (const dir of dirs) {
52077
52290
  if (!existsSync43(dir))
52078
52291
  continue;
52079
52292
  try {
52080
52293
  for (const f of readdirSync16(dir).filter((f2) => f2.endsWith(".json"))) {
52081
- const data = JSON.parse(readFileSync32(join58(dir, f), "utf-8"));
52294
+ const data = JSON.parse(readFileSync32(join59(dir, f), "utf-8"));
52082
52295
  for (const val of Object.values(data)) {
52083
52296
  const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
52084
52297
  if (v.length > 10)
@@ -53186,7 +53399,7 @@ async function startInteractive(config, repoPath) {
53186
53399
  let p2pGateway = null;
53187
53400
  let peerMesh = null;
53188
53401
  let inferenceRouter = null;
53189
- const secretVault = new SecretVault(join58(repoRoot, ".oa", "vault.enc"));
53402
+ const secretVault = new SecretVault(join59(repoRoot, ".oa", "vault.enc"));
53190
53403
  let adminSessionKey = null;
53191
53404
  const callSubAgents = /* @__PURE__ */ new Map();
53192
53405
  const streamRenderer = new StreamRenderer();
@@ -53395,8 +53608,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
53395
53608
  const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
53396
53609
  return [hits, line];
53397
53610
  }
53398
- const HISTORY_DIR = join58(homedir13(), ".open-agents");
53399
- const HISTORY_FILE = join58(HISTORY_DIR, "repl-history");
53611
+ const HISTORY_DIR = join59(homedir13(), ".open-agents");
53612
+ const HISTORY_FILE = join59(HISTORY_DIR, "repl-history");
53400
53613
  const MAX_HISTORY_LINES = 500;
53401
53614
  let savedHistory = [];
53402
53615
  try {
@@ -53606,7 +53819,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
53606
53819
  } catch {
53607
53820
  }
53608
53821
  try {
53609
- const oaDir = join58(repoRoot, ".oa");
53822
+ const oaDir = join59(repoRoot, ".oa");
53610
53823
  const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
53611
53824
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
53612
53825
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -53629,7 +53842,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
53629
53842
  } catch {
53630
53843
  }
53631
53844
  try {
53632
- const oaDir = join58(repoRoot, ".oa");
53845
+ const oaDir = join59(repoRoot, ".oa");
53633
53846
  const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
53634
53847
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
53635
53848
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -54463,7 +54676,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
54463
54676
  kind,
54464
54677
  targetUrl,
54465
54678
  authKey,
54466
- stateDir: join58(repoRoot, ".oa"),
54679
+ stateDir: join59(repoRoot, ".oa"),
54467
54680
  passthrough: passthrough ?? false,
54468
54681
  loadbalance: loadbalance ?? false,
54469
54682
  endpointAuth: passthrough ? currentConfig.apiKey : void 0,
@@ -54511,7 +54724,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
54511
54724
  await tunnelGateway.stop();
54512
54725
  tunnelGateway = null;
54513
54726
  }
54514
- const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join58(repoRoot, ".oa") });
54727
+ const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join59(repoRoot, ".oa") });
54515
54728
  newTunnel.on("stats", (stats) => {
54516
54729
  statusBar.setExposeStatus({
54517
54730
  status: stats.status,
@@ -54773,7 +54986,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
54773
54986
  }
54774
54987
  },
54775
54988
  destroyProject() {
54776
- const oaPath = join58(repoRoot, OA_DIR);
54989
+ const oaPath = join59(repoRoot, OA_DIR);
54777
54990
  if (existsSync43(oaPath)) {
54778
54991
  try {
54779
54992
  rmSync2(oaPath, { recursive: true, force: true });
@@ -55709,7 +55922,7 @@ import { glob } from "glob";
55709
55922
  import ignore from "ignore";
55710
55923
  import { readFile as readFile22, stat as stat4 } from "node:fs/promises";
55711
55924
  import { createHash as createHash4 } from "node:crypto";
55712
- import { join as join59, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
55925
+ import { join as join60, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
55713
55926
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
55714
55927
  var init_codebase_indexer = __esm({
55715
55928
  "packages/indexer/dist/codebase-indexer.js"() {
@@ -55753,7 +55966,7 @@ var init_codebase_indexer = __esm({
55753
55966
  const ig = ignore.default();
55754
55967
  if (this.config.respectGitignore) {
55755
55968
  try {
55756
- const gitignoreContent = await readFile22(join59(this.config.rootDir, ".gitignore"), "utf-8");
55969
+ const gitignoreContent = await readFile22(join60(this.config.rootDir, ".gitignore"), "utf-8");
55757
55970
  ig.add(gitignoreContent);
55758
55971
  } catch {
55759
55972
  }
@@ -55768,7 +55981,7 @@ var init_codebase_indexer = __esm({
55768
55981
  for (const relativePath of files) {
55769
55982
  if (ig.ignores(relativePath))
55770
55983
  continue;
55771
- const fullPath = join59(this.config.rootDir, relativePath);
55984
+ const fullPath = join60(this.config.rootDir, relativePath);
55772
55985
  try {
55773
55986
  const fileStat = await stat4(fullPath);
55774
55987
  if (fileStat.size > this.config.maxFileSize)
@@ -55814,7 +56027,7 @@ var init_codebase_indexer = __esm({
55814
56027
  if (!child) {
55815
56028
  child = {
55816
56029
  name: part,
55817
- path: join59(current.path, part),
56030
+ path: join60(current.path, part),
55818
56031
  type: "directory",
55819
56032
  children: []
55820
56033
  };
@@ -56155,7 +56368,7 @@ var config_exports = {};
56155
56368
  __export(config_exports, {
56156
56369
  configCommand: () => configCommand
56157
56370
  });
56158
- import { join as join60, resolve as resolve31 } from "node:path";
56371
+ import { join as join61, resolve as resolve31 } from "node:path";
56159
56372
  import { homedir as homedir14 } from "node:os";
56160
56373
  import { cwd as cwd3 } from "node:process";
56161
56374
  function redactIfSensitive(key, value) {
@@ -56238,7 +56451,7 @@ function handleShow(opts, config) {
56238
56451
  }
56239
56452
  }
56240
56453
  printSection("Config File");
56241
- printInfo(`~/.open-agents/config.json (${join60(homedir14(), ".open-agents", "config.json")})`);
56454
+ printInfo(`~/.open-agents/config.json (${join61(homedir14(), ".open-agents", "config.json")})`);
56242
56455
  printSection("Priority Chain");
56243
56456
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
56244
56457
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -56277,7 +56490,7 @@ function handleSet(opts, _config) {
56277
56490
  const coerced = coerceForSettings(key, value);
56278
56491
  saveProjectSettings(repoRoot, { [key]: coerced });
56279
56492
  printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
56280
- printInfo(`Saved to ${join60(repoRoot, ".oa", "settings.json")}`);
56493
+ printInfo(`Saved to ${join61(repoRoot, ".oa", "settings.json")}`);
56281
56494
  printInfo("This override applies only when running in this workspace.");
56282
56495
  } catch (err) {
56283
56496
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -56536,7 +56749,7 @@ __export(eval_exports, {
56536
56749
  });
56537
56750
  import { tmpdir as tmpdir10 } from "node:os";
56538
56751
  import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync19 } from "node:fs";
56539
- import { join as join61 } from "node:path";
56752
+ import { join as join62 } from "node:path";
56540
56753
  async function evalCommand(opts, config) {
56541
56754
  const suiteName = opts.suite ?? "basic";
56542
56755
  const suite = SUITES[suiteName];
@@ -56661,9 +56874,9 @@ async function evalCommand(opts, config) {
56661
56874
  process.exit(failed > 0 ? 1 : 0);
56662
56875
  }
56663
56876
  function createTempEvalRepo() {
56664
- const dir = join61(tmpdir10(), `open-agents-eval-${Date.now()}`);
56877
+ const dir = join62(tmpdir10(), `open-agents-eval-${Date.now()}`);
56665
56878
  mkdirSync20(dir, { recursive: true });
56666
- writeFileSync19(join61(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
56879
+ writeFileSync19(join62(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
56667
56880
  return dir;
56668
56881
  }
56669
56882
  var BASIC_SUITE, FULL_SUITE, SUITES;
@@ -56723,7 +56936,7 @@ init_updater();
56723
56936
  import { parseArgs as nodeParseArgs2 } from "node:util";
56724
56937
  import { createRequire as createRequire3 } from "node:module";
56725
56938
  import { fileURLToPath as fileURLToPath13 } from "node:url";
56726
- import { dirname as dirname19, join as join62 } from "node:path";
56939
+ import { dirname as dirname19, join as join63 } from "node:path";
56727
56940
 
56728
56941
  // packages/cli/dist/cli.js
56729
56942
  import { createInterface } from "node:readline";
@@ -56830,7 +57043,7 @@ init_output();
56830
57043
  function getVersion4() {
56831
57044
  try {
56832
57045
  const require2 = createRequire3(import.meta.url);
56833
- const pkgPath = join62(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
57046
+ const pkgPath = join63(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
56834
57047
  const pkg = require2(pkgPath);
56835
57048
  return pkg.version;
56836
57049
  } catch {