open-agents-ai 0.135.0 → 0.137.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 +554 -362
  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,10 @@ 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({ type: "error", content: `Model does not support tool calling. Use /model to select a model with tool support (e.g., qwen3.5, nemotron).`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
21587
+ break;
21588
+ }
21425
21589
  messages.push({ role: "user", content: "[System: backend request failed, retrying on next turn. The previous request was lost.]" });
21426
21590
  continue;
21427
21591
  }
@@ -22272,8 +22436,8 @@ ${marker}` : marker);
22272
22436
  return;
22273
22437
  try {
22274
22438
  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);
22439
+ const { join: join64 } = __require("node:path");
22440
+ const sessionDir = join64(this._workingDirectory, ".oa", "session", this._sessionId);
22277
22441
  mkdirSync21(sessionDir, { recursive: true });
22278
22442
  const checkpoint = {
22279
22443
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -22286,7 +22450,7 @@ ${marker}` : marker);
22286
22450
  memexEntryCount: this._memexArchive.size,
22287
22451
  fileRegistrySize: this._fileRegistry.size
22288
22452
  };
22289
- writeFileSync20(join63(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
22453
+ writeFileSync20(join64(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
22290
22454
  } catch {
22291
22455
  }
22292
22456
  }
@@ -23554,7 +23718,7 @@ ${transcript}`
23554
23718
  // packages/orchestrator/dist/nexusBackend.js
23555
23719
  import { existsSync as existsSync26, statSync as statSync9, openSync, readSync, closeSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync8 } from "node:fs";
23556
23720
  import { watch as fsWatch } from "node:fs";
23557
- import { join as join40 } from "node:path";
23721
+ import { join as join41 } from "node:path";
23558
23722
  import { tmpdir as tmpdir7 } from "node:os";
23559
23723
  import { randomBytes as randomBytes8 } from "node:crypto";
23560
23724
  var NexusAgenticBackend;
@@ -23704,7 +23868,7 @@ var init_nexusBackend = __esm({
23704
23868
  * Falls back to unary + word-split if streaming setup fails.
23705
23869
  */
23706
23870
  async *chatCompletionStream(request) {
23707
- const streamFile = join40(tmpdir7(), `nexus-stream-${randomBytes8(6).toString("hex")}.jsonl`);
23871
+ const streamFile = join41(tmpdir7(), `nexus-stream-${randomBytes8(6).toString("hex")}.jsonl`);
23708
23872
  writeFileSync8(streamFile, "", "utf8");
23709
23873
  const daemonArgs = {
23710
23874
  model: this.model,
@@ -24741,7 +24905,7 @@ __export(listen_exports, {
24741
24905
  });
24742
24906
  import { spawn as spawn15, execSync as execSync22 } from "node:child_process";
24743
24907
  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";
24908
+ import { join as join42, dirname as dirname13 } from "node:path";
24745
24909
  import { homedir as homedir8 } from "node:os";
24746
24910
  import { fileURLToPath as fileURLToPath8 } from "node:url";
24747
24911
  import { EventEmitter } from "node:events";
@@ -24827,12 +24991,12 @@ function findMicCaptureCommand() {
24827
24991
  function findLiveWhisperScript() {
24828
24992
  const thisDir = dirname13(fileURLToPath8(import.meta.url));
24829
24993
  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"),
24994
+ join42(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
24995
+ join42(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
24996
+ join42(thisDir, "../../execution/scripts/live-whisper.py"),
24833
24997
  // npm install layout — scripts bundled alongside dist
24834
- join41(thisDir, "../scripts/live-whisper.py"),
24835
- join41(thisDir, "../../scripts/live-whisper.py")
24998
+ join42(thisDir, "../scripts/live-whisper.py"),
24999
+ join42(thisDir, "../../scripts/live-whisper.py")
24836
25000
  ];
24837
25001
  for (const p of candidates) {
24838
25002
  if (existsSync27(p))
@@ -24845,8 +25009,8 @@ function findLiveWhisperScript() {
24845
25009
  stdio: ["pipe", "pipe", "pipe"]
24846
25010
  }).trim();
24847
25011
  const candidates2 = [
24848
- join41(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
24849
- join41(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
25012
+ join42(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
25013
+ join42(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
24850
25014
  ];
24851
25015
  for (const p of candidates2) {
24852
25016
  if (existsSync27(p))
@@ -24854,11 +25018,11 @@ function findLiveWhisperScript() {
24854
25018
  }
24855
25019
  } catch {
24856
25020
  }
24857
- const nvmBase = join41(homedir8(), ".nvm", "versions", "node");
25021
+ const nvmBase = join42(homedir8(), ".nvm", "versions", "node");
24858
25022
  if (existsSync27(nvmBase)) {
24859
25023
  try {
24860
25024
  for (const ver of readdirSync6(nvmBase)) {
24861
- const p = join41(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
25025
+ const p = join42(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
24862
25026
  if (existsSync27(p))
24863
25027
  return p;
24864
25028
  }
@@ -24877,7 +25041,7 @@ function ensureTranscribeCliBackground() {
24877
25041
  timeout: 5e3,
24878
25042
  stdio: ["pipe", "pipe", "pipe"]
24879
25043
  }).trim();
24880
- if (existsSync27(join41(globalRoot, "transcribe-cli", "dist", "index.js"))) {
25044
+ if (existsSync27(join42(globalRoot, "transcribe-cli", "dist", "index.js"))) {
24881
25045
  return true;
24882
25046
  }
24883
25047
  } catch {
@@ -25100,24 +25264,24 @@ var init_listen = __esm({
25100
25264
  timeout: 5e3,
25101
25265
  stdio: ["pipe", "pipe", "pipe"]
25102
25266
  }).trim();
25103
- const tcPath = join41(globalRoot, "transcribe-cli");
25104
- if (existsSync27(join41(tcPath, "dist", "index.js"))) {
25267
+ const tcPath = join42(globalRoot, "transcribe-cli");
25268
+ if (existsSync27(join42(tcPath, "dist", "index.js"))) {
25105
25269
  const { createRequire: createRequire4 } = await import("node:module");
25106
25270
  const req = createRequire4(import.meta.url);
25107
- return req(join41(tcPath, "dist", "index.js"));
25271
+ return req(join42(tcPath, "dist", "index.js"));
25108
25272
  }
25109
25273
  } catch {
25110
25274
  }
25111
- const nvmBase = join41(homedir8(), ".nvm", "versions", "node");
25275
+ const nvmBase = join42(homedir8(), ".nvm", "versions", "node");
25112
25276
  if (existsSync27(nvmBase)) {
25113
25277
  try {
25114
25278
  const { readdirSync: readdirSync17 } = await import("node:fs");
25115
25279
  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"))) {
25280
+ const tcPath = join42(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
25281
+ if (existsSync27(join42(tcPath, "dist", "index.js"))) {
25118
25282
  const { createRequire: createRequire4 } = await import("node:module");
25119
25283
  const req = createRequire4(import.meta.url);
25120
- return req(join41(tcPath, "dist", "index.js"));
25284
+ return req(join42(tcPath, "dist", "index.js"));
25121
25285
  }
25122
25286
  }
25123
25287
  } catch {
@@ -25399,9 +25563,9 @@ transcribe-cli error: ${transcribeCliError}` : "";
25399
25563
  });
25400
25564
  if (outputDir) {
25401
25565
  const { basename: basename16 } = await import("node:path");
25402
- const transcriptDir = join41(outputDir, ".oa", "transcripts");
25566
+ const transcriptDir = join42(outputDir, ".oa", "transcripts");
25403
25567
  mkdirSync8(transcriptDir, { recursive: true });
25404
- const outFile = join41(transcriptDir, `${basename16(filePath)}.txt`);
25568
+ const outFile = join42(transcriptDir, `${basename16(filePath)}.txt`);
25405
25569
  writeFileSync9(outFile, result.text, "utf-8");
25406
25570
  }
25407
25571
  return {
@@ -30760,7 +30924,7 @@ import { randomBytes as randomBytes9 } from "node:crypto";
30760
30924
  import { URL as URL2 } from "node:url";
30761
30925
  import { loadavg, cpus, totalmem, freemem } from "node:os";
30762
30926
  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";
30927
+ import { join as join43 } from "node:path";
30764
30928
  function cleanForwardHeaders(raw, targetHost) {
30765
30929
  const out = {};
30766
30930
  for (const [key, value] of Object.entries(raw)) {
@@ -30788,7 +30952,7 @@ function fmtTokens(n) {
30788
30952
  }
30789
30953
  function readExposeState(stateDir) {
30790
30954
  try {
30791
- const path = join42(stateDir, STATE_FILE_NAME);
30955
+ const path = join43(stateDir, STATE_FILE_NAME);
30792
30956
  if (!existsSync28(path))
30793
30957
  return null;
30794
30958
  const raw = readFileSync19(path, "utf8");
@@ -30803,13 +30967,13 @@ function readExposeState(stateDir) {
30803
30967
  function writeExposeState(stateDir, state) {
30804
30968
  try {
30805
30969
  mkdirSync9(stateDir, { recursive: true });
30806
- writeFileSync10(join42(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
30970
+ writeFileSync10(join43(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
30807
30971
  } catch {
30808
30972
  }
30809
30973
  }
30810
30974
  function removeExposeState(stateDir) {
30811
30975
  try {
30812
- unlinkSync5(join42(stateDir, STATE_FILE_NAME));
30976
+ unlinkSync5(join43(stateDir, STATE_FILE_NAME));
30813
30977
  } catch {
30814
30978
  }
30815
30979
  }
@@ -30898,7 +31062,7 @@ async function collectSystemMetricsAsync() {
30898
31062
  }
30899
31063
  function readP2PExposeState(stateDir) {
30900
31064
  try {
30901
- const path = join42(stateDir, P2P_STATE_FILE_NAME);
31065
+ const path = join43(stateDir, P2P_STATE_FILE_NAME);
30902
31066
  if (!existsSync28(path))
30903
31067
  return null;
30904
31068
  const raw = readFileSync19(path, "utf8");
@@ -30913,13 +31077,13 @@ function readP2PExposeState(stateDir) {
30913
31077
  function writeP2PExposeState(stateDir, state) {
30914
31078
  try {
30915
31079
  mkdirSync9(stateDir, { recursive: true });
30916
- writeFileSync10(join42(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
31080
+ writeFileSync10(join43(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
30917
31081
  } catch {
30918
31082
  }
30919
31083
  }
30920
31084
  function removeP2PExposeState(stateDir) {
30921
31085
  try {
30922
- unlinkSync5(join42(stateDir, P2P_STATE_FILE_NAME));
31086
+ unlinkSync5(join43(stateDir, P2P_STATE_FILE_NAME));
30923
31087
  } catch {
30924
31088
  }
30925
31089
  }
@@ -31767,7 +31931,7 @@ ${this.formatConnectionInfo()}`);
31767
31931
  throw new Error(`Expose failed: ${exposeResult.error}`);
31768
31932
  }
31769
31933
  const nexusDir = this._nexusTool.getNexusDir();
31770
- const statusPath = join42(nexusDir, "status.json");
31934
+ const statusPath = join43(nexusDir, "status.json");
31771
31935
  for (let i = 0; i < 80; i++) {
31772
31936
  try {
31773
31937
  const raw = readFileSync19(statusPath, "utf8");
@@ -31801,7 +31965,7 @@ ${this.formatConnectionInfo()}`);
31801
31965
  });
31802
31966
  }
31803
31967
  try {
31804
- const invocDir = join42(nexusDir, "invocations");
31968
+ const invocDir = join43(nexusDir, "invocations");
31805
31969
  if (existsSync28(invocDir)) {
31806
31970
  this._prevInvocCount = readdirSync7(invocDir).filter((f) => f.endsWith(".json")).length;
31807
31971
  this._stats.totalRequests = this._prevInvocCount;
@@ -31831,7 +31995,7 @@ ${this.formatConnectionInfo()}`);
31831
31995
  if (!state)
31832
31996
  return null;
31833
31997
  const nexusDir = nexusTool.getNexusDir();
31834
- const statusPath = join42(nexusDir, "status.json");
31998
+ const statusPath = join43(nexusDir, "status.json");
31835
31999
  try {
31836
32000
  if (!existsSync28(statusPath)) {
31837
32001
  removeP2PExposeState(stateDir);
@@ -31890,7 +32054,7 @@ ${this.formatConnectionInfo()}`);
31890
32054
  let lastMeteringLineCount = 0;
31891
32055
  this._activityPollTimer = setInterval(() => {
31892
32056
  try {
31893
- const invocDir = join42(nexusDir, "invocations");
32057
+ const invocDir = join43(nexusDir, "invocations");
31894
32058
  if (!existsSync28(invocDir))
31895
32059
  return;
31896
32060
  const files = readdirSync7(invocDir).filter((f) => f.endsWith(".json"));
@@ -31906,13 +32070,13 @@ ${this.formatConnectionInfo()}`);
31906
32070
  let recentActive = 0;
31907
32071
  for (const f of files.slice(-10)) {
31908
32072
  try {
31909
- const st = statSync10(join42(invocDir, f));
32073
+ const st = statSync10(join43(invocDir, f));
31910
32074
  if (now - st.mtimeMs < 1e4)
31911
32075
  recentActive++;
31912
32076
  } catch {
31913
32077
  }
31914
32078
  }
31915
- const meteringFile = join42(nexusDir, "metering.jsonl");
32079
+ const meteringFile = join43(nexusDir, "metering.jsonl");
31916
32080
  let meteringLines = lastMeteringLineCount;
31917
32081
  try {
31918
32082
  if (existsSync28(meteringFile)) {
@@ -31942,7 +32106,7 @@ ${this.formatConnectionInfo()}`);
31942
32106
  this._activityPollTimer.unref();
31943
32107
  this._pollTimer = setInterval(() => {
31944
32108
  try {
31945
- const statusPath = join42(nexusDir, "status.json");
32109
+ const statusPath = join43(nexusDir, "status.json");
31946
32110
  if (existsSync28(statusPath)) {
31947
32111
  const status = JSON.parse(readFileSync19(statusPath, "utf8"));
31948
32112
  if (status.peerId && !this._peerId) {
@@ -31953,7 +32117,7 @@ ${this.formatConnectionInfo()}`);
31953
32117
  } catch {
31954
32118
  }
31955
32119
  try {
31956
- const invocDir = join42(nexusDir, "invocations");
32120
+ const invocDir = join43(nexusDir, "invocations");
31957
32121
  if (existsSync28(invocDir)) {
31958
32122
  const files = readdirSync7(invocDir);
31959
32123
  const invocCount = files.filter((f) => f.endsWith(".json")).length;
@@ -31965,7 +32129,7 @@ ${this.formatConnectionInfo()}`);
31965
32129
  } catch {
31966
32130
  }
31967
32131
  try {
31968
- const meteringFile = join42(nexusDir, "metering.jsonl");
32132
+ const meteringFile = join43(nexusDir, "metering.jsonl");
31969
32133
  if (existsSync28(meteringFile)) {
31970
32134
  const content = readFileSync19(meteringFile, "utf8");
31971
32135
  if (content.length > lastMeteringSize) {
@@ -32177,7 +32341,7 @@ var init_types = __esm({
32177
32341
  // packages/cli/dist/tui/p2p/secret-vault.js
32178
32342
  import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes10, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
32179
32343
  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";
32344
+ import { join as join44, dirname as dirname14 } from "node:path";
32181
32345
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
32182
32346
  var init_secret_vault = __esm({
32183
32347
  "packages/cli/dist/tui/p2p/secret-vault.js"() {
@@ -33396,6 +33560,9 @@ ${activitySummary}
33396
33560
 
33397
33561
  // packages/cli/dist/tui/model-picker.js
33398
33562
  import { totalmem as totalmem2 } from "node:os";
33563
+ function isImageGenModel(name, family) {
33564
+ return IMAGE_GEN_PATTERNS.some((p) => p.test(name) || family && p.test(family));
33565
+ }
33399
33566
  async function fetchOllamaModels(baseUrl) {
33400
33567
  const url = `${normalizeBaseUrl(baseUrl)}/api/tags`;
33401
33568
  const resp = await fetch(url, {
@@ -33406,15 +33573,20 @@ async function fetchOllamaModels(baseUrl) {
33406
33573
  }
33407
33574
  const data = await resp.json();
33408
33575
  const models = data.models ?? [];
33409
- const result = models.map((m) => ({
33410
- name: m.name,
33411
- size: formatBytes(m.size),
33412
- sizeBytes: m.size,
33413
- modified: formatRelativeTime(m.modified_at),
33414
- parameterSize: m.details?.parameter_size,
33415
- contextLength: void 0,
33416
- caps: void 0
33417
- })).sort((a, b) => b.sizeBytes - a.sizeBytes);
33576
+ const result = models.map((m) => {
33577
+ const family = m.details?.family;
33578
+ return {
33579
+ name: m.name,
33580
+ size: formatBytes(m.size),
33581
+ sizeBytes: m.size,
33582
+ modified: formatRelativeTime(m.modified_at),
33583
+ parameterSize: m.details?.parameter_size,
33584
+ contextLength: void 0,
33585
+ caps: void 0,
33586
+ isImageGen: isImageGenModel(m.name, family),
33587
+ family
33588
+ };
33589
+ }).sort((a, b) => b.sizeBytes - a.sizeBytes);
33418
33590
  const normalized = normalizeBaseUrl(baseUrl);
33419
33591
  const showResults = await Promise.allSettled(result.map((m) => fetch(`${normalized}/api/show`, {
33420
33592
  method: "POST",
@@ -33514,13 +33686,13 @@ async function fetchPeerModels(peerId, authKey) {
33514
33686
  try {
33515
33687
  const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
33516
33688
  const { existsSync: existsSync45, readFileSync: readFileSync33 } = await import("node:fs");
33517
- const { join: join63 } = await import("node:path");
33689
+ const { join: join64 } = await import("node:path");
33518
33690
  const cwd4 = process.cwd();
33519
33691
  const nexusTool = new NexusTool2(cwd4);
33520
33692
  const nexusDir = nexusTool.getNexusDir();
33521
33693
  let isLocalPeer = false;
33522
33694
  try {
33523
- const statusPath = join63(nexusDir, "status.json");
33695
+ const statusPath = join64(nexusDir, "status.json");
33524
33696
  if (existsSync45(statusPath)) {
33525
33697
  const status = JSON.parse(readFileSync33(statusPath, "utf8"));
33526
33698
  if (status.peerId === peerId)
@@ -33529,7 +33701,7 @@ async function fetchPeerModels(peerId, authKey) {
33529
33701
  } catch {
33530
33702
  }
33531
33703
  if (isLocalPeer) {
33532
- const pricingPath = join63(nexusDir, "pricing.json");
33704
+ const pricingPath = join64(nexusDir, "pricing.json");
33533
33705
  if (existsSync45(pricingPath)) {
33534
33706
  try {
33535
33707
  const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
@@ -33546,7 +33718,7 @@ async function fetchPeerModels(peerId, authKey) {
33546
33718
  }
33547
33719
  }
33548
33720
  }
33549
- const cachePath = join63(nexusDir, "peer-models-cache.json");
33721
+ const cachePath = join64(nexusDir, "peer-models-cache.json");
33550
33722
  if (existsSync45(cachePath)) {
33551
33723
  try {
33552
33724
  const cache4 = JSON.parse(readFileSync33(cachePath, "utf8"));
@@ -33664,7 +33836,7 @@ async function fetchPeerModels(peerId, authKey) {
33664
33836
  } catch {
33665
33837
  }
33666
33838
  if (isLocalPeer) {
33667
- const pricingPath = join63(nexusDir, "pricing.json");
33839
+ const pricingPath = join64(nexusDir, "pricing.json");
33668
33840
  if (existsSync45(pricingPath)) {
33669
33841
  try {
33670
33842
  const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
@@ -33914,10 +34086,21 @@ function formatRelativeTime(iso) {
33914
34086
  const months = Math.floor(days / 30);
33915
34087
  return `${months}mo ago`;
33916
34088
  }
34089
+ var IMAGE_GEN_PATTERNS;
33917
34090
  var init_model_picker = __esm({
33918
34091
  "packages/cli/dist/tui/model-picker.js"() {
33919
34092
  "use strict";
33920
34093
  init_dist();
34094
+ IMAGE_GEN_PATTERNS = [
34095
+ /flux/i,
34096
+ /z-image/i,
34097
+ /stable-diffusion/i,
34098
+ /sdxl/i,
34099
+ /dall/i,
34100
+ /kandinsky/i,
34101
+ /midjourney/i,
34102
+ /imagen/i
34103
+ ];
33921
34104
  }
33922
34105
  });
33923
34106
 
@@ -33937,12 +34120,12 @@ var init_render2 = __esm({
33937
34120
 
33938
34121
  // packages/prompts/dist/promptLoader.js
33939
34122
  import { readFileSync as readFileSync21, existsSync as existsSync30 } from "node:fs";
33940
- import { join as join44, dirname as dirname15 } from "node:path";
34123
+ import { join as join45, dirname as dirname15 } from "node:path";
33941
34124
  import { fileURLToPath as fileURLToPath9 } from "node:url";
33942
34125
  function loadPrompt2(promptPath, vars) {
33943
34126
  let content = cache2.get(promptPath);
33944
34127
  if (content === void 0) {
33945
- const fullPath = join44(PROMPTS_DIR2, promptPath);
34128
+ const fullPath = join45(PROMPTS_DIR2, promptPath);
33946
34129
  if (!existsSync30(fullPath)) {
33947
34130
  throw new Error(`Prompt file not found: ${fullPath}`);
33948
34131
  }
@@ -33959,8 +34142,8 @@ var init_promptLoader2 = __esm({
33959
34142
  "use strict";
33960
34143
  __filename2 = fileURLToPath9(import.meta.url);
33961
34144
  __dirname5 = dirname15(__filename2);
33962
- devPath = join44(__dirname5, "..", "templates");
33963
- publishedPath = join44(__dirname5, "..", "prompts", "templates");
34145
+ devPath = join45(__dirname5, "..", "templates");
34146
+ publishedPath = join45(__dirname5, "..", "prompts", "templates");
33964
34147
  PROMPTS_DIR2 = existsSync30(devPath) ? devPath : publishedPath;
33965
34148
  cache2 = /* @__PURE__ */ new Map();
33966
34149
  }
@@ -34072,7 +34255,7 @@ var init_task_templates = __esm({
34072
34255
  });
34073
34256
 
34074
34257
  // packages/prompts/dist/index.js
34075
- import { join as join45, dirname as dirname16 } from "node:path";
34258
+ import { join as join46, dirname as dirname16 } from "node:path";
34076
34259
  import { fileURLToPath as fileURLToPath10 } from "node:url";
34077
34260
  var _dir, _packageRoot;
34078
34261
  var init_dist6 = __esm({
@@ -34083,21 +34266,21 @@ var init_dist6 = __esm({
34083
34266
  init_task_templates();
34084
34267
  init_render2();
34085
34268
  _dir = dirname16(fileURLToPath10(import.meta.url));
34086
- _packageRoot = join45(_dir, "..");
34269
+ _packageRoot = join46(_dir, "..");
34087
34270
  }
34088
34271
  });
34089
34272
 
34090
34273
  // packages/cli/dist/tui/oa-directory.js
34091
34274
  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";
34092
- import { join as join46, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
34275
+ import { join as join47, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
34093
34276
  import { homedir as homedir9 } from "node:os";
34094
34277
  function initOaDirectory(repoRoot) {
34095
- const oaPath = join46(repoRoot, OA_DIR);
34278
+ const oaPath = join47(repoRoot, OA_DIR);
34096
34279
  for (const sub of SUBDIRS) {
34097
- mkdirSync11(join46(oaPath, sub), { recursive: true });
34280
+ mkdirSync11(join47(oaPath, sub), { recursive: true });
34098
34281
  }
34099
34282
  try {
34100
- const gitignorePath = join46(repoRoot, ".gitignore");
34283
+ const gitignorePath = join47(repoRoot, ".gitignore");
34101
34284
  const settingsPattern = ".oa/settings.json";
34102
34285
  if (existsSync31(gitignorePath)) {
34103
34286
  const content = readFileSync22(gitignorePath, "utf-8");
@@ -34110,10 +34293,10 @@ function initOaDirectory(repoRoot) {
34110
34293
  return oaPath;
34111
34294
  }
34112
34295
  function hasOaDirectory(repoRoot) {
34113
- return existsSync31(join46(repoRoot, OA_DIR, "index"));
34296
+ return existsSync31(join47(repoRoot, OA_DIR, "index"));
34114
34297
  }
34115
34298
  function loadProjectSettings(repoRoot) {
34116
- const settingsPath = join46(repoRoot, OA_DIR, "settings.json");
34299
+ const settingsPath = join47(repoRoot, OA_DIR, "settings.json");
34117
34300
  try {
34118
34301
  if (existsSync31(settingsPath)) {
34119
34302
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
@@ -34123,14 +34306,14 @@ function loadProjectSettings(repoRoot) {
34123
34306
  return {};
34124
34307
  }
34125
34308
  function saveProjectSettings(repoRoot, settings) {
34126
- const oaPath = join46(repoRoot, OA_DIR);
34309
+ const oaPath = join47(repoRoot, OA_DIR);
34127
34310
  mkdirSync11(oaPath, { recursive: true });
34128
34311
  const existing = loadProjectSettings(repoRoot);
34129
34312
  const merged = { ...existing, ...settings };
34130
- writeFileSync12(join46(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
34313
+ writeFileSync12(join47(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
34131
34314
  }
34132
34315
  function loadGlobalSettings() {
34133
- const settingsPath = join46(homedir9(), ".open-agents", "settings.json");
34316
+ const settingsPath = join47(homedir9(), ".open-agents", "settings.json");
34134
34317
  try {
34135
34318
  if (existsSync31(settingsPath)) {
34136
34319
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
@@ -34140,11 +34323,11 @@ function loadGlobalSettings() {
34140
34323
  return {};
34141
34324
  }
34142
34325
  function saveGlobalSettings(settings) {
34143
- const dir = join46(homedir9(), ".open-agents");
34326
+ const dir = join47(homedir9(), ".open-agents");
34144
34327
  mkdirSync11(dir, { recursive: true });
34145
34328
  const existing = loadGlobalSettings();
34146
34329
  const merged = { ...existing, ...settings };
34147
- writeFileSync12(join46(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
34330
+ writeFileSync12(join47(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
34148
34331
  }
34149
34332
  function resolveSettings(repoRoot) {
34150
34333
  const global = loadGlobalSettings();
@@ -34159,7 +34342,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
34159
34342
  while (dir && !visited.has(dir)) {
34160
34343
  visited.add(dir);
34161
34344
  for (const name of CONTEXT_FILES) {
34162
- const filePath = join46(dir, name);
34345
+ const filePath = join47(dir, name);
34163
34346
  const normalizedName = name.toLowerCase();
34164
34347
  if (existsSync31(filePath) && !seen.has(filePath)) {
34165
34348
  seen.add(filePath);
@@ -34178,7 +34361,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
34178
34361
  }
34179
34362
  }
34180
34363
  }
34181
- const projectMap = join46(dir, OA_DIR, "context", "project-map.md");
34364
+ const projectMap = join47(dir, OA_DIR, "context", "project-map.md");
34182
34365
  if (existsSync31(projectMap) && !seen.has(projectMap)) {
34183
34366
  seen.add(projectMap);
34184
34367
  try {
@@ -34194,7 +34377,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
34194
34377
  } catch {
34195
34378
  }
34196
34379
  }
34197
- const parent = join46(dir, "..");
34380
+ const parent = join47(dir, "..");
34198
34381
  if (parent === dir)
34199
34382
  break;
34200
34383
  dir = parent;
@@ -34212,7 +34395,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
34212
34395
  return found;
34213
34396
  }
34214
34397
  function readIndexMeta(repoRoot) {
34215
- const metaPath = join46(repoRoot, OA_DIR, "index", "meta.json");
34398
+ const metaPath = join47(repoRoot, OA_DIR, "index", "meta.json");
34216
34399
  try {
34217
34400
  return JSON.parse(readFileSync22(metaPath, "utf-8"));
34218
34401
  } catch {
@@ -34265,28 +34448,28 @@ ${tree}\`\`\`
34265
34448
  sections.push("");
34266
34449
  }
34267
34450
  const content = sections.join("\n");
34268
- const contextDir = join46(repoRoot, OA_DIR, "context");
34451
+ const contextDir = join47(repoRoot, OA_DIR, "context");
34269
34452
  mkdirSync11(contextDir, { recursive: true });
34270
- writeFileSync12(join46(contextDir, "project-map.md"), content, "utf-8");
34453
+ writeFileSync12(join47(contextDir, "project-map.md"), content, "utf-8");
34271
34454
  return content;
34272
34455
  }
34273
34456
  function saveSession(repoRoot, session) {
34274
- const historyDir = join46(repoRoot, OA_DIR, "history");
34457
+ const historyDir = join47(repoRoot, OA_DIR, "history");
34275
34458
  mkdirSync11(historyDir, { recursive: true });
34276
- writeFileSync12(join46(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
34459
+ writeFileSync12(join47(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
34277
34460
  }
34278
34461
  function loadRecentSessions(repoRoot, limit = 5) {
34279
- const historyDir = join46(repoRoot, OA_DIR, "history");
34462
+ const historyDir = join47(repoRoot, OA_DIR, "history");
34280
34463
  if (!existsSync31(historyDir))
34281
34464
  return [];
34282
34465
  try {
34283
34466
  const files = readdirSync8(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
34284
- const stat5 = statSync11(join46(historyDir, f));
34467
+ const stat5 = statSync11(join47(historyDir, f));
34285
34468
  return { file: f, mtime: stat5.mtimeMs };
34286
34469
  }).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
34287
34470
  return files.map((f) => {
34288
34471
  try {
34289
- return JSON.parse(readFileSync22(join46(historyDir, f.file), "utf-8"));
34472
+ return JSON.parse(readFileSync22(join47(historyDir, f.file), "utf-8"));
34290
34473
  } catch {
34291
34474
  return null;
34292
34475
  }
@@ -34296,12 +34479,12 @@ function loadRecentSessions(repoRoot, limit = 5) {
34296
34479
  }
34297
34480
  }
34298
34481
  function savePendingTask(repoRoot, task) {
34299
- const historyDir = join46(repoRoot, OA_DIR, "history");
34482
+ const historyDir = join47(repoRoot, OA_DIR, "history");
34300
34483
  mkdirSync11(historyDir, { recursive: true });
34301
- writeFileSync12(join46(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
34484
+ writeFileSync12(join47(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
34302
34485
  }
34303
34486
  function loadPendingTask(repoRoot) {
34304
- const filePath = join46(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
34487
+ const filePath = join47(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
34305
34488
  try {
34306
34489
  if (!existsSync31(filePath))
34307
34490
  return null;
@@ -34316,9 +34499,9 @@ function loadPendingTask(repoRoot) {
34316
34499
  }
34317
34500
  }
34318
34501
  function saveSessionContext(repoRoot, entry) {
34319
- const contextDir = join46(repoRoot, OA_DIR, "context");
34502
+ const contextDir = join47(repoRoot, OA_DIR, "context");
34320
34503
  mkdirSync11(contextDir, { recursive: true });
34321
- const filePath = join46(contextDir, CONTEXT_SAVE_FILE);
34504
+ const filePath = join47(contextDir, CONTEXT_SAVE_FILE);
34322
34505
  let ctx;
34323
34506
  try {
34324
34507
  if (existsSync31(filePath)) {
@@ -34337,7 +34520,7 @@ function saveSessionContext(repoRoot, entry) {
34337
34520
  writeFileSync12(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
34338
34521
  }
34339
34522
  function loadSessionContext(repoRoot) {
34340
- const filePath = join46(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
34523
+ const filePath = join47(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
34341
34524
  try {
34342
34525
  if (!existsSync31(filePath))
34343
34526
  return null;
@@ -34388,7 +34571,7 @@ function detectManifests(repoRoot) {
34388
34571
  { file: "docker-compose.yaml", type: "Docker Compose" }
34389
34572
  ];
34390
34573
  for (const check of checks) {
34391
- const filePath = join46(repoRoot, check.file);
34574
+ const filePath = join47(repoRoot, check.file);
34392
34575
  if (existsSync31(filePath)) {
34393
34576
  let name;
34394
34577
  if (check.nameField) {
@@ -34422,7 +34605,7 @@ function findKeyFiles(repoRoot) {
34422
34605
  { pattern: "CLAUDE.md", description: "Claude Code context" }
34423
34606
  ];
34424
34607
  for (const check of checks) {
34425
- if (existsSync31(join46(repoRoot, check.pattern))) {
34608
+ if (existsSync31(join47(repoRoot, check.pattern))) {
34426
34609
  keyFiles.push({ path: check.pattern, description: check.description });
34427
34610
  }
34428
34611
  }
@@ -34448,12 +34631,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
34448
34631
  if (entry.isDirectory()) {
34449
34632
  let fileCount = 0;
34450
34633
  try {
34451
- fileCount = readdirSync8(join46(root, entry.name)).filter((f) => !f.startsWith(".")).length;
34634
+ fileCount = readdirSync8(join47(root, entry.name)).filter((f) => !f.startsWith(".")).length;
34452
34635
  } catch {
34453
34636
  }
34454
34637
  result += `${prefix}${connector}${entry.name}/ (${fileCount})
34455
34638
  `;
34456
- result += buildDirTree(join46(root, entry.name), maxDepth, childPrefix, depth + 1);
34639
+ result += buildDirTree(join47(root, entry.name), maxDepth, childPrefix, depth + 1);
34457
34640
  } else if (depth < maxDepth) {
34458
34641
  result += `${prefix}${connector}${entry.name}
34459
34642
  `;
@@ -34473,7 +34656,7 @@ function loadUsageFile(filePath) {
34473
34656
  return { records: [] };
34474
34657
  }
34475
34658
  function saveUsageFile(filePath, data) {
34476
- const dir = join46(filePath, "..");
34659
+ const dir = join47(filePath, "..");
34477
34660
  mkdirSync11(dir, { recursive: true });
34478
34661
  writeFileSync12(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
34479
34662
  }
@@ -34503,15 +34686,15 @@ function recordUsage(kind, value, opts) {
34503
34686
  }
34504
34687
  saveUsageFile(filePath, data);
34505
34688
  };
34506
- update(join46(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34689
+ update(join47(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34507
34690
  if (opts?.repoRoot) {
34508
- update(join46(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34691
+ update(join47(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34509
34692
  }
34510
34693
  }
34511
34694
  function loadUsageHistory(kind, repoRoot) {
34512
- const globalPath = join46(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
34695
+ const globalPath = join47(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
34513
34696
  const globalData = loadUsageFile(globalPath);
34514
- const localData = repoRoot ? loadUsageFile(join46(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
34697
+ const localData = repoRoot ? loadUsageFile(join47(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
34515
34698
  const map = /* @__PURE__ */ new Map();
34516
34699
  for (const r of globalData.records) {
34517
34700
  if (r.kind !== kind)
@@ -34542,9 +34725,9 @@ function deleteUsageRecord(kind, value, repoRoot) {
34542
34725
  saveUsageFile(filePath, data);
34543
34726
  }
34544
34727
  };
34545
- remove(join46(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34728
+ remove(join47(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34546
34729
  if (repoRoot) {
34547
- remove(join46(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34730
+ remove(join47(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34548
34731
  }
34549
34732
  }
34550
34733
  var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
@@ -34595,7 +34778,7 @@ import * as readline from "node:readline";
34595
34778
  import { execSync as execSync24, spawn as spawn18, exec as exec2 } from "node:child_process";
34596
34779
  import { promisify as promisify5 } from "node:util";
34597
34780
  import { existsSync as existsSync32, writeFileSync as writeFileSync13, readFileSync as readFileSync23, appendFileSync as appendFileSync2, mkdirSync as mkdirSync12 } from "node:fs";
34598
- import { join as join47 } from "node:path";
34781
+ import { join as join48 } from "node:path";
34599
34782
  import { homedir as homedir10, platform } from "node:os";
34600
34783
  function detectSystemSpecs() {
34601
34784
  let totalRamGB = 0;
@@ -35636,9 +35819,9 @@ async function doSetup(config, rl) {
35636
35819
  `PARAMETER num_predict ${numPredict}`,
35637
35820
  `PARAMETER stop "<|endoftext|>"`
35638
35821
  ].join("\n");
35639
- const modelDir2 = join47(homedir10(), ".open-agents", "models");
35822
+ const modelDir2 = join48(homedir10(), ".open-agents", "models");
35640
35823
  mkdirSync12(modelDir2, { recursive: true });
35641
- const modelfilePath = join47(modelDir2, `Modelfile.${customName}`);
35824
+ const modelfilePath = join48(modelDir2, `Modelfile.${customName}`);
35642
35825
  writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
35643
35826
  process.stdout.write(` ${c2.dim("Creating model...")} `);
35644
35827
  execSync24(`ollama create ${customName} -f ${modelfilePath}`, {
@@ -35684,7 +35867,7 @@ async function isModelAvailable(config) {
35684
35867
  }
35685
35868
  function isFirstRun() {
35686
35869
  try {
35687
- return !existsSync32(join47(homedir10(), ".open-agents", "config.json"));
35870
+ return !existsSync32(join48(homedir10(), ".open-agents", "config.json"));
35688
35871
  } catch {
35689
35872
  return true;
35690
35873
  }
@@ -35721,7 +35904,7 @@ function detectPkgManager() {
35721
35904
  return null;
35722
35905
  }
35723
35906
  function getVenvDir() {
35724
- return join47(homedir10(), ".open-agents", "venv");
35907
+ return join48(homedir10(), ".open-agents", "venv");
35725
35908
  }
35726
35909
  function hasVenvModule() {
35727
35910
  try {
@@ -35733,7 +35916,7 @@ function hasVenvModule() {
35733
35916
  }
35734
35917
  function ensureVenv(log) {
35735
35918
  const venvDir = getVenvDir();
35736
- const venvPip = join47(venvDir, "bin", "pip");
35919
+ const venvPip = join48(venvDir, "bin", "pip");
35737
35920
  if (existsSync32(venvPip))
35738
35921
  return venvDir;
35739
35922
  log("Creating Python venv for vision deps...");
@@ -35746,9 +35929,9 @@ function ensureVenv(log) {
35746
35929
  return null;
35747
35930
  }
35748
35931
  try {
35749
- mkdirSync12(join47(homedir10(), ".open-agents"), { recursive: true });
35932
+ mkdirSync12(join48(homedir10(), ".open-agents"), { recursive: true });
35750
35933
  execSync24(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
35751
- execSync24(`"${join47(venvDir, "bin", "pip")}" install --upgrade pip`, {
35934
+ execSync24(`"${join48(venvDir, "bin", "pip")}" install --upgrade pip`, {
35752
35935
  stdio: "pipe",
35753
35936
  timeout: 6e4
35754
35937
  });
@@ -35939,11 +36122,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
35939
36122
  }
35940
36123
  }
35941
36124
  const venvDir = getVenvDir();
35942
- const venvBin = join47(venvDir, "bin");
35943
- const venvMoondream = join47(venvBin, "moondream-station");
36125
+ const venvBin = join48(venvDir, "bin");
36126
+ const venvMoondream = join48(venvBin, "moondream-station");
35944
36127
  const venv = ensureVenv(log);
35945
36128
  if (venv && !hasCmd("moondream-station") && !existsSync32(venvMoondream)) {
35946
- const venvPip = join47(venvBin, "pip");
36129
+ const venvPip = join48(venvBin, "pip");
35947
36130
  log("Installing moondream-station in ~/.open-agents/venv...");
35948
36131
  try {
35949
36132
  execSync24(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
@@ -35964,8 +36147,8 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
35964
36147
  }
35965
36148
  }
35966
36149
  if (venv) {
35967
- const venvPython = join47(venvBin, "python");
35968
- const venvPip2 = join47(venvBin, "pip");
36150
+ const venvPython = join48(venvBin, "python");
36151
+ const venvPip2 = join48(venvBin, "pip");
35969
36152
  let ocrStackInstalled = false;
35970
36153
  try {
35971
36154
  execSync24(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
@@ -36109,9 +36292,9 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
36109
36292
  `PARAMETER num_predict ${numPredict}`,
36110
36293
  `PARAMETER stop "<|endoftext|>"`
36111
36294
  ].join("\n");
36112
- const modelDir2 = join47(homedir10(), ".open-agents", "models");
36295
+ const modelDir2 = join48(homedir10(), ".open-agents", "models");
36113
36296
  mkdirSync12(modelDir2, { recursive: true });
36114
- const modelfilePath = join47(modelDir2, `Modelfile.${customName}`);
36297
+ const modelfilePath = join48(modelDir2, `Modelfile.${customName}`);
36115
36298
  writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
36116
36299
  await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
36117
36300
  timeout: 12e4
@@ -36186,8 +36369,8 @@ async function ensureNeovim() {
36186
36369
  const platform5 = process.platform;
36187
36370
  const arch = process.arch;
36188
36371
  if (platform5 === "linux") {
36189
- const binDir = join47(homedir10(), ".local", "bin");
36190
- const nvimDest = join47(binDir, "nvim");
36372
+ const binDir = join48(homedir10(), ".local", "bin");
36373
+ const nvimDest = join48(binDir, "nvim");
36191
36374
  try {
36192
36375
  mkdirSync12(binDir, { recursive: true });
36193
36376
  } catch {
@@ -36258,7 +36441,7 @@ async function ensureNeovim() {
36258
36441
  }
36259
36442
  function ensurePathInShellRc(binDir) {
36260
36443
  const shell = process.env.SHELL ?? "";
36261
- const rcFile = shell.includes("zsh") ? join47(homedir10(), ".zshrc") : join47(homedir10(), ".bashrc");
36444
+ const rcFile = shell.includes("zsh") ? join48(homedir10(), ".zshrc") : join48(homedir10(), ".bashrc");
36262
36445
  try {
36263
36446
  const rcContent = existsSync32(rcFile) ? readFileSync23(rcFile, "utf8") : "";
36264
36447
  if (rcContent.includes(binDir))
@@ -37030,7 +37213,7 @@ var init_drop_panel = __esm({
37030
37213
  // packages/cli/dist/tui/neovim-mode.js
37031
37214
  import { existsSync as existsSync34, unlinkSync as unlinkSync7 } from "node:fs";
37032
37215
  import { tmpdir as tmpdir8 } from "node:os";
37033
- import { join as join48 } from "node:path";
37216
+ import { join as join49 } from "node:path";
37034
37217
  import { execSync as execSync25 } from "node:child_process";
37035
37218
  function isNeovimActive() {
37036
37219
  return _state !== null && !_state.cleanedUp;
@@ -37078,7 +37261,7 @@ async function startNeovimMode(opts) {
37078
37261
  );
37079
37262
  } catch {
37080
37263
  }
37081
- const socketPath = join48(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
37264
+ const socketPath = join49(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
37082
37265
  try {
37083
37266
  if (existsSync34(socketPath))
37084
37267
  unlinkSync7(socketPath);
@@ -37430,7 +37613,7 @@ __export(voice_exports, {
37430
37613
  resetNarrationContext: () => resetNarrationContext
37431
37614
  });
37432
37615
  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";
37433
- import { join as join49 } from "node:path";
37616
+ import { join as join50 } from "node:path";
37434
37617
  import { homedir as homedir11, tmpdir as tmpdir9, platform as platform2 } from "node:os";
37435
37618
  import { execSync as execSync26, spawn as nodeSpawn } from "node:child_process";
37436
37619
  import { createRequire } from "node:module";
@@ -37452,34 +37635,34 @@ function listVoiceModels() {
37452
37635
  }));
37453
37636
  }
37454
37637
  function voiceDir() {
37455
- return join49(homedir11(), ".open-agents", "voice");
37638
+ return join50(homedir11(), ".open-agents", "voice");
37456
37639
  }
37457
37640
  function modelsDir() {
37458
- return join49(voiceDir(), "models");
37641
+ return join50(voiceDir(), "models");
37459
37642
  }
37460
37643
  function modelDir(id) {
37461
- return join49(modelsDir(), id);
37644
+ return join50(modelsDir(), id);
37462
37645
  }
37463
37646
  function modelOnnxPath(id) {
37464
- return join49(modelDir(id), "model.onnx");
37647
+ return join50(modelDir(id), "model.onnx");
37465
37648
  }
37466
37649
  function modelConfigPath(id) {
37467
- return join49(modelDir(id), "config.json");
37650
+ return join50(modelDir(id), "config.json");
37468
37651
  }
37469
37652
  function luxttsVenvDir() {
37470
- return join49(voiceDir(), "luxtts-venv");
37653
+ return join50(voiceDir(), "luxtts-venv");
37471
37654
  }
37472
37655
  function luxttsVenvPy() {
37473
- return platform2() === "win32" ? join49(luxttsVenvDir(), "Scripts", "python.exe") : join49(luxttsVenvDir(), "bin", "python3");
37656
+ return platform2() === "win32" ? join50(luxttsVenvDir(), "Scripts", "python.exe") : join50(luxttsVenvDir(), "bin", "python3");
37474
37657
  }
37475
37658
  function luxttsRepoDir() {
37476
- return join49(voiceDir(), "LuxTTS");
37659
+ return join50(voiceDir(), "LuxTTS");
37477
37660
  }
37478
37661
  function luxttsCloneRefsDir() {
37479
- return join49(voiceDir(), "clone-refs");
37662
+ return join50(voiceDir(), "clone-refs");
37480
37663
  }
37481
37664
  function luxttsInferScript() {
37482
- return join49(voiceDir(), "luxtts-infer.py");
37665
+ return join50(voiceDir(), "luxtts-infer.py");
37483
37666
  }
37484
37667
  function emotionToPitchBias(emotion, stark = false, autist = false) {
37485
37668
  if (autist)
@@ -38287,7 +38470,7 @@ var init_voice = __esm({
38287
38470
  const refsDir = luxttsCloneRefsDir();
38288
38471
  const targets = ["glados", "overwatch"];
38289
38472
  for (const modelId of targets) {
38290
- const refFile = join49(refsDir, `${modelId}-ref.wav`);
38473
+ const refFile = join50(refsDir, `${modelId}-ref.wav`);
38291
38474
  if (existsSync35(refFile))
38292
38475
  continue;
38293
38476
  try {
@@ -38367,7 +38550,7 @@ var init_voice = __esm({
38367
38550
  }
38368
38551
  p = p.replace(/\\ /g, " ");
38369
38552
  if (p.startsWith("~/") || p === "~") {
38370
- p = join49(homedir11(), p.slice(1));
38553
+ p = join50(homedir11(), p.slice(1));
38371
38554
  }
38372
38555
  if (!existsSync35(p)) {
38373
38556
  return `File not found: ${p}
@@ -38381,7 +38564,7 @@ var init_voice = __esm({
38381
38564
  const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
38382
38565
  const ts = Date.now().toString(36);
38383
38566
  const destFilename = `clone-${srcName}-${ts}.${ext}`;
38384
- const destPath = join49(refsDir, destFilename);
38567
+ const destPath = join50(refsDir, destFilename);
38385
38568
  try {
38386
38569
  const data = readFileSync24(audioPath);
38387
38570
  writeFileSync14(destPath, data);
@@ -38426,7 +38609,7 @@ var init_voice = __esm({
38426
38609
  const refsDir = luxttsCloneRefsDir();
38427
38610
  if (!existsSync35(refsDir))
38428
38611
  mkdirSync13(refsDir, { recursive: true });
38429
- const destPath = join49(refsDir, `${sourceModelId}-ref.wav`);
38612
+ const destPath = join50(refsDir, `${sourceModelId}-ref.wav`);
38430
38613
  const sampleRate = this.config?.audio?.sample_rate ?? 22050;
38431
38614
  this.writeWav(audioData, sampleRate, destPath);
38432
38615
  this.luxttsCloneRef = destPath;
@@ -38442,7 +38625,7 @@ var init_voice = __esm({
38442
38625
  // -------------------------------------------------------------------------
38443
38626
  /** Metadata file for friendly names of clone refs */
38444
38627
  static cloneMetaFile() {
38445
- return join49(luxttsCloneRefsDir(), "meta.json");
38628
+ return join50(luxttsCloneRefsDir(), "meta.json");
38446
38629
  }
38447
38630
  loadCloneMeta() {
38448
38631
  const p = _VoiceEngine.cloneMetaFile();
@@ -38476,7 +38659,7 @@ var init_voice = __esm({
38476
38659
  return _VoiceEngine.AUDIO_EXTS.has(ext);
38477
38660
  });
38478
38661
  return files.map((f) => {
38479
- const p = join49(dir, f);
38662
+ const p = join50(dir, f);
38480
38663
  let size = 0;
38481
38664
  try {
38482
38665
  size = statSync12(p).size;
@@ -38493,7 +38676,7 @@ var init_voice = __esm({
38493
38676
  }
38494
38677
  /** Delete a clone reference file by filename. Returns true if deleted. */
38495
38678
  deleteCloneRef(filename) {
38496
- const p = join49(luxttsCloneRefsDir(), filename);
38679
+ const p = join50(luxttsCloneRefsDir(), filename);
38497
38680
  if (!existsSync35(p))
38498
38681
  return false;
38499
38682
  try {
@@ -38518,7 +38701,7 @@ var init_voice = __esm({
38518
38701
  }
38519
38702
  /** Set the active clone reference by filename. */
38520
38703
  setActiveCloneRef(filename) {
38521
- const p = join49(luxttsCloneRefsDir(), filename);
38704
+ const p = join50(luxttsCloneRefsDir(), filename);
38522
38705
  if (!existsSync35(p))
38523
38706
  return `File not found: ${filename}`;
38524
38707
  this.luxttsCloneRef = p;
@@ -38804,7 +38987,7 @@ var init_voice = __esm({
38804
38987
  }
38805
38988
  this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
38806
38989
  }
38807
- const wavPath = join49(tmpdir9(), `oa-voice-${Date.now()}.wav`);
38990
+ const wavPath = join50(tmpdir9(), `oa-voice-${Date.now()}.wav`);
38808
38991
  this.writeWav(audioData, sampleRate, wavPath);
38809
38992
  await this.playWav(wavPath);
38810
38993
  try {
@@ -39147,7 +39330,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
39147
39330
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
39148
39331
  const mlxVoice = model.mlxVoice ?? "af_heart";
39149
39332
  const mlxLangCode = model.mlxLangCode ?? "a";
39150
- const wavPath = join49(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
39333
+ const wavPath = join50(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
39151
39334
  const pyScript = [
39152
39335
  "import sys, json",
39153
39336
  "from mlx_audio.tts import generate as tts_gen",
@@ -39215,7 +39398,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
39215
39398
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
39216
39399
  const mlxVoice = model.mlxVoice ?? "af_heart";
39217
39400
  const mlxLangCode = model.mlxLangCode ?? "a";
39218
- const wavPath = join49(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
39401
+ const wavPath = join50(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
39219
39402
  const pyScript = [
39220
39403
  "import sys, json",
39221
39404
  "from mlx_audio.tts import generate as tts_gen",
@@ -39326,7 +39509,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
39326
39509
  }
39327
39510
  }
39328
39511
  const repoDir = luxttsRepoDir();
39329
- if (!existsSync35(join49(repoDir, "zipvoice", "luxvoice.py"))) {
39512
+ if (!existsSync35(join50(repoDir, "zipvoice", "luxvoice.py"))) {
39330
39513
  renderInfo(" Cloning LuxTTS repository...");
39331
39514
  try {
39332
39515
  if (existsSync35(repoDir)) {
@@ -39375,7 +39558,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
39375
39558
  if (!existsSync35(refsDir))
39376
39559
  return;
39377
39560
  for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
39378
- const p = join49(refsDir, name);
39561
+ const p = join50(refsDir, name);
39379
39562
  if (existsSync35(p)) {
39380
39563
  this.luxttsCloneRef = p;
39381
39564
  return;
@@ -39572,7 +39755,7 @@ if __name__ == '__main__':
39572
39755
  const ready = await this.ensureLuxttsDaemon();
39573
39756
  if (!ready)
39574
39757
  return;
39575
- const wavPath = join49(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
39758
+ const wavPath = join50(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
39576
39759
  try {
39577
39760
  await this.luxttsRequest({
39578
39761
  action: "synthesize",
@@ -39646,7 +39829,7 @@ if __name__ == '__main__':
39646
39829
  const ready = await this.ensureLuxttsDaemon();
39647
39830
  if (!ready)
39648
39831
  return null;
39649
- const wavPath = join49(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
39832
+ const wavPath = join50(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
39650
39833
  try {
39651
39834
  await this.luxttsRequest({
39652
39835
  action: "synthesize",
@@ -39676,7 +39859,7 @@ if __name__ == '__main__':
39676
39859
  return;
39677
39860
  const arch = process.arch;
39678
39861
  mkdirSync13(voiceDir(), { recursive: true });
39679
- const pkgPath = join49(voiceDir(), "package.json");
39862
+ const pkgPath = join50(voiceDir(), "package.json");
39680
39863
  const expectedDeps = {
39681
39864
  "onnxruntime-node": "^1.21.0",
39682
39865
  "phonemizer": "^1.2.1"
@@ -39698,17 +39881,17 @@ if __name__ == '__main__':
39698
39881
  dependencies: expectedDeps
39699
39882
  }, null, 2));
39700
39883
  }
39701
- const voiceRequire = createRequire(join49(voiceDir(), "index.js"));
39884
+ const voiceRequire = createRequire(join50(voiceDir(), "index.js"));
39702
39885
  const probeOnnx = () => {
39703
39886
  try {
39704
- 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") } });
39887
+ 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") } });
39705
39888
  const output = result.toString().trim();
39706
39889
  return output === "OK";
39707
39890
  } catch {
39708
39891
  return false;
39709
39892
  }
39710
39893
  };
39711
- const onnxNodeModules = join49(voiceDir(), "node_modules", "onnxruntime-node");
39894
+ const onnxNodeModules = join50(voiceDir(), "node_modules", "onnxruntime-node");
39712
39895
  const onnxInstalled = existsSync35(onnxNodeModules);
39713
39896
  if (onnxInstalled && !probeOnnx()) {
39714
39897
  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.`);
@@ -42112,8 +42295,8 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
42112
42295
  if (models.length > 0) {
42113
42296
  try {
42114
42297
  const { writeFileSync: writeFileSync20, mkdirSync: mkdirSync21 } = await import("node:fs");
42115
- const { join: join63, dirname: dirname20 } = await import("node:path");
42116
- const cachePath = join63(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
42298
+ const { join: join64, dirname: dirname20 } = await import("node:path");
42299
+ const cachePath = join64(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
42117
42300
  mkdirSync21(dirname20(cachePath), { recursive: true });
42118
42301
  writeFileSync20(cachePath, JSON.stringify({
42119
42302
  peerId,
@@ -42314,14 +42497,14 @@ async function handleUpdate(subcommand, ctx) {
42314
42497
  try {
42315
42498
  const { createRequire: createRequire4 } = await import("node:module");
42316
42499
  const { fileURLToPath: fileURLToPath14 } = await import("node:url");
42317
- const { dirname: dirname20, join: join63 } = await import("node:path");
42500
+ const { dirname: dirname20, join: join64 } = await import("node:path");
42318
42501
  const { existsSync: existsSync45 } = await import("node:fs");
42319
42502
  const req = createRequire4(import.meta.url);
42320
42503
  const thisDir = dirname20(fileURLToPath14(import.meta.url));
42321
42504
  const candidates = [
42322
- join63(thisDir, "..", "package.json"),
42323
- join63(thisDir, "..", "..", "package.json"),
42324
- join63(thisDir, "..", "..", "..", "package.json")
42505
+ join64(thisDir, "..", "package.json"),
42506
+ join64(thisDir, "..", "..", "package.json"),
42507
+ join64(thisDir, "..", "..", "..", "package.json")
42325
42508
  ];
42326
42509
  for (const pkgPath of candidates) {
42327
42510
  if (existsSync45(pkgPath)) {
@@ -42692,6 +42875,13 @@ async function switchModel(query, ctx, local = false) {
42692
42875
  return;
42693
42876
  }
42694
42877
  }
42878
+ if (match.isImageGen || isImageGenModel(match.name, match.family)) {
42879
+ renderWarning(`"${match.name}" is an image generation model, not a chat/code model.`);
42880
+ renderInfo("Image gen models use /api/generate with width/height/steps parameters.");
42881
+ renderInfo("They cannot be used as the primary chat backend for tool-calling tasks.");
42882
+ renderInfo("Use a text model instead (e.g., qwen3.5, nemotron, devstral).");
42883
+ return;
42884
+ }
42695
42885
  let finalModel = match.name;
42696
42886
  if (ctx.config.backendType === "ollama") {
42697
42887
  const result = await ensureExpandedContext(match.name, ctx.config.backendUrl);
@@ -43073,7 +43263,7 @@ var init_commands = __esm({
43073
43263
 
43074
43264
  // packages/cli/dist/tui/project-context.js
43075
43265
  import { existsSync as existsSync36, readFileSync as readFileSync25, readdirSync as readdirSync10 } from "node:fs";
43076
- import { join as join50, basename as basename10 } from "node:path";
43266
+ import { join as join51, basename as basename10 } from "node:path";
43077
43267
  import { execSync as execSync27 } from "node:child_process";
43078
43268
  import { homedir as homedir12, platform as platform3, release } from "node:os";
43079
43269
  function getModelTier(modelName) {
@@ -43108,7 +43298,7 @@ function loadProjectMap(repoRoot) {
43108
43298
  if (!hasOaDirectory(repoRoot)) {
43109
43299
  initOaDirectory(repoRoot);
43110
43300
  }
43111
- const mapPath = join50(repoRoot, OA_DIR, "context", "project-map.md");
43301
+ const mapPath = join51(repoRoot, OA_DIR, "context", "project-map.md");
43112
43302
  if (existsSync36(mapPath)) {
43113
43303
  try {
43114
43304
  const content = readFileSync25(mapPath, "utf-8");
@@ -43152,17 +43342,17 @@ ${log}`);
43152
43342
  }
43153
43343
  function loadMemoryContext(repoRoot) {
43154
43344
  const sections = [];
43155
- const oaMemDir = join50(repoRoot, OA_DIR, "memory");
43345
+ const oaMemDir = join51(repoRoot, OA_DIR, "memory");
43156
43346
  const oaEntries = loadMemoryDir(oaMemDir, "project");
43157
43347
  if (oaEntries)
43158
43348
  sections.push(oaEntries);
43159
- const legacyMemDir = join50(repoRoot, ".open-agents", "memory");
43349
+ const legacyMemDir = join51(repoRoot, ".open-agents", "memory");
43160
43350
  if (legacyMemDir !== oaMemDir && existsSync36(legacyMemDir)) {
43161
43351
  const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
43162
43352
  if (legacyEntries)
43163
43353
  sections.push(legacyEntries);
43164
43354
  }
43165
- const globalMemDir = join50(homedir12(), ".open-agents", "memory");
43355
+ const globalMemDir = join51(homedir12(), ".open-agents", "memory");
43166
43356
  const globalEntries = loadMemoryDir(globalMemDir, "global");
43167
43357
  if (globalEntries)
43168
43358
  sections.push(globalEntries);
@@ -43176,7 +43366,7 @@ function loadMemoryDir(memDir, scope) {
43176
43366
  const files = readdirSync10(memDir).filter((f) => f.endsWith(".json"));
43177
43367
  for (const file of files.slice(0, 10)) {
43178
43368
  try {
43179
- const raw = readFileSync25(join50(memDir, file), "utf-8");
43369
+ const raw = readFileSync25(join51(memDir, file), "utf-8");
43180
43370
  const entries = JSON.parse(raw);
43181
43371
  const topic = basename10(file, ".json");
43182
43372
  const keys = Object.keys(entries);
@@ -44395,9 +44585,9 @@ var init_banner = __esm({
44395
44585
 
44396
44586
  // packages/cli/dist/tui/carousel-descriptors.js
44397
44587
  import { existsSync as existsSync37, readFileSync as readFileSync26, writeFileSync as writeFileSync15, mkdirSync as mkdirSync14, readdirSync as readdirSync11 } from "node:fs";
44398
- import { join as join51, basename as basename11 } from "node:path";
44588
+ import { join as join52, basename as basename11 } from "node:path";
44399
44589
  function loadToolProfile(repoRoot) {
44400
- const filePath = join51(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
44590
+ const filePath = join52(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
44401
44591
  try {
44402
44592
  if (!existsSync37(filePath))
44403
44593
  return null;
@@ -44407,9 +44597,9 @@ function loadToolProfile(repoRoot) {
44407
44597
  }
44408
44598
  }
44409
44599
  function saveToolProfile(repoRoot, profile) {
44410
- const contextDir = join51(repoRoot, OA_DIR, "context");
44600
+ const contextDir = join52(repoRoot, OA_DIR, "context");
44411
44601
  mkdirSync14(contextDir, { recursive: true });
44412
- writeFileSync15(join51(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
44602
+ writeFileSync15(join52(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
44413
44603
  }
44414
44604
  function categorizeToolCall(toolName) {
44415
44605
  for (const cat of TOOL_CATEGORIES) {
@@ -44467,7 +44657,7 @@ function weightedColor(profile) {
44467
44657
  return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
44468
44658
  }
44469
44659
  function loadCachedDescriptors(repoRoot) {
44470
- const filePath = join51(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
44660
+ const filePath = join52(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
44471
44661
  try {
44472
44662
  if (!existsSync37(filePath))
44473
44663
  return null;
@@ -44478,14 +44668,14 @@ function loadCachedDescriptors(repoRoot) {
44478
44668
  }
44479
44669
  }
44480
44670
  function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
44481
- const contextDir = join51(repoRoot, OA_DIR, "context");
44671
+ const contextDir = join52(repoRoot, OA_DIR, "context");
44482
44672
  mkdirSync14(contextDir, { recursive: true });
44483
44673
  const cached = {
44484
44674
  phrases,
44485
44675
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
44486
44676
  sourceHash
44487
44677
  };
44488
- writeFileSync15(join51(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
44678
+ writeFileSync15(join52(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
44489
44679
  }
44490
44680
  function generateDescriptors(repoRoot) {
44491
44681
  const profile = loadToolProfile(repoRoot);
@@ -44533,7 +44723,7 @@ function generateDescriptors(repoRoot) {
44533
44723
  return phrases;
44534
44724
  }
44535
44725
  function extractFromPackageJson(repoRoot, tags) {
44536
- const pkgPath = join51(repoRoot, "package.json");
44726
+ const pkgPath = join52(repoRoot, "package.json");
44537
44727
  try {
44538
44728
  if (!existsSync37(pkgPath))
44539
44729
  return;
@@ -44581,7 +44771,7 @@ function extractFromManifests(repoRoot, tags) {
44581
44771
  { file: ".github/workflows", tag: "ci/cd" }
44582
44772
  ];
44583
44773
  for (const check of manifestChecks) {
44584
- if (existsSync37(join51(repoRoot, check.file))) {
44774
+ if (existsSync37(join52(repoRoot, check.file))) {
44585
44775
  tags.push(check.tag);
44586
44776
  }
44587
44777
  }
@@ -44603,7 +44793,7 @@ function extractFromSessions(repoRoot, tags) {
44603
44793
  }
44604
44794
  }
44605
44795
  function extractFromMemory(repoRoot, tags) {
44606
- const memoryDir = join51(repoRoot, OA_DIR, "memory");
44796
+ const memoryDir = join52(repoRoot, OA_DIR, "memory");
44607
44797
  try {
44608
44798
  if (!existsSync37(memoryDir))
44609
44799
  return;
@@ -44612,7 +44802,7 @@ function extractFromMemory(repoRoot, tags) {
44612
44802
  const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
44613
44803
  tags.push(topic);
44614
44804
  try {
44615
- const data = JSON.parse(readFileSync26(join51(memoryDir, file), "utf-8"));
44805
+ const data = JSON.parse(readFileSync26(join52(memoryDir, file), "utf-8"));
44616
44806
  if (data && typeof data === "object") {
44617
44807
  const keys = Object.keys(data).slice(0, 3);
44618
44808
  for (const key of keys) {
@@ -45235,10 +45425,10 @@ var init_stream_renderer = __esm({
45235
45425
 
45236
45426
  // packages/cli/dist/tui/edit-history.js
45237
45427
  import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync15 } from "node:fs";
45238
- import { join as join52 } from "node:path";
45428
+ import { join as join53 } from "node:path";
45239
45429
  function createEditHistoryLogger(repoRoot, sessionId) {
45240
- const historyDir = join52(repoRoot, ".oa", "history");
45241
- const logPath = join52(historyDir, "edits.jsonl");
45430
+ const historyDir = join53(repoRoot, ".oa", "history");
45431
+ const logPath = join53(historyDir, "edits.jsonl");
45242
45432
  try {
45243
45433
  mkdirSync15(historyDir, { recursive: true });
45244
45434
  } catch {
@@ -45350,12 +45540,12 @@ var init_edit_history = __esm({
45350
45540
 
45351
45541
  // packages/cli/dist/tui/promptLoader.js
45352
45542
  import { readFileSync as readFileSync27, existsSync as existsSync38 } from "node:fs";
45353
- import { join as join53, dirname as dirname17 } from "node:path";
45543
+ import { join as join54, dirname as dirname17 } from "node:path";
45354
45544
  import { fileURLToPath as fileURLToPath11 } from "node:url";
45355
45545
  function loadPrompt3(promptPath, vars) {
45356
45546
  let content = cache3.get(promptPath);
45357
45547
  if (content === void 0) {
45358
- const fullPath = join53(PROMPTS_DIR3, promptPath);
45548
+ const fullPath = join54(PROMPTS_DIR3, promptPath);
45359
45549
  if (!existsSync38(fullPath)) {
45360
45550
  throw new Error(`Prompt file not found: ${fullPath}`);
45361
45551
  }
@@ -45372,8 +45562,8 @@ var init_promptLoader3 = __esm({
45372
45562
  "use strict";
45373
45563
  __filename3 = fileURLToPath11(import.meta.url);
45374
45564
  __dirname6 = dirname17(__filename3);
45375
- devPath2 = join53(__dirname6, "..", "..", "prompts");
45376
- publishedPath2 = join53(__dirname6, "..", "prompts");
45565
+ devPath2 = join54(__dirname6, "..", "..", "prompts");
45566
+ publishedPath2 = join54(__dirname6, "..", "prompts");
45377
45567
  PROMPTS_DIR3 = existsSync38(devPath2) ? devPath2 : publishedPath2;
45378
45568
  cache3 = /* @__PURE__ */ new Map();
45379
45569
  }
@@ -45381,10 +45571,10 @@ var init_promptLoader3 = __esm({
45381
45571
 
45382
45572
  // packages/cli/dist/tui/dream-engine.js
45383
45573
  import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync16, readFileSync as readFileSync28, existsSync as existsSync39, cpSync, rmSync, readdirSync as readdirSync12 } from "node:fs";
45384
- import { join as join54, basename as basename12 } from "node:path";
45574
+ import { join as join55, basename as basename12 } from "node:path";
45385
45575
  import { execSync as execSync28 } from "node:child_process";
45386
45576
  function loadAutoresearchMemory(repoRoot) {
45387
- const memoryPath = join54(repoRoot, ".oa", "memory", "autoresearch.json");
45577
+ const memoryPath = join55(repoRoot, ".oa", "memory", "autoresearch.json");
45388
45578
  if (!existsSync39(memoryPath))
45389
45579
  return "";
45390
45580
  try {
@@ -45578,12 +45768,12 @@ var init_dream_engine = __esm({
45578
45768
  const content = String(args["content"] ?? "");
45579
45769
  if (!rawPath)
45580
45770
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
45581
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join54(this.autoresearchDir, basename12(rawPath)) : join54(this.autoresearchDir, rawPath);
45771
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join55(this.autoresearchDir, basename12(rawPath)) : join55(this.autoresearchDir, rawPath);
45582
45772
  if (!targetPath.startsWith(this.autoresearchDir)) {
45583
45773
  return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
45584
45774
  }
45585
45775
  try {
45586
- const dir = join54(targetPath, "..");
45776
+ const dir = join55(targetPath, "..");
45587
45777
  mkdirSync16(dir, { recursive: true });
45588
45778
  writeFileSync16(targetPath, content, "utf-8");
45589
45779
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -45613,7 +45803,7 @@ var init_dream_engine = __esm({
45613
45803
  const rawPath = String(args["path"] ?? "");
45614
45804
  const oldStr = String(args["old_string"] ?? "");
45615
45805
  const newStr = String(args["new_string"] ?? "");
45616
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join54(this.autoresearchDir, basename12(rawPath)) : join54(this.autoresearchDir, rawPath);
45806
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join55(this.autoresearchDir, basename12(rawPath)) : join55(this.autoresearchDir, rawPath);
45617
45807
  if (!targetPath.startsWith(this.autoresearchDir)) {
45618
45808
  return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
45619
45809
  }
@@ -45667,12 +45857,12 @@ var init_dream_engine = __esm({
45667
45857
  const content = String(args["content"] ?? "");
45668
45858
  if (!rawPath)
45669
45859
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
45670
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join54(this.dreamsDir, basename12(rawPath)) : join54(this.dreamsDir, rawPath);
45860
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join55(this.dreamsDir, basename12(rawPath)) : join55(this.dreamsDir, rawPath);
45671
45861
  if (!targetPath.startsWith(this.dreamsDir)) {
45672
45862
  return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
45673
45863
  }
45674
45864
  try {
45675
- const dir = join54(targetPath, "..");
45865
+ const dir = join55(targetPath, "..");
45676
45866
  mkdirSync16(dir, { recursive: true });
45677
45867
  writeFileSync16(targetPath, content, "utf-8");
45678
45868
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -45702,7 +45892,7 @@ var init_dream_engine = __esm({
45702
45892
  const rawPath = String(args["path"] ?? "");
45703
45893
  const oldStr = String(args["old_string"] ?? "");
45704
45894
  const newStr = String(args["new_string"] ?? "");
45705
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join54(this.dreamsDir, basename12(rawPath)) : join54(this.dreamsDir, rawPath);
45895
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join55(this.dreamsDir, basename12(rawPath)) : join55(this.dreamsDir, rawPath);
45706
45896
  if (!targetPath.startsWith(this.dreamsDir)) {
45707
45897
  return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
45708
45898
  }
@@ -45769,7 +45959,7 @@ var init_dream_engine = __esm({
45769
45959
  constructor(config, repoRoot) {
45770
45960
  this.config = config;
45771
45961
  this.repoRoot = repoRoot;
45772
- this.dreamsDir = join54(repoRoot, ".oa", "dreams");
45962
+ this.dreamsDir = join55(repoRoot, ".oa", "dreams");
45773
45963
  this.state = {
45774
45964
  mode: "default",
45775
45965
  active: false,
@@ -45853,7 +46043,7 @@ ${result.summary}`;
45853
46043
  if (mode !== "default" || cycle === totalCycles) {
45854
46044
  renderDreamContraction(cycle);
45855
46045
  const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
45856
- const summaryPath = join54(this.dreamsDir, `cycle-${cycle}-summary.md`);
46046
+ const summaryPath = join55(this.dreamsDir, `cycle-${cycle}-summary.md`);
45857
46047
  writeFileSync16(summaryPath, cycleSummary, "utf-8");
45858
46048
  }
45859
46049
  if (mode === "lucid" && !this.abortController.signal.aborted) {
@@ -46066,7 +46256,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
46066
46256
  }
46067
46257
  /** Build role-specific tool sets for swarm agents */
46068
46258
  buildSwarmTools(role, _workspace) {
46069
- const autoresearchDir = join54(this.repoRoot, ".oa", "autoresearch");
46259
+ const autoresearchDir = join55(this.repoRoot, ".oa", "autoresearch");
46070
46260
  const taskComplete = this.createSwarmTaskCompleteTool(role);
46071
46261
  switch (role) {
46072
46262
  case "researcher": {
@@ -46430,7 +46620,7 @@ INSTRUCTIONS:
46430
46620
  2. Summarize the key learnings and next steps
46431
46621
 
46432
46622
  Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
46433
- const reportPath = join54(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
46623
+ const reportPath = join55(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
46434
46624
  const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
46435
46625
 
46436
46626
  **Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -46519,7 +46709,7 @@ ${summaryResult}
46519
46709
  }
46520
46710
  /** Save workspace backup for lucid mode */
46521
46711
  saveVersionCheckpoint(cycle) {
46522
- const checkpointDir = join54(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
46712
+ const checkpointDir = join55(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
46523
46713
  try {
46524
46714
  mkdirSync16(checkpointDir, { recursive: true });
46525
46715
  try {
@@ -46538,10 +46728,10 @@ ${summaryResult}
46538
46728
  encoding: "utf-8",
46539
46729
  timeout: 5e3
46540
46730
  }).trim();
46541
- writeFileSync16(join54(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
46542
- writeFileSync16(join54(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
46543
- writeFileSync16(join54(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
46544
- writeFileSync16(join54(checkpointDir, "checkpoint.json"), JSON.stringify({
46731
+ writeFileSync16(join55(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
46732
+ writeFileSync16(join55(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
46733
+ writeFileSync16(join55(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
46734
+ writeFileSync16(join55(checkpointDir, "checkpoint.json"), JSON.stringify({
46545
46735
  cycle,
46546
46736
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
46547
46737
  gitHash,
@@ -46549,7 +46739,7 @@ ${summaryResult}
46549
46739
  }, null, 2), "utf-8");
46550
46740
  renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
46551
46741
  } catch {
46552
- writeFileSync16(join54(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
46742
+ writeFileSync16(join55(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
46553
46743
  renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
46554
46744
  }
46555
46745
  } catch (err) {
@@ -46607,14 +46797,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
46607
46797
  ---
46608
46798
  *Auto-generated by open-agents dream engine*
46609
46799
  `;
46610
- writeFileSync16(join54(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
46800
+ writeFileSync16(join55(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
46611
46801
  } catch {
46612
46802
  }
46613
46803
  }
46614
46804
  /** Save dream state for resume/inspection */
46615
46805
  saveDreamState() {
46616
46806
  try {
46617
- writeFileSync16(join54(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
46807
+ writeFileSync16(join55(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
46618
46808
  } catch {
46619
46809
  }
46620
46810
  }
@@ -46989,7 +47179,7 @@ var init_bless_engine = __esm({
46989
47179
 
46990
47180
  // packages/cli/dist/tui/dmn-engine.js
46991
47181
  import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync17, readdirSync as readdirSync13, unlinkSync as unlinkSync9 } from "node:fs";
46992
- import { join as join55, basename as basename13 } from "node:path";
47182
+ import { join as join56, basename as basename13 } from "node:path";
46993
47183
  function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
46994
47184
  const competenceReport = competence.length > 0 ? competence.map((c3) => {
46995
47185
  const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
@@ -47102,8 +47292,8 @@ var init_dmn_engine = __esm({
47102
47292
  constructor(config, repoRoot) {
47103
47293
  this.config = config;
47104
47294
  this.repoRoot = repoRoot;
47105
- this.stateDir = join55(repoRoot, ".oa", "dmn");
47106
- this.historyDir = join55(repoRoot, ".oa", "dmn", "cycles");
47295
+ this.stateDir = join56(repoRoot, ".oa", "dmn");
47296
+ this.historyDir = join56(repoRoot, ".oa", "dmn", "cycles");
47107
47297
  mkdirSync17(this.historyDir, { recursive: true });
47108
47298
  this.loadState();
47109
47299
  }
@@ -47693,8 +47883,8 @@ OUTPUT: Call task_complete with JSON:
47693
47883
  async gatherMemoryTopics() {
47694
47884
  const topics = [];
47695
47885
  const dirs = [
47696
- join55(this.repoRoot, ".oa", "memory"),
47697
- join55(this.repoRoot, ".open-agents", "memory")
47886
+ join56(this.repoRoot, ".oa", "memory"),
47887
+ join56(this.repoRoot, ".open-agents", "memory")
47698
47888
  ];
47699
47889
  for (const dir of dirs) {
47700
47890
  if (!existsSync40(dir))
@@ -47713,7 +47903,7 @@ OUTPUT: Call task_complete with JSON:
47713
47903
  }
47714
47904
  // ── State persistence ─────────────────────────────────────────────────
47715
47905
  loadState() {
47716
- const path = join55(this.stateDir, "state.json");
47906
+ const path = join56(this.stateDir, "state.json");
47717
47907
  if (existsSync40(path)) {
47718
47908
  try {
47719
47909
  this.state = JSON.parse(readFileSync29(path, "utf-8"));
@@ -47723,19 +47913,19 @@ OUTPUT: Call task_complete with JSON:
47723
47913
  }
47724
47914
  saveState() {
47725
47915
  try {
47726
- writeFileSync17(join55(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
47916
+ writeFileSync17(join56(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
47727
47917
  } catch {
47728
47918
  }
47729
47919
  }
47730
47920
  saveCycleResult(result) {
47731
47921
  try {
47732
47922
  const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
47733
- writeFileSync17(join55(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
47923
+ writeFileSync17(join56(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
47734
47924
  const files = readdirSync13(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
47735
47925
  if (files.length > 50) {
47736
47926
  for (const old of files.slice(0, files.length - 50)) {
47737
47927
  try {
47738
- unlinkSync9(join55(this.historyDir, old));
47928
+ unlinkSync9(join56(this.historyDir, old));
47739
47929
  } catch {
47740
47930
  }
47741
47931
  }
@@ -47749,7 +47939,7 @@ OUTPUT: Call task_complete with JSON:
47749
47939
 
47750
47940
  // packages/cli/dist/tui/snr-engine.js
47751
47941
  import { existsSync as existsSync41, readdirSync as readdirSync14, readFileSync as readFileSync30 } from "node:fs";
47752
- import { join as join56, basename as basename14 } from "node:path";
47942
+ import { join as join57, basename as basename14 } from "node:path";
47753
47943
  function computeDPrime(signalScores, noiseScores) {
47754
47944
  if (signalScores.length === 0 || noiseScores.length === 0)
47755
47945
  return 0;
@@ -47989,8 +48179,8 @@ Call task_complete with the JSON array when done.`, onEvent)
47989
48179
  loadMemoryEntries(topics) {
47990
48180
  const entries = [];
47991
48181
  const dirs = [
47992
- join56(this.repoRoot, ".oa", "memory"),
47993
- join56(this.repoRoot, ".open-agents", "memory")
48182
+ join57(this.repoRoot, ".oa", "memory"),
48183
+ join57(this.repoRoot, ".open-agents", "memory")
47994
48184
  ];
47995
48185
  for (const dir of dirs) {
47996
48186
  if (!existsSync41(dir))
@@ -48002,7 +48192,7 @@ Call task_complete with the JSON array when done.`, onEvent)
48002
48192
  if (topics.length > 0 && !topics.includes(topic))
48003
48193
  continue;
48004
48194
  try {
48005
- const data = JSON.parse(readFileSync30(join56(dir, f), "utf-8"));
48195
+ const data = JSON.parse(readFileSync30(join57(dir, f), "utf-8"));
48006
48196
  for (const [key, val] of Object.entries(data)) {
48007
48197
  const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
48008
48198
  entries.push({ topic, key, value });
@@ -48570,7 +48760,7 @@ var init_tool_policy = __esm({
48570
48760
 
48571
48761
  // packages/cli/dist/tui/telegram-bridge.js
48572
48762
  import { mkdirSync as mkdirSync18, existsSync as existsSync42, unlinkSync as unlinkSync10, readdirSync as readdirSync15, statSync as statSync13 } from "node:fs";
48573
- import { join as join57, resolve as resolve28 } from "node:path";
48763
+ import { join as join58, resolve as resolve28 } from "node:path";
48574
48764
  import { writeFile as writeFileAsync } from "node:fs/promises";
48575
48765
  function convertMarkdownToTelegramHTML(md) {
48576
48766
  let html = md;
@@ -49335,7 +49525,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
49335
49525
  return null;
49336
49526
  const buffer = Buffer.from(await res.arrayBuffer());
49337
49527
  const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
49338
- const localPath = join57(this.mediaCacheDir, fileName);
49528
+ const localPath = join58(this.mediaCacheDir, fileName);
49339
49529
  await writeFileAsync(localPath, buffer);
49340
49530
  return localPath;
49341
49531
  } catch {
@@ -51796,7 +51986,7 @@ var init_status_bar = __esm({
51796
51986
  import * as readline2 from "node:readline";
51797
51987
  import { Writable } from "node:stream";
51798
51988
  import { cwd } from "node:process";
51799
- import { resolve as resolve29, join as join58, dirname as dirname18, extname as extname10 } from "node:path";
51989
+ import { resolve as resolve29, join as join59, dirname as dirname18, extname as extname10 } from "node:path";
51800
51990
  import { createRequire as createRequire2 } from "node:module";
51801
51991
  import { fileURLToPath as fileURLToPath12 } from "node:url";
51802
51992
  import { readFileSync as readFileSync32, writeFileSync as writeFileSync18, appendFileSync as appendFileSync4, rmSync as rmSync2, readdirSync as readdirSync16, mkdirSync as mkdirSync19 } from "node:fs";
@@ -51820,9 +52010,9 @@ function getVersion3() {
51820
52010
  const require2 = createRequire2(import.meta.url);
51821
52011
  const thisDir = dirname18(fileURLToPath12(import.meta.url));
51822
52012
  const candidates = [
51823
- join58(thisDir, "..", "package.json"),
51824
- join58(thisDir, "..", "..", "package.json"),
51825
- join58(thisDir, "..", "..", "..", "package.json")
52013
+ join59(thisDir, "..", "package.json"),
52014
+ join59(thisDir, "..", "..", "package.json"),
52015
+ join59(thisDir, "..", "..", "..", "package.json")
51826
52016
  ];
51827
52017
  for (const pkgPath of candidates) {
51828
52018
  if (existsSync43(pkgPath)) {
@@ -51925,6 +52115,8 @@ function buildTools(repoRoot, config, contextWindowSize) {
51925
52115
  new ExplorationCultureTool(repoRoot),
51926
52116
  // Embedding Store — COHERE Private Brain semantic retrieval
51927
52117
  new EmbeddingStoreTool(repoRoot),
52118
+ // Image Generation — Ollama diffusion models
52119
+ new ImageGenerateTool(repoRoot, config.backendUrl),
51928
52120
  // Structured file reading (CSV, JSON, Markdown, binary detection)
51929
52121
  new StructuredReadTool(repoRoot),
51930
52122
  // Vision tools (Moondream — desktop awareness + point-and-click)
@@ -52044,15 +52236,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
52044
52236
  function gatherMemorySnippets(root) {
52045
52237
  const snippets = [];
52046
52238
  const dirs = [
52047
- join58(root, ".oa", "memory"),
52048
- join58(root, ".open-agents", "memory")
52239
+ join59(root, ".oa", "memory"),
52240
+ join59(root, ".open-agents", "memory")
52049
52241
  ];
52050
52242
  for (const dir of dirs) {
52051
52243
  if (!existsSync43(dir))
52052
52244
  continue;
52053
52245
  try {
52054
52246
  for (const f of readdirSync16(dir).filter((f2) => f2.endsWith(".json"))) {
52055
- const data = JSON.parse(readFileSync32(join58(dir, f), "utf-8"));
52247
+ const data = JSON.parse(readFileSync32(join59(dir, f), "utf-8"));
52056
52248
  for (const val of Object.values(data)) {
52057
52249
  const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
52058
52250
  if (v.length > 10)
@@ -53160,7 +53352,7 @@ async function startInteractive(config, repoPath) {
53160
53352
  let p2pGateway = null;
53161
53353
  let peerMesh = null;
53162
53354
  let inferenceRouter = null;
53163
- const secretVault = new SecretVault(join58(repoRoot, ".oa", "vault.enc"));
53355
+ const secretVault = new SecretVault(join59(repoRoot, ".oa", "vault.enc"));
53164
53356
  let adminSessionKey = null;
53165
53357
  const callSubAgents = /* @__PURE__ */ new Map();
53166
53358
  const streamRenderer = new StreamRenderer();
@@ -53369,8 +53561,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
53369
53561
  const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
53370
53562
  return [hits, line];
53371
53563
  }
53372
- const HISTORY_DIR = join58(homedir13(), ".open-agents");
53373
- const HISTORY_FILE = join58(HISTORY_DIR, "repl-history");
53564
+ const HISTORY_DIR = join59(homedir13(), ".open-agents");
53565
+ const HISTORY_FILE = join59(HISTORY_DIR, "repl-history");
53374
53566
  const MAX_HISTORY_LINES = 500;
53375
53567
  let savedHistory = [];
53376
53568
  try {
@@ -53580,7 +53772,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
53580
53772
  } catch {
53581
53773
  }
53582
53774
  try {
53583
- const oaDir = join58(repoRoot, ".oa");
53775
+ const oaDir = join59(repoRoot, ".oa");
53584
53776
  const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
53585
53777
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
53586
53778
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -53603,7 +53795,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
53603
53795
  } catch {
53604
53796
  }
53605
53797
  try {
53606
- const oaDir = join58(repoRoot, ".oa");
53798
+ const oaDir = join59(repoRoot, ".oa");
53607
53799
  const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
53608
53800
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
53609
53801
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -54437,7 +54629,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
54437
54629
  kind,
54438
54630
  targetUrl,
54439
54631
  authKey,
54440
- stateDir: join58(repoRoot, ".oa"),
54632
+ stateDir: join59(repoRoot, ".oa"),
54441
54633
  passthrough: passthrough ?? false,
54442
54634
  loadbalance: loadbalance ?? false,
54443
54635
  endpointAuth: passthrough ? currentConfig.apiKey : void 0,
@@ -54485,7 +54677,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
54485
54677
  await tunnelGateway.stop();
54486
54678
  tunnelGateway = null;
54487
54679
  }
54488
- const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join58(repoRoot, ".oa") });
54680
+ const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join59(repoRoot, ".oa") });
54489
54681
  newTunnel.on("stats", (stats) => {
54490
54682
  statusBar.setExposeStatus({
54491
54683
  status: stats.status,
@@ -54747,7 +54939,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
54747
54939
  }
54748
54940
  },
54749
54941
  destroyProject() {
54750
- const oaPath = join58(repoRoot, OA_DIR);
54942
+ const oaPath = join59(repoRoot, OA_DIR);
54751
54943
  if (existsSync43(oaPath)) {
54752
54944
  try {
54753
54945
  rmSync2(oaPath, { recursive: true, force: true });
@@ -55683,7 +55875,7 @@ import { glob } from "glob";
55683
55875
  import ignore from "ignore";
55684
55876
  import { readFile as readFile22, stat as stat4 } from "node:fs/promises";
55685
55877
  import { createHash as createHash4 } from "node:crypto";
55686
- import { join as join59, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
55878
+ import { join as join60, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
55687
55879
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
55688
55880
  var init_codebase_indexer = __esm({
55689
55881
  "packages/indexer/dist/codebase-indexer.js"() {
@@ -55727,7 +55919,7 @@ var init_codebase_indexer = __esm({
55727
55919
  const ig = ignore.default();
55728
55920
  if (this.config.respectGitignore) {
55729
55921
  try {
55730
- const gitignoreContent = await readFile22(join59(this.config.rootDir, ".gitignore"), "utf-8");
55922
+ const gitignoreContent = await readFile22(join60(this.config.rootDir, ".gitignore"), "utf-8");
55731
55923
  ig.add(gitignoreContent);
55732
55924
  } catch {
55733
55925
  }
@@ -55742,7 +55934,7 @@ var init_codebase_indexer = __esm({
55742
55934
  for (const relativePath of files) {
55743
55935
  if (ig.ignores(relativePath))
55744
55936
  continue;
55745
- const fullPath = join59(this.config.rootDir, relativePath);
55937
+ const fullPath = join60(this.config.rootDir, relativePath);
55746
55938
  try {
55747
55939
  const fileStat = await stat4(fullPath);
55748
55940
  if (fileStat.size > this.config.maxFileSize)
@@ -55788,7 +55980,7 @@ var init_codebase_indexer = __esm({
55788
55980
  if (!child) {
55789
55981
  child = {
55790
55982
  name: part,
55791
- path: join59(current.path, part),
55983
+ path: join60(current.path, part),
55792
55984
  type: "directory",
55793
55985
  children: []
55794
55986
  };
@@ -56129,7 +56321,7 @@ var config_exports = {};
56129
56321
  __export(config_exports, {
56130
56322
  configCommand: () => configCommand
56131
56323
  });
56132
- import { join as join60, resolve as resolve31 } from "node:path";
56324
+ import { join as join61, resolve as resolve31 } from "node:path";
56133
56325
  import { homedir as homedir14 } from "node:os";
56134
56326
  import { cwd as cwd3 } from "node:process";
56135
56327
  function redactIfSensitive(key, value) {
@@ -56212,7 +56404,7 @@ function handleShow(opts, config) {
56212
56404
  }
56213
56405
  }
56214
56406
  printSection("Config File");
56215
- printInfo(`~/.open-agents/config.json (${join60(homedir14(), ".open-agents", "config.json")})`);
56407
+ printInfo(`~/.open-agents/config.json (${join61(homedir14(), ".open-agents", "config.json")})`);
56216
56408
  printSection("Priority Chain");
56217
56409
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
56218
56410
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -56251,7 +56443,7 @@ function handleSet(opts, _config) {
56251
56443
  const coerced = coerceForSettings(key, value);
56252
56444
  saveProjectSettings(repoRoot, { [key]: coerced });
56253
56445
  printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
56254
- printInfo(`Saved to ${join60(repoRoot, ".oa", "settings.json")}`);
56446
+ printInfo(`Saved to ${join61(repoRoot, ".oa", "settings.json")}`);
56255
56447
  printInfo("This override applies only when running in this workspace.");
56256
56448
  } catch (err) {
56257
56449
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -56510,7 +56702,7 @@ __export(eval_exports, {
56510
56702
  });
56511
56703
  import { tmpdir as tmpdir10 } from "node:os";
56512
56704
  import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync19 } from "node:fs";
56513
- import { join as join61 } from "node:path";
56705
+ import { join as join62 } from "node:path";
56514
56706
  async function evalCommand(opts, config) {
56515
56707
  const suiteName = opts.suite ?? "basic";
56516
56708
  const suite = SUITES[suiteName];
@@ -56635,9 +56827,9 @@ async function evalCommand(opts, config) {
56635
56827
  process.exit(failed > 0 ? 1 : 0);
56636
56828
  }
56637
56829
  function createTempEvalRepo() {
56638
- const dir = join61(tmpdir10(), `open-agents-eval-${Date.now()}`);
56830
+ const dir = join62(tmpdir10(), `open-agents-eval-${Date.now()}`);
56639
56831
  mkdirSync20(dir, { recursive: true });
56640
- writeFileSync19(join61(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
56832
+ writeFileSync19(join62(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
56641
56833
  return dir;
56642
56834
  }
56643
56835
  var BASIC_SUITE, FULL_SUITE, SUITES;
@@ -56697,7 +56889,7 @@ init_updater();
56697
56889
  import { parseArgs as nodeParseArgs2 } from "node:util";
56698
56890
  import { createRequire as createRequire3 } from "node:module";
56699
56891
  import { fileURLToPath as fileURLToPath13 } from "node:url";
56700
- import { dirname as dirname19, join as join62 } from "node:path";
56892
+ import { dirname as dirname19, join as join63 } from "node:path";
56701
56893
 
56702
56894
  // packages/cli/dist/cli.js
56703
56895
  import { createInterface } from "node:readline";
@@ -56804,7 +56996,7 @@ init_output();
56804
56996
  function getVersion4() {
56805
56997
  try {
56806
56998
  const require2 = createRequire3(import.meta.url);
56807
- const pkgPath = join62(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
56999
+ const pkgPath = join63(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
56808
57000
  const pkg = require2(pkgPath);
56809
57001
  return pkg.version;
56810
57002
  } catch {