open-agents-ai 0.71.5 → 0.71.7

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 +228 -170
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -255,6 +255,7 @@ var init_output = __esm({
255
255
  });
256
256
 
257
257
  // packages/cli/dist/updater.js
258
+ import { execSync } from "node:child_process";
258
259
  import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
259
260
  import { join as join2 } from "node:path";
260
261
  import { homedir as homedir2 } from "node:os";
@@ -319,6 +320,17 @@ async function checkForUpdate(currentVersion, forceCheck = false) {
319
320
  latestVersion: latest
320
321
  };
321
322
  }
323
+ function performSilentUpdate() {
324
+ try {
325
+ execSync(`npm install -g ${PACKAGE_NAME}@latest --prefer-online`, {
326
+ stdio: "pipe",
327
+ timeout: 12e4
328
+ });
329
+ return true;
330
+ } catch {
331
+ return false;
332
+ }
333
+ }
322
334
  function formatUpdateBanner(info) {
323
335
  return `
324
336
  Update available: v${info.currentVersion} \u2192 v${info.latestVersion}
@@ -3124,7 +3136,7 @@ var init_list_directory = __esm({
3124
3136
  });
3125
3137
 
3126
3138
  // packages/execution/dist/tools/aiwg-setup.js
3127
- import { execSync } from "node:child_process";
3139
+ import { execSync as execSync2 } from "node:child_process";
3128
3140
  var AiwgSetupTool;
3129
3141
  var init_aiwg_setup = __esm({
3130
3142
  "packages/execution/dist/tools/aiwg-setup.js"() {
@@ -3163,7 +3175,7 @@ var init_aiwg_setup = __esm({
3163
3175
  };
3164
3176
  }
3165
3177
  try {
3166
- const output = execSync(`aiwg use ${framework}`, {
3178
+ const output = execSync2(`aiwg use ${framework}`, {
3167
3179
  cwd: projectDir,
3168
3180
  encoding: "utf8",
3169
3181
  timeout: 6e4,
@@ -3187,7 +3199,7 @@ ${output}`,
3187
3199
  }
3188
3200
  isAiwgInstalled() {
3189
3201
  try {
3190
- execSync("aiwg --version", {
3202
+ execSync2("aiwg --version", {
3191
3203
  encoding: "utf8",
3192
3204
  timeout: 5e3,
3193
3205
  stdio: ["pipe", "pipe", "pipe"]
@@ -3202,7 +3214,7 @@ ${output}`,
3202
3214
  });
3203
3215
 
3204
3216
  // packages/execution/dist/tools/aiwg-health.js
3205
- import { execSync as execSync2 } from "node:child_process";
3217
+ import { execSync as execSync3 } from "node:child_process";
3206
3218
  import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync3, statSync as statSync2 } from "node:fs";
3207
3219
  import { join as join8 } from "node:path";
3208
3220
  var AiwgHealthTool;
@@ -3282,7 +3294,7 @@ var init_aiwg_health = __esm({
3282
3294
  }
3283
3295
  if (this.isAiwgInstalled()) {
3284
3296
  try {
3285
- const runtimeInfo = execSync2("aiwg runtime-info 2>/dev/null", {
3297
+ const runtimeInfo = execSync3("aiwg runtime-info 2>/dev/null", {
3286
3298
  cwd: projectDir,
3287
3299
  encoding: "utf8",
3288
3300
  timeout: 15e3
@@ -3403,7 +3415,7 @@ var init_aiwg_health = __esm({
3403
3415
  }
3404
3416
  isAiwgInstalled() {
3405
3417
  try {
3406
- execSync2("aiwg --version", { encoding: "utf8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] });
3418
+ execSync3("aiwg --version", { encoding: "utf8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] });
3407
3419
  return true;
3408
3420
  } catch {
3409
3421
  return false;
@@ -3414,7 +3426,7 @@ var init_aiwg_health = __esm({
3414
3426
  });
3415
3427
 
3416
3428
  // packages/execution/dist/tools/aiwg-workflow.js
3417
- import { execSync as execSync3 } from "node:child_process";
3429
+ import { execSync as execSync4 } from "node:child_process";
3418
3430
  var AiwgWorkflowTool;
3419
3431
  var init_aiwg_workflow = __esm({
3420
3432
  "packages/execution/dist/tools/aiwg-workflow.js"() {
@@ -3462,7 +3474,7 @@ var init_aiwg_workflow = __esm({
3462
3474
  }
3463
3475
  const sanitized = command.replace(/[;&|`$()]/g, "");
3464
3476
  try {
3465
- const output = execSync3(`aiwg ${sanitized}`, {
3477
+ const output = execSync4(`aiwg ${sanitized}`, {
3466
3478
  cwd: projectDir,
3467
3479
  encoding: "utf8",
3468
3480
  timeout: 12e4,
@@ -3488,7 +3500,7 @@ var init_aiwg_workflow = __esm({
3488
3500
  }
3489
3501
  isAiwgInstalled() {
3490
3502
  try {
3491
- execSync3("aiwg --version", { encoding: "utf8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] });
3503
+ execSync4("aiwg --version", { encoding: "utf8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] });
3492
3504
  return true;
3493
3505
  } catch {
3494
3506
  return false;
@@ -4085,7 +4097,7 @@ var init_codebase_map = __esm({
4085
4097
  });
4086
4098
 
4087
4099
  // packages/execution/dist/tools/diagnostic.js
4088
- import { execSync as execSync4 } from "node:child_process";
4100
+ import { execSync as execSync5 } from "node:child_process";
4089
4101
  import { existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
4090
4102
  import { join as join10 } from "node:path";
4091
4103
  var DiagnosticTool;
@@ -4200,7 +4212,7 @@ var init_diagnostic = __esm({
4200
4212
  runStep(step, command, cwd4) {
4201
4213
  const start = performance.now();
4202
4214
  try {
4203
- const output = execSync4(command, {
4215
+ const output = execSync5(command, {
4204
4216
  cwd: cwd4,
4205
4217
  encoding: "utf8",
4206
4218
  timeout: 12e4,
@@ -4230,7 +4242,7 @@ ${err.stderr ?? ""}`.trim(),
4230
4242
  });
4231
4243
 
4232
4244
  // packages/execution/dist/tools/git-info.js
4233
- import { execSync as execSync5 } from "node:child_process";
4245
+ import { execSync as execSync6 } from "node:child_process";
4234
4246
  import { existsSync as existsSync8 } from "node:fs";
4235
4247
  import { join as join11 } from "node:path";
4236
4248
  var GitInfoTool;
@@ -4346,7 +4358,7 @@ var init_git_info = __esm({
4346
4358
  }
4347
4359
  git(cwd4, cmd) {
4348
4360
  try {
4349
- return execSync5(`git ${cmd}`, {
4361
+ return execSync6(`git ${cmd}`, {
4350
4362
  cwd: cwd4,
4351
4363
  encoding: "utf8",
4352
4364
  timeout: 1e4,
@@ -4649,7 +4661,7 @@ Exit code: ${task.exitCode ?? "N/A"}`,
4649
4661
  });
4650
4662
 
4651
4663
  // packages/execution/dist/system-deps.js
4652
- import { execSync as execSync6 } from "node:child_process";
4664
+ import { execSync as execSync7 } from "node:child_process";
4653
4665
  function detectPackageManager() {
4654
4666
  if (_detectedPkgManager !== void 0)
4655
4667
  return _detectedPkgManager;
@@ -4682,7 +4694,7 @@ function detectPackageManager() {
4682
4694
  function hasCommand(cmd) {
4683
4695
  try {
4684
4696
  const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
4685
- execSync6(whichCmd, { stdio: "pipe", timeout: 3e3 });
4697
+ execSync7(whichCmd, { stdio: "pipe", timeout: 3e3 });
4686
4698
  return true;
4687
4699
  } catch {
4688
4700
  return false;
@@ -4698,7 +4710,7 @@ function runInstall(installCmd) {
4698
4710
  cmd = `sudo -n ${installCmd}`;
4699
4711
  }
4700
4712
  }
4701
- execSync6(cmd, {
4713
+ execSync7(cmd, {
4702
4714
  stdio: "pipe",
4703
4715
  timeout: 12e4,
4704
4716
  // 2 min for package install
@@ -4843,7 +4855,7 @@ var init_system_deps = __esm({
4843
4855
  // packages/execution/dist/tools/image.js
4844
4856
  import { existsSync as existsSync9, readFileSync as readFileSync6, statSync as statSync4 } from "node:fs";
4845
4857
  import { resolve as resolve12, extname as extname2, basename as basename2 } from "node:path";
4846
- import { execSync as execSync7 } from "node:child_process";
4858
+ import { execSync as execSync8 } from "node:child_process";
4847
4859
  import { tmpdir } from "node:os";
4848
4860
  import { join as join12 } from "node:path";
4849
4861
  function isImagePath(path) {
@@ -4870,7 +4882,7 @@ function getMimeType(filePath) {
4870
4882
  }
4871
4883
  function getImageDimensions(filePath) {
4872
4884
  try {
4873
- const out = execSync7(`identify -format "%w %h" ${JSON.stringify(filePath)}`, {
4885
+ const out = execSync8(`identify -format "%w %h" ${JSON.stringify(filePath)}`, {
4874
4886
  encoding: "utf8",
4875
4887
  stdio: ["pipe", "pipe", "pipe"],
4876
4888
  timeout: 5e3
@@ -4882,7 +4894,7 @@ function getImageDimensions(filePath) {
4882
4894
  const dep = ensureCommand("identify");
4883
4895
  if (dep.installed) {
4884
4896
  try {
4885
- const out = execSync7(`identify -format "%w %h" ${JSON.stringify(filePath)}`, {
4897
+ const out = execSync8(`identify -format "%w %h" ${JSON.stringify(filePath)}`, {
4886
4898
  encoding: "utf8",
4887
4899
  stdio: ["pipe", "pipe", "pipe"],
4888
4900
  timeout: 5e3
@@ -4895,7 +4907,7 @@ function getImageDimensions(filePath) {
4895
4907
  }
4896
4908
  }
4897
4909
  try {
4898
- const out = execSync7(`file ${JSON.stringify(filePath)}`, {
4910
+ const out = execSync8(`file ${JSON.stringify(filePath)}`, {
4899
4911
  encoding: "utf8",
4900
4912
  stdio: ["pipe", "pipe", "pipe"],
4901
4913
  timeout: 5e3
@@ -4909,7 +4921,7 @@ function getImageDimensions(filePath) {
4909
4921
  }
4910
4922
  function hasTesseract() {
4911
4923
  try {
4912
- execSync7("tesseract --version", { stdio: "pipe", timeout: 5e3 });
4924
+ execSync8("tesseract --version", { stdio: "pipe", timeout: 5e3 });
4913
4925
  return true;
4914
4926
  } catch {
4915
4927
  const dep = ensureCommand("tesseract");
@@ -4918,7 +4930,7 @@ function hasTesseract() {
4918
4930
  }
4919
4931
  function runOCR(filePath) {
4920
4932
  try {
4921
- return execSync7(`tesseract ${JSON.stringify(filePath)} stdout 2>/dev/null`, {
4933
+ return execSync8(`tesseract ${JSON.stringify(filePath)} stdout 2>/dev/null`, {
4922
4934
  encoding: "utf8",
4923
4935
  stdio: ["pipe", "pipe", "pipe"],
4924
4936
  timeout: 3e4
@@ -5052,7 +5064,7 @@ ${ocrText}`);
5052
5064
  };
5053
5065
  }
5054
5066
  try {
5055
- execSync7(cmd, { stdio: "pipe", timeout: 1e4 });
5067
+ execSync8(cmd, { stdio: "pipe", timeout: 1e4 });
5056
5068
  } catch (err) {
5057
5069
  return {
5058
5070
  success: false,
@@ -5100,7 +5112,7 @@ ${ocrText}`);
5100
5112
  if (plat === "linux") {
5101
5113
  for (const tool of ["scrot", "gnome-screenshot", "import"]) {
5102
5114
  try {
5103
- execSync7(`which ${tool}`, { stdio: "pipe" });
5115
+ execSync8(`which ${tool}`, { stdio: "pipe" });
5104
5116
  if (tool === "scrot") {
5105
5117
  if (region === "active")
5106
5118
  return `scrot -u ${out}`;
@@ -5187,14 +5199,14 @@ ${ocrText}`);
5187
5199
  if (x != null && y != null && w != null && h != null) {
5188
5200
  const croppedPath = join12(tmpdir(), `oa-ocr-crop-${Date.now()}.png`);
5189
5201
  try {
5190
- execSync7(`convert ${JSON.stringify(fullPath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
5202
+ execSync8(`convert ${JSON.stringify(fullPath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
5191
5203
  inputPath = croppedPath;
5192
5204
  } catch {
5193
5205
  }
5194
5206
  }
5195
5207
  }
5196
5208
  try {
5197
- const text = execSync7(`tesseract ${JSON.stringify(inputPath)} stdout -l ${language} --psm ${psm} 2>/dev/null`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e4 }).trim();
5209
+ const text = execSync8(`tesseract ${JSON.stringify(inputPath)} stdout -l ${language} --psm ${psm} 2>/dev/null`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e4 }).trim();
5198
5210
  if (!text) {
5199
5211
  return { success: true, output: "(no text detected in image)", durationMs: Date.now() - start };
5200
5212
  }
@@ -5729,7 +5741,7 @@ var init_tool_creator = __esm({
5729
5741
  import { existsSync as existsSync11, readdirSync as readdirSync5, readFileSync as readFileSync8 } from "node:fs";
5730
5742
  import { join as join14, basename as basename3, dirname as dirname3 } from "node:path";
5731
5743
  import { homedir as homedir5 } from "node:os";
5732
- import { execSync as execSync8 } from "node:child_process";
5744
+ import { execSync as execSync9 } from "node:child_process";
5733
5745
  function getAiwgPaths() {
5734
5746
  const dataDir = join14(homedir5(), ".local", "share", "ai-writing-guide");
5735
5747
  return {
@@ -5742,7 +5754,7 @@ function findAiwgPackageRoot() {
5742
5754
  if (_cachedAiwgPkgRoot !== void 0)
5743
5755
  return _cachedAiwgPkgRoot;
5744
5756
  try {
5745
- const globalRoot = execSync8("npm root -g", {
5757
+ const globalRoot = execSync9("npm root -g", {
5746
5758
  encoding: "utf-8",
5747
5759
  timeout: 5e3,
5748
5760
  stdio: ["pipe", "pipe", "pipe"]
@@ -6129,7 +6141,7 @@ ${content}`,
6129
6141
  import { existsSync as existsSync12, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4, readFileSync as readFileSync9, unlinkSync } from "node:fs";
6130
6142
  import { join as join15, basename as basename4, extname as extname3, resolve as resolve13 } from "node:path";
6131
6143
  import { homedir as homedir6 } from "node:os";
6132
- import { execSync as execSync9, spawn as spawn4 } from "node:child_process";
6144
+ import { execSync as execSync10, spawn as spawn4 } from "node:child_process";
6133
6145
  function isTranscribable(path) {
6134
6146
  const ext = extname3(path).toLowerCase();
6135
6147
  return AUDIO_EXTS.has(ext) || VIDEO_EXTS.has(ext);
@@ -6139,7 +6151,7 @@ async function loadTranscribeCli() {
6139
6151
  return _tcModule;
6140
6152
  _tcChecked = true;
6141
6153
  try {
6142
- const globalRoot = execSync9("npm root -g", {
6154
+ const globalRoot = execSync10("npm root -g", {
6143
6155
  encoding: "utf-8",
6144
6156
  timeout: 5e3,
6145
6157
  stdio: ["pipe", "pipe", "pipe"]
@@ -6304,7 +6316,7 @@ var init_transcribe_tool = __esm({
6304
6316
  const args = [filePath, "-m", model, "-f", "txt"];
6305
6317
  if (diarize)
6306
6318
  args.push("--diarize");
6307
- const output = execSync9(`transcribe-cli ${args.join(" ")}`, {
6319
+ const output = execSync10(`transcribe-cli ${args.join(" ")}`, {
6308
6320
  encoding: "utf-8",
6309
6321
  timeout: 3e5,
6310
6322
  // 5 min max
@@ -6371,12 +6383,12 @@ var init_transcribe_tool = __esm({
6371
6383
  const tmpFile = join15(tmpDir, `download-${Date.now()}${ext}`);
6372
6384
  try {
6373
6385
  try {
6374
- execSync9(`curl -sL -o "${tmpFile}" "${url}"`, {
6386
+ execSync10(`curl -sL -o "${tmpFile}" "${url}"`, {
6375
6387
  timeout: 12e4,
6376
6388
  stdio: ["pipe", "pipe", "pipe"]
6377
6389
  });
6378
6390
  } catch {
6379
- execSync9(`wget -q -O "${tmpFile}" "${url}"`, {
6391
+ execSync10(`wget -q -O "${tmpFile}" "${url}"`, {
6380
6392
  timeout: 12e4,
6381
6393
  stdio: ["pipe", "pipe", "pipe"]
6382
6394
  });
@@ -7189,7 +7201,7 @@ ${parts.join("\n\n")}`,
7189
7201
 
7190
7202
  // packages/execution/dist/tools/vision.js
7191
7203
  import { readFileSync as readFileSync10, existsSync as existsSync13, statSync as statSync5 } from "node:fs";
7192
- import { execSync as execSync10, spawn as spawn6 } from "node:child_process";
7204
+ import { execSync as execSync11, spawn as spawn6 } from "node:child_process";
7193
7205
  import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname5, join as join17 } from "node:path";
7194
7206
  import { fileURLToPath as fileURLToPath2 } from "node:url";
7195
7207
  async function probeStation(endpoint) {
@@ -7208,7 +7220,7 @@ function findStationBinary() {
7208
7220
  const oaVenvPython = join17(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
7209
7221
  if (existsSync13(oaVenvPython)) {
7210
7222
  try {
7211
- execSync10(`${JSON.stringify(oaVenvPython)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
7223
+ execSync11(`${JSON.stringify(oaVenvPython)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
7212
7224
  return oaVenvPython;
7213
7225
  } catch {
7214
7226
  }
@@ -7224,14 +7236,14 @@ function findStationBinary() {
7224
7236
  for (const p of localVenvPaths) {
7225
7237
  if (existsSync13(p)) {
7226
7238
  try {
7227
- execSync10(`${JSON.stringify(p)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
7239
+ execSync11(`${JSON.stringify(p)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
7228
7240
  return p;
7229
7241
  } catch {
7230
7242
  }
7231
7243
  }
7232
7244
  }
7233
7245
  try {
7234
- const path = execSync10("which moondream-station", { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e3 }).trim();
7246
+ const path = execSync11("which moondream-station", { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e3 }).trim();
7235
7247
  if (path)
7236
7248
  return path;
7237
7249
  } catch {
@@ -7559,13 +7571,13 @@ ${response}`, durationMs: performance.now() - start };
7559
7571
 
7560
7572
  // packages/execution/dist/tools/desktop-click.js
7561
7573
  import { readFileSync as readFileSync11, existsSync as existsSync14 } from "node:fs";
7562
- import { execSync as execSync11 } from "node:child_process";
7574
+ import { execSync as execSync12 } from "node:child_process";
7563
7575
  import { tmpdir as tmpdir3 } from "node:os";
7564
7576
  import { join as join18, dirname as dirname6 } from "node:path";
7565
7577
  import { fileURLToPath as fileURLToPath3 } from "node:url";
7566
7578
  function hasCommand2(cmd) {
7567
7579
  try {
7568
- execSync11(`which ${cmd}`, { stdio: "pipe", timeout: 3e3 });
7580
+ execSync12(`which ${cmd}`, { stdio: "pipe", timeout: 3e3 });
7569
7581
  return true;
7570
7582
  } catch {
7571
7583
  return false;
@@ -7573,7 +7585,7 @@ function hasCommand2(cmd) {
7573
7585
  }
7574
7586
  function getImageDimensions2(filePath) {
7575
7587
  try {
7576
- const out = execSync11(`identify -format "%w %h" ${JSON.stringify(filePath)}`, {
7588
+ const out = execSync12(`identify -format "%w %h" ${JSON.stringify(filePath)}`, {
7577
7589
  encoding: "utf8",
7578
7590
  stdio: ["pipe", "pipe", "pipe"],
7579
7591
  timeout: 5e3
@@ -7584,14 +7596,14 @@ function getImageDimensions2(filePath) {
7584
7596
  } catch {
7585
7597
  }
7586
7598
  try {
7587
- const out = execSync11(`python3 -c "from PIL import Image; i=Image.open(${JSON.stringify(filePath)}); print(i.size[0], i.size[1])"`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 5e3 }).trim();
7599
+ const out = execSync12(`python3 -c "from PIL import Image; i=Image.open(${JSON.stringify(filePath)}); print(i.size[0], i.size[1])"`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 5e3 }).trim();
7588
7600
  const [w, h] = out.split(" ").map(Number);
7589
7601
  if (w && h)
7590
7602
  return { width: w, height: h };
7591
7603
  } catch {
7592
7604
  }
7593
7605
  try {
7594
- const out = execSync11(`file ${JSON.stringify(filePath)}`, {
7606
+ const out = execSync12(`file ${JSON.stringify(filePath)}`, {
7595
7607
  encoding: "utf8",
7596
7608
  stdio: ["pipe", "pipe", "pipe"],
7597
7609
  timeout: 5e3
@@ -7622,7 +7634,7 @@ function captureScreenshot(outputPath) {
7622
7634
  cmd = `scrot ${out}`;
7623
7635
  } else {
7624
7636
  try {
7625
- execSync11(`DISPLAY=:0 python3 -c "from PIL import ImageGrab; ImageGrab.grab().save(${JSON.stringify(outputPath)})"`, { stdio: "pipe", timeout: 1e4 });
7637
+ execSync12(`DISPLAY=:0 python3 -c "from PIL import ImageGrab; ImageGrab.grab().save(${JSON.stringify(outputPath)})"`, { stdio: "pipe", timeout: 1e4 });
7626
7638
  if (existsSync14(outputPath))
7627
7639
  return;
7628
7640
  } catch {
@@ -7633,7 +7645,7 @@ function captureScreenshot(outputPath) {
7633
7645
  if (!cmd) {
7634
7646
  throw new Error("No screenshot tool found. Auto-install failed. Try manually: sudo apt install scrot");
7635
7647
  }
7636
- execSync11(cmd, { stdio: "pipe", timeout: 1e4 });
7648
+ execSync12(cmd, { stdio: "pipe", timeout: 1e4 });
7637
7649
  if (!existsSync14(outputPath)) {
7638
7650
  throw new Error("Screenshot file was not created");
7639
7651
  }
@@ -7651,11 +7663,11 @@ function clickAt(x, y, button, clickType) {
7651
7663
  hasXdotool = dep.available;
7652
7664
  }
7653
7665
  if (hasXdotool) {
7654
- execSync11(`xdotool mousemove --sync ${rx} ${ry}`, { stdio: "pipe", timeout: 5e3 });
7666
+ execSync12(`xdotool mousemove --sync ${rx} ${ry}`, { stdio: "pipe", timeout: 5e3 });
7655
7667
  if (clickType === "double") {
7656
- execSync11(`xdotool click --repeat 2 --delay 50 ${buttonNum}`, { stdio: "pipe", timeout: 5e3 });
7668
+ execSync12(`xdotool click --repeat 2 --delay 50 ${buttonNum}`, { stdio: "pipe", timeout: 5e3 });
7657
7669
  } else {
7658
- execSync11(`xdotool click ${buttonNum}`, { stdio: "pipe", timeout: 5e3 });
7670
+ execSync12(`xdotool click ${buttonNum}`, { stdio: "pipe", timeout: 5e3 });
7659
7671
  }
7660
7672
  return;
7661
7673
  }
@@ -7680,13 +7692,13 @@ for i in range(${clicks}):
7680
7692
  time.sleep(0.05)
7681
7693
  `.trim().replace(/\n/g, "; ");
7682
7694
  try {
7683
- execSync11(`DISPLAY=:0 python3 -c "${pyScript}"`, { stdio: "pipe", timeout: 5e3 });
7695
+ execSync12(`DISPLAY=:0 python3 -c "${pyScript}"`, { stdio: "pipe", timeout: 5e3 });
7684
7696
  return;
7685
7697
  } catch {
7686
7698
  }
7687
7699
  try {
7688
7700
  const venvPy = join18(__dirname, "../../../../.moondream-venv/bin/python");
7689
- execSync11(`DISPLAY=:0 ${JSON.stringify(venvPy)} -c "${pyScript}"`, { stdio: "pipe", timeout: 5e3 });
7701
+ execSync12(`DISPLAY=:0 ${JSON.stringify(venvPy)} -c "${pyScript}"`, { stdio: "pipe", timeout: 5e3 });
7690
7702
  return;
7691
7703
  } catch {
7692
7704
  }
@@ -7698,11 +7710,11 @@ for i in range(${clicks}):
7698
7710
  const rx2 = Math.round(x);
7699
7711
  const ry2 = Math.round(y);
7700
7712
  if (clickType === "double") {
7701
- execSync11(`cliclick dc:${rx2},${ry2}`, { stdio: "pipe", timeout: 5e3 });
7713
+ execSync12(`cliclick dc:${rx2},${ry2}`, { stdio: "pipe", timeout: 5e3 });
7702
7714
  } else if (button === "right") {
7703
- execSync11(`cliclick rc:${rx2},${ry2}`, { stdio: "pipe", timeout: 5e3 });
7715
+ execSync12(`cliclick rc:${rx2},${ry2}`, { stdio: "pipe", timeout: 5e3 });
7704
7716
  } else {
7705
- execSync11(`cliclick c:${rx2},${ry2}`, { stdio: "pipe", timeout: 5e3 });
7717
+ execSync12(`cliclick c:${rx2},${ry2}`, { stdio: "pipe", timeout: 5e3 });
7706
7718
  }
7707
7719
  } else {
7708
7720
  throw new Error(`Desktop click not supported on platform: ${plat}`);
@@ -8018,7 +8030,7 @@ ${data.response}`);
8018
8030
  const tess = ensureCommand("tesseract");
8019
8031
  if (tess.available) {
8020
8032
  try {
8021
- ocrText = execSync11(`tesseract ${JSON.stringify(screenshotPath)} stdout 2>/dev/null`, {
8033
+ ocrText = execSync12(`tesseract ${JSON.stringify(screenshotPath)} stdout 2>/dev/null`, {
8022
8034
  encoding: "utf8",
8023
8035
  timeout: 15e3
8024
8036
  }).trim();
@@ -8069,7 +8081,7 @@ Screen: ${dims.width}x${dims.height}`);
8069
8081
  // packages/execution/dist/tools/ocr-pdf.js
8070
8082
  import { existsSync as existsSync15, statSync as statSync6 } from "node:fs";
8071
8083
  import { resolve as resolve17, basename as basename6 } from "node:path";
8072
- import { execSync as execSync12 } from "node:child_process";
8084
+ import { execSync as execSync13 } from "node:child_process";
8073
8085
  var OcrPdfTool;
8074
8086
  var init_ocr_pdf = __esm({
8075
8087
  "packages/execution/dist/tools/ocr-pdf.js"() {
@@ -8156,7 +8168,7 @@ var init_ocr_pdf = __esm({
8156
8168
  cmdParts.push(JSON.stringify(inputPath));
8157
8169
  cmdParts.push(JSON.stringify(outputPath));
8158
8170
  try {
8159
- const stdout = execSync12(cmdParts.join(" "), {
8171
+ const stdout = execSync13(cmdParts.join(" "), {
8160
8172
  encoding: "utf8",
8161
8173
  stdio: ["pipe", "pipe", "pipe"],
8162
8174
  timeout: 6e5,
@@ -8192,7 +8204,7 @@ Language: ${language}
8192
8204
  // packages/execution/dist/tools/pdf-to-text.js
8193
8205
  import { existsSync as existsSync16, statSync as statSync7, readFileSync as readFileSync12, unlinkSync as unlinkSync2 } from "node:fs";
8194
8206
  import { resolve as resolve18, basename as basename7, join as join19 } from "node:path";
8195
- import { execSync as execSync13 } from "node:child_process";
8207
+ import { execSync as execSync14 } from "node:child_process";
8196
8208
  import { tmpdir as tmpdir4 } from "node:os";
8197
8209
  var PdfToTextTool;
8198
8210
  var init_pdf_to_text = __esm({
@@ -8288,7 +8300,7 @@ var init_pdf_to_text = __esm({
8288
8300
  cmdParts.push("-l", String(lastPage));
8289
8301
  cmdParts.push(JSON.stringify(fullPath), "-");
8290
8302
  try {
8291
- let text = execSync13(cmdParts.join(" "), {
8303
+ let text = execSync14(cmdParts.join(" "), {
8292
8304
  encoding: "utf8",
8293
8305
  stdio: ["pipe", "pipe", "pipe"],
8294
8306
  timeout: 12e4
@@ -8348,14 +8360,14 @@ ${text}`,
8348
8360
  const tmpPdf = join19(tmpdir4(), `oa-ocr-${Date.now()}.pdf`);
8349
8361
  try {
8350
8362
  const ocrCmd = `ocrmypdf -l ${language} --skip-text ${JSON.stringify(inputPath)} ${JSON.stringify(tmpPdf)}`;
8351
- execSync13(ocrCmd, { stdio: "pipe", timeout: 6e5 });
8363
+ execSync14(ocrCmd, { stdio: "pipe", timeout: 6e5 });
8352
8364
  const textCmdParts = ["pdftotext"];
8353
8365
  if (firstPage)
8354
8366
  textCmdParts.push("-f", String(firstPage));
8355
8367
  if (lastPage)
8356
8368
  textCmdParts.push("-l", String(lastPage));
8357
8369
  textCmdParts.push(JSON.stringify(tmpPdf), "-");
8358
- const text = execSync13(textCmdParts.join(" "), {
8370
+ const text = execSync14(textCmdParts.join(" "), {
8359
8371
  encoding: "utf8",
8360
8372
  stdio: ["pipe", "pipe", "pipe"],
8361
8373
  timeout: 12e4
@@ -8377,7 +8389,7 @@ ${text}`,
8377
8389
  // packages/execution/dist/tools/ocr-image-advanced.js
8378
8390
  import { existsSync as existsSync17, statSync as statSync8 } from "node:fs";
8379
8391
  import { resolve as resolve19, basename as basename8, dirname as dirname7, join as join20 } from "node:path";
8380
- import { execSync as execSync14 } from "node:child_process";
8392
+ import { execSync as execSync15 } from "node:child_process";
8381
8393
  import { fileURLToPath as fileURLToPath4 } from "node:url";
8382
8394
  import { homedir as homedir7, tmpdir as tmpdir5 } from "node:os";
8383
8395
  function findOcrScript() {
@@ -8397,7 +8409,7 @@ function findPython() {
8397
8409
  const venvPython = join20(homedir7(), ".open-agents", "venv", "bin", "python");
8398
8410
  if (existsSync17(venvPython)) {
8399
8411
  try {
8400
- execSync14(`${JSON.stringify(venvPython)} -c "import cv2, pytesseract, numpy, PIL"`, {
8412
+ execSync15(`${JSON.stringify(venvPython)} -c "import cv2, pytesseract, numpy, PIL"`, {
8401
8413
  stdio: "pipe",
8402
8414
  timeout: 5e3
8403
8415
  });
@@ -8406,7 +8418,7 @@ function findPython() {
8406
8418
  }
8407
8419
  }
8408
8420
  try {
8409
- execSync14(`python3 -c "import cv2, pytesseract, numpy, PIL"`, {
8421
+ execSync15(`python3 -c "import cv2, pytesseract, numpy, PIL"`, {
8410
8422
  stdio: "pipe",
8411
8423
  timeout: 5e3
8412
8424
  });
@@ -8544,7 +8556,7 @@ var init_ocr_image_advanced = __esm({
8544
8556
  cmdParts.push("--debug-dir", debugDir);
8545
8557
  }
8546
8558
  try {
8547
- const stdout = execSync14(cmdParts.join(" "), {
8559
+ const stdout = execSync15(cmdParts.join(" "), {
8548
8560
  encoding: "utf8",
8549
8561
  stdio: ["pipe", "pipe", "pipe"],
8550
8562
  timeout: 3e5,
@@ -8640,14 +8652,14 @@ var init_ocr_image_advanced = __esm({
8640
8652
  try {
8641
8653
  const [x, y, w, h] = region.split(",").map(Number);
8642
8654
  const croppedPath = join20(tmpdir5(), `oa-ocr-crop-${Date.now()}.png`);
8643
- execSync14(`convert ${JSON.stringify(imagePath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
8655
+ execSync15(`convert ${JSON.stringify(imagePath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
8644
8656
  inputPath = croppedPath;
8645
8657
  } catch {
8646
8658
  }
8647
8659
  }
8648
8660
  const psmArg = psm ?? 6;
8649
8661
  try {
8650
- const text = execSync14(`tesseract ${JSON.stringify(inputPath)} stdout -l ${language} --psm ${psmArg} 2>/dev/null`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 6e4 }).trim();
8662
+ const text = execSync15(`tesseract ${JSON.stringify(inputPath)} stdout -l ${language} --psm ${psmArg} 2>/dev/null`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 6e4 }).trim();
8651
8663
  if (!text) {
8652
8664
  return {
8653
8665
  success: true,
@@ -8678,7 +8690,7 @@ Note: Advanced Python pipeline not available \u2014 install pytesseract, opencv-
8678
8690
  });
8679
8691
 
8680
8692
  // packages/execution/dist/tools/browser-action.js
8681
- import { execSync as execSync15, spawn as spawn7 } from "node:child_process";
8693
+ import { execSync as execSync16, spawn as spawn7 } from "node:child_process";
8682
8694
  import { existsSync as existsSync18, readFileSync as readFileSync13 } from "node:fs";
8683
8695
  import { join as join21, dirname as dirname8 } from "node:path";
8684
8696
  import { fileURLToPath as fileURLToPath5 } from "node:url";
@@ -8696,7 +8708,7 @@ async function probeService() {
8696
8708
  function findPython2() {
8697
8709
  for (const cmd of ["python3", "python"]) {
8698
8710
  try {
8699
- const ver = execSync15(`${cmd} --version 2>&1`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
8711
+ const ver = execSync16(`${cmd} --version 2>&1`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
8700
8712
  if (ver.includes("Python 3"))
8701
8713
  return cmd;
8702
8714
  } catch {
@@ -8931,7 +8943,7 @@ var init_browser_action = __esm({
8931
8943
  });
8932
8944
 
8933
8945
  // packages/execution/dist/tools/autoresearch.js
8934
- import { execSync as execSync16, spawn as spawn8 } from "node:child_process";
8946
+ import { execSync as execSync17, spawn as spawn8 } from "node:child_process";
8935
8947
  import { existsSync as existsSync19, readFileSync as readFileSync14, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, appendFileSync, copyFileSync } from "node:fs";
8936
8948
  import { join as join22, resolve as resolve20, dirname as dirname9 } from "node:path";
8937
8949
  import { fileURLToPath as fileURLToPath6 } from "node:url";
@@ -9061,13 +9073,13 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
9061
9073
  async setup(workspace, args, start) {
9062
9074
  const output = [];
9063
9075
  try {
9064
- execSync16("which uv", { encoding: "utf-8", timeout: 5e3 });
9076
+ execSync17("which uv", { encoding: "utf-8", timeout: 5e3 });
9065
9077
  output.push("uv: found");
9066
9078
  } catch {
9067
9079
  return { success: false, output: "", error: "uv not found. Install with: curl -LsSf https://astral.sh/uv/install.sh | sh", durationMs: Date.now() - start };
9068
9080
  }
9069
9081
  try {
9070
- const gpuInfo = execSync16("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader 2>/dev/null || echo 'no GPU'", { encoding: "utf-8", timeout: 1e4 }).trim();
9082
+ const gpuInfo = execSync17("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader 2>/dev/null || echo 'no GPU'", { encoding: "utf-8", timeout: 1e4 }).trim();
9071
9083
  output.push(`GPU: ${gpuInfo}`);
9072
9084
  } catch {
9073
9085
  output.push("GPU: detection failed (nvidia-smi not available)");
@@ -9117,10 +9129,10 @@ explicit = true
9117
9129
  writeFileSync5(join22(workspace, "pyproject.toml"), pyprojectContent, "utf-8");
9118
9130
  output.push("Created pyproject.toml");
9119
9131
  try {
9120
- execSync16("git rev-parse --git-dir", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
9132
+ execSync17("git rev-parse --git-dir", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
9121
9133
  output.push("Git: already initialized");
9122
9134
  } catch {
9123
- execSync16("git init && git add -A && git commit -m 'autoresearch: initial setup'", {
9135
+ execSync17("git init && git add -A && git commit -m 'autoresearch: initial setup'", {
9124
9136
  cwd: workspace,
9125
9137
  encoding: "utf-8",
9126
9138
  timeout: 1e4
@@ -9130,14 +9142,14 @@ explicit = true
9130
9142
  const tag = String(args["tag"] ?? (/* @__PURE__ */ new Date()).toISOString().slice(5, 10).replace("-", ""));
9131
9143
  const branchName = `autoresearch/${tag}`;
9132
9144
  try {
9133
- execSync16(`git checkout -b ${branchName}`, { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
9145
+ execSync17(`git checkout -b ${branchName}`, { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
9134
9146
  output.push(`Branch: created ${branchName}`);
9135
9147
  } catch {
9136
9148
  output.push(`Branch: ${branchName} may already exist, staying on current branch`);
9137
9149
  }
9138
9150
  output.push("Installing dependencies with uv sync (this may take a while)...");
9139
9151
  try {
9140
- const uvOut = execSync16("uv sync 2>&1", { cwd: workspace, encoding: "utf-8", timeout: 3e5 });
9152
+ const uvOut = execSync17("uv sync 2>&1", { cwd: workspace, encoding: "utf-8", timeout: 3e5 });
9141
9153
  output.push(`uv sync: ${uvOut.trim().split("\n").slice(-3).join(" | ")}`);
9142
9154
  } catch (err) {
9143
9155
  const e = err;
@@ -9146,7 +9158,7 @@ explicit = true
9146
9158
  const numShards = Number(args["num_shards"] ?? 10);
9147
9159
  output.push(`Preparing data (${numShards} shards)...`);
9148
9160
  try {
9149
- const prepOut = execSync16(`uv run prepare.py --num-shards ${numShards} 2>&1`, {
9161
+ const prepOut = execSync17(`uv run prepare.py --num-shards ${numShards} 2>&1`, {
9150
9162
  cwd: workspace,
9151
9163
  encoding: "utf-8",
9152
9164
  timeout: 6e5
@@ -9183,7 +9195,7 @@ Next steps:
9183
9195
  }
9184
9196
  if (!existsSync19(join22(workspace, ".venv")) && existsSync19(join22(workspace, "pyproject.toml"))) {
9185
9197
  try {
9186
- execSync16("uv sync 2>&1", { cwd: workspace, encoding: "utf-8", timeout: 3e5 });
9198
+ execSync17("uv sync 2>&1", { cwd: workspace, encoding: "utf-8", timeout: 3e5 });
9187
9199
  } catch {
9188
9200
  }
9189
9201
  }
@@ -9333,15 +9345,15 @@ Run autoresearch(action="setup") to begin.`,
9333
9345
  }
9334
9346
  output.push(`Workspace: ${workspace}`);
9335
9347
  try {
9336
- const branch = execSync16("git branch --show-current", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9348
+ const branch = execSync17("git branch --show-current", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9337
9349
  output.push(`Branch: ${branch}`);
9338
- const lastCommit = execSync16("git log --oneline -1", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9350
+ const lastCommit = execSync17("git log --oneline -1", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9339
9351
  output.push(`Last commit: ${lastCommit}`);
9340
9352
  } catch {
9341
9353
  output.push("Git: not initialized");
9342
9354
  }
9343
9355
  try {
9344
- const gpuInfo = execSync16("nvidia-smi --query-gpu=name,memory.total,memory.used --format=csv,noheader 2>/dev/null", { encoding: "utf-8", timeout: 1e4 }).trim();
9356
+ const gpuInfo = execSync17("nvidia-smi --query-gpu=name,memory.total,memory.used --format=csv,noheader 2>/dev/null", { encoding: "utf-8", timeout: 1e4 }).trim();
9345
9357
  output.push(`GPU: ${gpuInfo}`);
9346
9358
  } catch {
9347
9359
  output.push("GPU: not detected");
@@ -9384,12 +9396,12 @@ Run autoresearch(action="setup") to begin.`,
9384
9396
  memGb = memGb ?? 0;
9385
9397
  let commitHash = "0000000";
9386
9398
  try {
9387
- execSync16("git add train.py", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
9388
- execSync16(`git commit -m "autoresearch: ${desc}"`, { cwd: workspace, encoding: "utf-8", timeout: 1e4 });
9389
- commitHash = execSync16("git rev-parse --short HEAD", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9399
+ execSync17("git add train.py", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
9400
+ execSync17(`git commit -m "autoresearch: ${desc}"`, { cwd: workspace, encoding: "utf-8", timeout: 1e4 });
9401
+ commitHash = execSync17("git rev-parse --short HEAD", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9390
9402
  } catch {
9391
9403
  try {
9392
- commitHash = execSync16("git rev-parse --short HEAD", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9404
+ commitHash = execSync17("git rev-parse --short HEAD", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9393
9405
  } catch {
9394
9406
  }
9395
9407
  }
@@ -9423,14 +9435,14 @@ Branch advanced. Ready for next experiment.`,
9423
9435
  memGb = memGb ?? 0;
9424
9436
  let commitHash = "0000000";
9425
9437
  try {
9426
- commitHash = execSync16("git rev-parse --short HEAD", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9438
+ commitHash = execSync17("git rev-parse --short HEAD", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9427
9439
  } catch {
9428
9440
  }
9429
9441
  const row = `${commitHash} ${valBpb.toFixed(6)} ${memGb.toFixed(1)} discard ${desc}
9430
9442
  `;
9431
9443
  appendFileSync(tsvPath, row, "utf-8");
9432
9444
  try {
9433
- execSync16("git checkout -- train.py", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
9445
+ execSync17("git checkout -- train.py", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
9434
9446
  } catch {
9435
9447
  return {
9436
9448
  success: false,
@@ -9451,7 +9463,7 @@ train.py reverted to last kept state. Ready for next experiment.`,
9451
9463
  });
9452
9464
 
9453
9465
  // packages/execution/dist/tools/scheduler.js
9454
- import { execSync as execSync17, exec as execCb } from "node:child_process";
9466
+ import { execSync as execSync18, exec as execCb } from "node:child_process";
9455
9467
  import { readFile as readFile9, writeFile as writeFile8, mkdir as mkdir4 } from "node:fs/promises";
9456
9468
  import { resolve as resolve21, join as join23 } from "node:path";
9457
9469
  import { randomBytes as randomBytes2 } from "node:crypto";
@@ -9513,19 +9525,19 @@ function describeCron(expr) {
9513
9525
  }
9514
9526
  function getCurrentCrontab() {
9515
9527
  try {
9516
- return execSync17("crontab -l 2>/dev/null", { stdio: "pipe" }).toString().split("\n");
9528
+ return execSync18("crontab -l 2>/dev/null", { stdio: "pipe" }).toString().split("\n");
9517
9529
  } catch {
9518
9530
  return [];
9519
9531
  }
9520
9532
  }
9521
9533
  function writeCrontab(lines) {
9522
9534
  const content = lines.join("\n") + "\n";
9523
- execSync17(`echo ${JSON.stringify(content)} | crontab -`, { stdio: "pipe" });
9535
+ execSync18(`echo ${JSON.stringify(content)} | crontab -`, { stdio: "pipe" });
9524
9536
  }
9525
9537
  function findOaBinary() {
9526
9538
  for (const cmd of ["oa", "open-agents"]) {
9527
9539
  try {
9528
- const path = execSync17(`which ${cmd} 2>/dev/null`, { stdio: "pipe" }).toString().trim();
9540
+ const path = execSync18(`which ${cmd} 2>/dev/null`, { stdio: "pipe" }).toString().trim();
9529
9541
  if (path)
9530
9542
  return path;
9531
9543
  } catch {
@@ -10440,13 +10452,13 @@ ${sections.join("\n")}`,
10440
10452
  });
10441
10453
 
10442
10454
  // packages/execution/dist/tools/opencode.js
10443
- import { execSync as execSync18, spawn as spawn9 } from "node:child_process";
10455
+ import { execSync as execSync19, spawn as spawn9 } from "node:child_process";
10444
10456
  import { existsSync as existsSync20 } from "node:fs";
10445
10457
  import { join as join26, resolve as resolve24 } from "node:path";
10446
10458
  function findOpencode() {
10447
10459
  for (const cmd of ["opencode"]) {
10448
10460
  try {
10449
- const path = execSync18(`which ${cmd} 2>/dev/null`, { stdio: "pipe" }).toString().trim();
10461
+ const path = execSync19(`which ${cmd} 2>/dev/null`, { stdio: "pipe" }).toString().trim();
10450
10462
  if (path)
10451
10463
  return path;
10452
10464
  } catch {
@@ -10466,7 +10478,7 @@ function findOpencode() {
10466
10478
  }
10467
10479
  function getVersion(binary) {
10468
10480
  try {
10469
- return execSync18(`${binary} --version 2>/dev/null`, { stdio: "pipe", timeout: 1e4 }).toString().trim();
10481
+ return execSync19(`${binary} --version 2>/dev/null`, { stdio: "pipe", timeout: 1e4 }).toString().trim();
10470
10482
  } catch {
10471
10483
  return "unknown";
10472
10484
  }
@@ -10475,12 +10487,12 @@ function installOpencode() {
10475
10487
  const platform4 = process.platform;
10476
10488
  try {
10477
10489
  if (platform4 === "win32") {
10478
- execSync18('powershell -Command "irm https://opencode.ai/install | iex"', {
10490
+ execSync19('powershell -Command "irm https://opencode.ai/install | iex"', {
10479
10491
  stdio: "pipe",
10480
10492
  timeout: 12e4
10481
10493
  });
10482
10494
  } else {
10483
- execSync18("curl -fsSL https://opencode.ai/install | bash", {
10495
+ execSync19("curl -fsSL https://opencode.ai/install | bash", {
10484
10496
  stdio: "pipe",
10485
10497
  timeout: 12e4
10486
10498
  });
@@ -10714,7 +10726,7 @@ var init_opencode = __esm({
10714
10726
  });
10715
10727
 
10716
10728
  // packages/execution/dist/tools/cron-agent.js
10717
- import { execSync as execSync19 } from "node:child_process";
10729
+ import { execSync as execSync20 } from "node:child_process";
10718
10730
  import { readFile as readFile12, writeFile as writeFile11, mkdir as mkdir7 } from "node:fs/promises";
10719
10731
  import { resolve as resolve25, join as join27 } from "node:path";
10720
10732
  import { randomBytes as randomBytes5 } from "node:crypto";
@@ -10778,19 +10790,19 @@ function resolveSchedule2(schedule) {
10778
10790
  }
10779
10791
  function getCurrentCrontab2() {
10780
10792
  try {
10781
- return execSync19("crontab -l 2>/dev/null", { stdio: "pipe" }).toString().split("\n");
10793
+ return execSync20("crontab -l 2>/dev/null", { stdio: "pipe" }).toString().split("\n");
10782
10794
  } catch {
10783
10795
  return [];
10784
10796
  }
10785
10797
  }
10786
10798
  function writeCrontab2(lines) {
10787
10799
  const content = lines.join("\n") + "\n";
10788
- execSync19(`echo ${JSON.stringify(content)} | crontab -`, { stdio: "pipe" });
10800
+ execSync20(`echo ${JSON.stringify(content)} | crontab -`, { stdio: "pipe" });
10789
10801
  }
10790
10802
  function findOaBinary2() {
10791
10803
  for (const cmd of ["oa", "open-agents"]) {
10792
10804
  try {
10793
- const path = execSync19(`which ${cmd} 2>/dev/null`, { stdio: "pipe" }).toString().trim();
10805
+ const path = execSync20(`which ${cmd} 2>/dev/null`, { stdio: "pipe" }).toString().trim();
10794
10806
  if (path)
10795
10807
  return path;
10796
10808
  } catch {
@@ -11120,7 +11132,7 @@ ${truncated}`, durationMs: performance.now() - start };
11120
11132
  ];
11121
11133
  if (job.verifyCommand) {
11122
11134
  try {
11123
- const result = execSync19(job.verifyCommand, {
11135
+ const result = execSync20(job.verifyCommand, {
11124
11136
  cwd: this.workingDir,
11125
11137
  stdio: "pipe",
11126
11138
  timeout: 3e4
@@ -11170,7 +11182,7 @@ import { readFile as readFile13, writeFile as writeFile12, mkdir as mkdir8, chmo
11170
11182
  import { existsSync as existsSync21 } from "node:fs";
11171
11183
  import { resolve as resolve26, join as join28 } from "node:path";
11172
11184
  import { randomBytes as randomBytes6, createCipheriv, createDecipheriv, scryptSync, createHash } from "node:crypto";
11173
- import { execSync as execSync20, spawn as spawn10 } from "node:child_process";
11185
+ import { execSync as execSync21, spawn as spawn10 } from "node:child_process";
11174
11186
  function containsKeyMaterial(input) {
11175
11187
  for (const pattern of KEY_PATTERNS) {
11176
11188
  if (pattern.test(input))
@@ -11529,26 +11541,50 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
11529
11541
  }
11530
11542
  return `Daemon already running (pid: ${existingPid}).`;
11531
11543
  }
11544
+ const nodeModulesDir = resolve26(this.repoRoot, "node_modules");
11545
+ let nexusResolved = false;
11532
11546
  try {
11533
- execSync20(`node -e "require.resolve('open-agents-nexus')"`, { stdio: "pipe", timeout: 5e3 });
11547
+ const nexusPkg = join28(nodeModulesDir, "open-agents-nexus", "package.json");
11548
+ if (existsSync21(nexusPkg)) {
11549
+ nexusResolved = true;
11550
+ } else {
11551
+ const globalDir = execSync21("npm root -g", { encoding: "utf8", timeout: 5e3 }).trim();
11552
+ if (existsSync21(join28(globalDir, "open-agents-nexus", "package.json"))) {
11553
+ nexusResolved = true;
11554
+ }
11555
+ }
11534
11556
  } catch {
11557
+ }
11558
+ if (!nexusResolved) {
11535
11559
  try {
11536
- execSync20("npm install -g open-agents-nexus@latest 2>&1 || npm install open-agents-nexus@latest 2>&1", {
11560
+ execSync21("npm install open-agents-nexus@latest 2>&1", {
11561
+ cwd: this.repoRoot,
11537
11562
  stdio: "pipe",
11538
11563
  timeout: 12e4
11539
11564
  });
11540
11565
  } catch {
11541
- throw new Error("Failed to install open-agents-nexus. Run: npm install -g open-agents-nexus");
11566
+ try {
11567
+ execSync21("npm install -g open-agents-nexus@latest 2>&1", { stdio: "pipe", timeout: 12e4 });
11568
+ } catch {
11569
+ throw new Error("Failed to install open-agents-nexus. Run: npm install open-agents-nexus");
11570
+ }
11542
11571
  }
11543
11572
  }
11544
11573
  const daemonPath = join28(this.nexusDir, "nexus-daemon.mjs");
11545
11574
  await writeFile12(daemonPath, DAEMON_SCRIPT);
11546
11575
  const agentName = args.agent_name || "open-agents-node";
11547
11576
  const agentType = args.agent_type || "general";
11577
+ const nodePaths = [nodeModulesDir];
11578
+ try {
11579
+ const globalDir = execSync21("npm root -g", { encoding: "utf8", timeout: 5e3 }).trim();
11580
+ nodePaths.push(globalDir);
11581
+ } catch {
11582
+ }
11548
11583
  const child = spawn10("node", [daemonPath, this.nexusDir, agentName, agentType], {
11549
11584
  detached: true,
11550
11585
  stdio: ["ignore", "pipe", "pipe"],
11551
- cwd: this.repoRoot
11586
+ cwd: this.repoRoot,
11587
+ env: { ...process.env, NODE_PATH: nodePaths.join(":") }
11552
11588
  });
11553
11589
  child.unref();
11554
11590
  let earlyOutput = "";
@@ -11781,7 +11817,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
11781
11817
  }
11782
11818
  async doInferenceProof() {
11783
11819
  try {
11784
- const psRaw = execSync20("ollama ps 2>/dev/null", { timeout: 1e4, encoding: "utf8" });
11820
+ const psRaw = execSync21("ollama ps 2>/dev/null", { timeout: 1e4, encoding: "utf8" });
11785
11821
  const lines = psRaw.trim().split("\n").filter((l) => l.trim());
11786
11822
  if (lines.length < 2)
11787
11823
  return "No model loaded. Run 'ollama ps' to check.";
@@ -11789,7 +11825,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
11789
11825
  const modelName = parts[0] || "unknown";
11790
11826
  let gpuName = "none", vramMb = 0;
11791
11827
  try {
11792
- const smi = execSync20("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader 2>/dev/null", {
11828
+ const smi = execSync21("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader 2>/dev/null", {
11793
11829
  timeout: 5e3,
11794
11830
  encoding: "utf8"
11795
11831
  });
@@ -11798,7 +11834,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
11798
11834
  vramMb = parseInt(gp[1]?.trim() || "0", 10);
11799
11835
  } catch {
11800
11836
  try {
11801
- execSync20("rocm-smi 2>/dev/null", { timeout: 5e3 });
11837
+ execSync21("rocm-smi 2>/dev/null", { timeout: 5e3 });
11802
11838
  gpuName = "AMD GPU";
11803
11839
  } catch {
11804
11840
  }
@@ -17639,7 +17675,7 @@ __export(listen_exports, {
17639
17675
  isVideoPath: () => isVideoPath,
17640
17676
  waitForTranscribeCli: () => waitForTranscribeCli
17641
17677
  });
17642
- import { spawn as spawn11, execSync as execSync21 } from "node:child_process";
17678
+ import { spawn as spawn11, execSync as execSync22 } from "node:child_process";
17643
17679
  import { existsSync as existsSync22, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6, readdirSync as readdirSync6 } from "node:fs";
17644
17680
  import { join as join31, dirname as dirname10 } from "node:path";
17645
17681
  import { homedir as homedir8 } from "node:os";
@@ -17661,7 +17697,7 @@ function findMicCaptureCommand() {
17661
17697
  const platform4 = process.platform;
17662
17698
  if (platform4 === "linux") {
17663
17699
  try {
17664
- execSync21("which arecord", { stdio: "pipe" });
17700
+ execSync22("which arecord", { stdio: "pipe" });
17665
17701
  return {
17666
17702
  cmd: "arecord",
17667
17703
  args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
@@ -17671,7 +17707,7 @@ function findMicCaptureCommand() {
17671
17707
  }
17672
17708
  if (platform4 === "darwin") {
17673
17709
  try {
17674
- execSync21("which sox", { stdio: "pipe" });
17710
+ execSync22("which sox", { stdio: "pipe" });
17675
17711
  return {
17676
17712
  cmd: "sox",
17677
17713
  args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
@@ -17680,7 +17716,7 @@ function findMicCaptureCommand() {
17680
17716
  }
17681
17717
  }
17682
17718
  try {
17683
- execSync21("which ffmpeg", { stdio: "pipe" });
17719
+ execSync22("which ffmpeg", { stdio: "pipe" });
17684
17720
  if (platform4 === "linux") {
17685
17721
  return {
17686
17722
  cmd: "ffmpeg",
@@ -17739,7 +17775,7 @@ function findLiveWhisperScript() {
17739
17775
  return p;
17740
17776
  }
17741
17777
  try {
17742
- const globalRoot = execSync21("npm root -g", {
17778
+ const globalRoot = execSync22("npm root -g", {
17743
17779
  encoding: "utf-8",
17744
17780
  timeout: 5e3,
17745
17781
  stdio: ["pipe", "pipe", "pipe"]
@@ -17772,7 +17808,7 @@ function ensureTranscribeCliBackground() {
17772
17808
  return;
17773
17809
  _bgInstallPromise = (async () => {
17774
17810
  try {
17775
- const globalRoot = execSync21("npm root -g", {
17811
+ const globalRoot = execSync22("npm root -g", {
17776
17812
  encoding: "utf-8",
17777
17813
  timeout: 5e3,
17778
17814
  stdio: ["pipe", "pipe", "pipe"]
@@ -17978,7 +18014,7 @@ var init_listen = __esm({
17978
18014
  }
17979
18015
  if (!this.transcribeCliAvailable) {
17980
18016
  try {
17981
- execSync21("which transcribe-cli", { stdio: "pipe" });
18017
+ execSync22("which transcribe-cli", { stdio: "pipe" });
17982
18018
  this.transcribeCliAvailable = true;
17983
18019
  } catch {
17984
18020
  this.transcribeCliAvailable = false;
@@ -17995,7 +18031,7 @@ var init_listen = __esm({
17995
18031
  } catch {
17996
18032
  }
17997
18033
  try {
17998
- const globalRoot = execSync21("npm root -g", {
18034
+ const globalRoot = execSync22("npm root -g", {
17999
18035
  encoding: "utf-8",
18000
18036
  timeout: 5e3,
18001
18037
  stdio: ["pipe", "pipe", "pipe"]
@@ -18045,7 +18081,7 @@ var init_listen = __esm({
18045
18081
  }
18046
18082
  if (!tc) {
18047
18083
  try {
18048
- execSync21("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
18084
+ execSync22("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
18049
18085
  this.transcribeCliAvailable = null;
18050
18086
  tc = await this.loadTranscribeCli();
18051
18087
  } catch {
@@ -18228,7 +18264,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
18228
18264
  }
18229
18265
  if (!tc) {
18230
18266
  try {
18231
- execSync21("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
18267
+ execSync22("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
18232
18268
  this.transcribeCliAvailable = null;
18233
18269
  tc = await this.loadTranscribeCli();
18234
18270
  } catch {
@@ -18282,7 +18318,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
18282
18318
  }
18283
18319
  if (!tc) {
18284
18320
  try {
18285
- execSync21("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
18321
+ execSync22("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
18286
18322
  this.transcribeCliAvailable = null;
18287
18323
  tc = await this.loadTranscribeCli();
18288
18324
  } catch {
@@ -22794,6 +22830,7 @@ var init_render = __esm({
22794
22830
  };
22795
22831
  _contentWriteHook = null;
22796
22832
  HINTS = [
22833
+ "Ask the agent to connect to the Open Agents Nexus for P2P agent networking",
22797
22834
  "Use /voice to enable TTS voice feedback while the agent works",
22798
22835
  "Drop an image file onto the terminal to give the agent visual context",
22799
22836
  "Type while the agent works (+ prompt) to steer its approach",
@@ -22805,7 +22842,8 @@ var init_render = __esm({
22805
22842
  "Use /update to check for and install the latest version",
22806
22843
  "The agent can take screenshots and OCR text from images autonomously",
22807
22844
  "Sub-agents can run independent tasks in parallel via sub_agent tool",
22808
- "Background tasks let the agent run tests while making other changes"
22845
+ "Background tasks let the agent run tests while making other changes",
22846
+ "Use /nexus connect to join the decentralized agent mesh network"
22809
22847
  ];
22810
22848
  TOOL_NAMES = [
22811
22849
  "file_read",
@@ -22867,7 +22905,7 @@ var init_render = __esm({
22867
22905
 
22868
22906
  // packages/cli/dist/tui/voice-session.js
22869
22907
  import { createServer } from "node:http";
22870
- import { spawn as spawn12, execSync as execSync22 } from "node:child_process";
22908
+ import { spawn as spawn12, execSync as execSync23 } from "node:child_process";
22871
22909
  import { EventEmitter as EventEmitter2 } from "node:events";
22872
22910
  function generateFrontendHTML() {
22873
22911
  return `<!DOCTYPE html>
@@ -25906,7 +25944,7 @@ var init_oa_directory = __esm({
25906
25944
 
25907
25945
  // packages/cli/dist/tui/setup.js
25908
25946
  import * as readline from "node:readline";
25909
- import { execSync as execSync23, spawn as spawn14 } from "node:child_process";
25947
+ import { execSync as execSync24, spawn as spawn14 } from "node:child_process";
25910
25948
  import { existsSync as existsSync25, writeFileSync as writeFileSync9, mkdirSync as mkdirSync9 } from "node:fs";
25911
25949
  import { join as join35 } from "node:path";
25912
25950
  import { homedir as homedir10, platform } from "node:os";
@@ -25916,7 +25954,7 @@ function detectSystemSpecs() {
25916
25954
  let gpuVramGB = 0;
25917
25955
  let gpuName = "";
25918
25956
  try {
25919
- const memInfo = execSync23("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
25957
+ const memInfo = execSync24("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
25920
25958
  encoding: "utf8",
25921
25959
  timeout: 5e3
25922
25960
  });
@@ -25936,7 +25974,7 @@ function detectSystemSpecs() {
25936
25974
  } catch {
25937
25975
  }
25938
25976
  try {
25939
- const nvidiaSmi = execSync23("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
25977
+ const nvidiaSmi = execSync24("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
25940
25978
  const lines = nvidiaSmi.trim().split("\n");
25941
25979
  if (lines.length > 0) {
25942
25980
  for (const line of lines) {
@@ -26061,7 +26099,7 @@ function ensureCurl() {
26061
26099
  for (const s of strategies) {
26062
26100
  if (hasCmd(s.check)) {
26063
26101
  try {
26064
- execSync23(s.install, { stdio: "inherit", timeout: 12e4 });
26102
+ execSync24(s.install, { stdio: "inherit", timeout: 12e4 });
26065
26103
  if (hasCmd("curl")) {
26066
26104
  process.stdout.write(` ${c2.green("\u2714")} curl installed via ${s.label}.
26067
26105
  `);
@@ -26075,7 +26113,7 @@ function ensureCurl() {
26075
26113
  }
26076
26114
  if (plat === "darwin") {
26077
26115
  try {
26078
- execSync23("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
26116
+ execSync24("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
26079
26117
  if (hasCmd("curl"))
26080
26118
  return true;
26081
26119
  } catch {
@@ -26110,7 +26148,7 @@ function installOllamaLinux() {
26110
26148
 
26111
26149
  `);
26112
26150
  try {
26113
- execSync23("curl -fsSL https://ollama.com/install.sh | sh", {
26151
+ execSync24("curl -fsSL https://ollama.com/install.sh | sh", {
26114
26152
  stdio: "inherit",
26115
26153
  timeout: 3e5
26116
26154
  });
@@ -26138,7 +26176,7 @@ async function installOllamaMac(_rl) {
26138
26176
 
26139
26177
  `);
26140
26178
  try {
26141
- execSync23('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
26179
+ execSync24('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
26142
26180
  if (!hasCmd("brew")) {
26143
26181
  try {
26144
26182
  const brewPrefix = existsSync25("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
@@ -26171,7 +26209,7 @@ async function installOllamaMac(_rl) {
26171
26209
 
26172
26210
  `);
26173
26211
  try {
26174
- execSync23("brew install ollama", {
26212
+ execSync24("brew install ollama", {
26175
26213
  stdio: "inherit",
26176
26214
  timeout: 3e5
26177
26215
  });
@@ -26198,7 +26236,7 @@ function installOllamaWindows() {
26198
26236
 
26199
26237
  `);
26200
26238
  try {
26201
- execSync23('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
26239
+ execSync24('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
26202
26240
  stdio: "inherit",
26203
26241
  timeout: 3e5
26204
26242
  });
@@ -26279,7 +26317,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
26279
26317
  }
26280
26318
  function pullModelWithAutoUpdate(tag) {
26281
26319
  try {
26282
- execSync23(`ollama pull ${tag}`, {
26320
+ execSync24(`ollama pull ${tag}`, {
26283
26321
  stdio: "inherit",
26284
26322
  timeout: 36e5
26285
26323
  // 1 hour max
@@ -26299,7 +26337,7 @@ function pullModelWithAutoUpdate(tag) {
26299
26337
 
26300
26338
  `);
26301
26339
  try {
26302
- execSync23("curl -fsSL https://ollama.com/install.sh | sh", {
26340
+ execSync24("curl -fsSL https://ollama.com/install.sh | sh", {
26303
26341
  stdio: "inherit",
26304
26342
  timeout: 3e5
26305
26343
  // 5 min max for install
@@ -26310,7 +26348,7 @@ function pullModelWithAutoUpdate(tag) {
26310
26348
  process.stdout.write(` ${c2.cyan("\u25CF")} Retrying pull of ${c2.bold(tag)}...
26311
26349
 
26312
26350
  `);
26313
- execSync23(`ollama pull ${tag}`, {
26351
+ execSync24(`ollama pull ${tag}`, {
26314
26352
  stdio: "inherit",
26315
26353
  timeout: 36e5
26316
26354
  });
@@ -26412,7 +26450,7 @@ function ensurePython3() {
26412
26450
  if (plat === "darwin") {
26413
26451
  if (hasCmd("brew")) {
26414
26452
  try {
26415
- execSync23("brew install python3", { stdio: "inherit", timeout: 3e5 });
26453
+ execSync24("brew install python3", { stdio: "inherit", timeout: 3e5 });
26416
26454
  if (hasCmd("python3")) {
26417
26455
  process.stdout.write(` ${c2.green("\u2714")} Python3 installed via Homebrew.
26418
26456
  `);
@@ -26425,7 +26463,7 @@ function ensurePython3() {
26425
26463
  for (const s of strategies) {
26426
26464
  if (hasCmd(s.check)) {
26427
26465
  try {
26428
- execSync23(s.install, { stdio: "inherit", timeout: 12e4 });
26466
+ execSync24(s.install, { stdio: "inherit", timeout: 12e4 });
26429
26467
  if (hasCmd("python3") || hasCmd("python")) {
26430
26468
  process.stdout.write(` ${c2.green("\u2714")} Python3 installed via ${s.label}.
26431
26469
  `);
@@ -26441,11 +26479,11 @@ function ensurePython3() {
26441
26479
  }
26442
26480
  function checkPythonVenv() {
26443
26481
  try {
26444
- execSync23("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
26482
+ execSync24("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
26445
26483
  return true;
26446
26484
  } catch {
26447
26485
  try {
26448
- execSync23("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
26486
+ execSync24("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
26449
26487
  return true;
26450
26488
  } catch {
26451
26489
  return false;
@@ -26464,7 +26502,7 @@ function ensurePythonVenv() {
26464
26502
  for (const s of strategies) {
26465
26503
  if (hasCmd(s.check)) {
26466
26504
  try {
26467
- execSync23(s.install, { stdio: "inherit", timeout: 12e4 });
26505
+ execSync24(s.install, { stdio: "inherit", timeout: 12e4 });
26468
26506
  if (checkPythonVenv()) {
26469
26507
  process.stdout.write(` ${c2.green("\u2714")} python3-venv installed via ${s.label}.
26470
26508
  `);
@@ -26900,7 +26938,7 @@ async function doSetup(config, rl) {
26900
26938
  const modelfilePath = join35(modelDir2, `Modelfile.${customName}`);
26901
26939
  writeFileSync9(modelfilePath, modelfileContent + "\n", "utf8");
26902
26940
  process.stdout.write(` ${c2.dim("Creating model...")} `);
26903
- execSync23(`ollama create ${customName} -f ${modelfilePath}`, {
26941
+ execSync24(`ollama create ${customName} -f ${modelfilePath}`, {
26904
26942
  stdio: "pipe",
26905
26943
  timeout: 12e4
26906
26944
  });
@@ -26951,7 +26989,7 @@ function isFirstRun() {
26951
26989
  function hasCmd(cmd) {
26952
26990
  try {
26953
26991
  const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
26954
- execSync23(whichCmd, { stdio: "pipe", timeout: 3e3 });
26992
+ execSync24(whichCmd, { stdio: "pipe", timeout: 3e3 });
26955
26993
  return true;
26956
26994
  } catch {
26957
26995
  return false;
@@ -26984,7 +27022,7 @@ function getVenvDir() {
26984
27022
  }
26985
27023
  function hasVenvModule() {
26986
27024
  try {
26987
- execSync23("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
27025
+ execSync24("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
26988
27026
  return true;
26989
27027
  } catch {
26990
27028
  return false;
@@ -27006,8 +27044,8 @@ function ensureVenv(log) {
27006
27044
  }
27007
27045
  try {
27008
27046
  mkdirSync9(join35(homedir10(), ".open-agents"), { recursive: true });
27009
- execSync23(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
27010
- execSync23(`"${join35(venvDir, "bin", "pip")}" install --upgrade pip`, {
27047
+ execSync24(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
27048
+ execSync24(`"${join35(venvDir, "bin", "pip")}" install --upgrade pip`, {
27011
27049
  stdio: "pipe",
27012
27050
  timeout: 6e4
27013
27051
  });
@@ -27020,7 +27058,7 @@ function ensureVenv(log) {
27020
27058
  }
27021
27059
  function trySudoPasswordless(cmd, timeoutMs = 12e4) {
27022
27060
  try {
27023
- execSync23(`sudo -n ${cmd}`, {
27061
+ execSync24(`sudo -n ${cmd}`, {
27024
27062
  stdio: "pipe",
27025
27063
  timeout: timeoutMs,
27026
27064
  env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
@@ -27032,7 +27070,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
27032
27070
  }
27033
27071
  function runWithSudo(cmd, password, timeoutMs = 12e4) {
27034
27072
  try {
27035
- execSync23(`sudo -S ${cmd}`, {
27073
+ execSync24(`sudo -S ${cmd}`, {
27036
27074
  input: password + "\n",
27037
27075
  stdio: ["pipe", "pipe", "pipe"],
27038
27076
  timeout: timeoutMs,
@@ -27092,7 +27130,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
27092
27130
  } else {
27093
27131
  log("Installing tesseract-ocr...");
27094
27132
  try {
27095
- execSync23(pkg.cmd, { stdio: "pipe", timeout: 12e4 });
27133
+ execSync24(pkg.cmd, { stdio: "pipe", timeout: 12e4 });
27096
27134
  if (hasCmd("tesseract")) {
27097
27135
  log("tesseract-ocr installed successfully.");
27098
27136
  } else {
@@ -27164,7 +27202,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
27164
27202
  } else {
27165
27203
  log(`Installing ${dep.label}...`);
27166
27204
  try {
27167
- execSync23(pkg.cmd, { stdio: "pipe", timeout: 12e4 });
27205
+ execSync24(pkg.cmd, { stdio: "pipe", timeout: 12e4 });
27168
27206
  if (hasCmd(dep.binary)) {
27169
27207
  log(`${dep.label} installed successfully.`);
27170
27208
  } else {
@@ -27195,7 +27233,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
27195
27233
  const venvCmds = {
27196
27234
  apt: () => {
27197
27235
  try {
27198
- const pyVer = execSync23(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
27236
+ const pyVer = execSync24(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
27199
27237
  return `apt-get install -y python3-venv python${pyVer}-venv`;
27200
27238
  } catch {
27201
27239
  return "apt-get install -y python3-venv";
@@ -27223,12 +27261,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
27223
27261
  const venvPip = join35(venvBin, "pip");
27224
27262
  log("Installing moondream-station in ~/.open-agents/venv...");
27225
27263
  try {
27226
- execSync23(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
27264
+ execSync24(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
27227
27265
  if (existsSync25(venvMoondream)) {
27228
27266
  log("moondream-station installed successfully.");
27229
27267
  } else {
27230
27268
  try {
27231
- const check = execSync23(`"${venvPip}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
27269
+ const check = execSync24(`"${venvPip}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
27232
27270
  if (check.includes("moondream")) {
27233
27271
  log("moondream-station package installed.");
27234
27272
  }
@@ -27245,7 +27283,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
27245
27283
  const venvPip2 = join35(venvBin, "pip");
27246
27284
  let ocrStackInstalled = false;
27247
27285
  try {
27248
- execSync23(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
27286
+ execSync24(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
27249
27287
  ocrStackInstalled = true;
27250
27288
  } catch {
27251
27289
  }
@@ -27253,9 +27291,9 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
27253
27291
  const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
27254
27292
  log("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
27255
27293
  try {
27256
- execSync23(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
27294
+ execSync24(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
27257
27295
  try {
27258
- execSync23(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
27296
+ execSync24(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
27259
27297
  log("OCR Python stack installed successfully.");
27260
27298
  } catch {
27261
27299
  log("OCR Python stack install completed but import verification failed.");
@@ -27289,7 +27327,7 @@ function ensureCloudflaredBackground(onInfo) {
27289
27327
  const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
27290
27328
  const cfArch = archMap[arch] ?? "amd64";
27291
27329
  try {
27292
- execSync23(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir10()}/.local/bin" && mv /tmp/cloudflared "${homedir10()}/.local/bin/cloudflared"`, { stdio: "pipe", timeout: 6e4 });
27330
+ execSync24(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir10()}/.local/bin" && mv /tmp/cloudflared "${homedir10()}/.local/bin/cloudflared"`, { stdio: "pipe", timeout: 6e4 });
27293
27331
  if (!process.env.PATH?.includes(`${homedir10()}/.local/bin`)) {
27294
27332
  process.env.PATH = `${homedir10()}/.local/bin:${process.env.PATH}`;
27295
27333
  }
@@ -27300,7 +27338,7 @@ function ensureCloudflaredBackground(onInfo) {
27300
27338
  } catch {
27301
27339
  }
27302
27340
  try {
27303
- execSync23(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && sudo mv /tmp/cloudflared /usr/local/bin/cloudflared 2>/dev/null`, { stdio: "pipe", timeout: 6e4 });
27341
+ execSync24(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && sudo mv /tmp/cloudflared /usr/local/bin/cloudflared 2>/dev/null`, { stdio: "pipe", timeout: 6e4 });
27304
27342
  if (hasCmd("cloudflared")) {
27305
27343
  log("cloudflared installed.");
27306
27344
  return true;
@@ -27309,7 +27347,7 @@ function ensureCloudflaredBackground(onInfo) {
27309
27347
  }
27310
27348
  } else if (os === "darwin") {
27311
27349
  try {
27312
- execSync23("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
27350
+ execSync24("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
27313
27351
  if (hasCmd("cloudflared")) {
27314
27352
  log("cloudflared installed via Homebrew.");
27315
27353
  return true;
@@ -27359,7 +27397,7 @@ function createExpandedVariant(baseModel, specs, sizeGB) {
27359
27397
  mkdirSync9(modelDir2, { recursive: true });
27360
27398
  const modelfilePath = join35(modelDir2, `Modelfile.${customName}`);
27361
27399
  writeFileSync9(modelfilePath, modelfileContent + "\n", "utf8");
27362
- execSync23(`ollama create ${customName} -f ${modelfilePath}`, {
27400
+ execSync24(`ollama create ${customName} -f ${modelfilePath}`, {
27363
27401
  stdio: "pipe",
27364
27402
  timeout: 12e4
27365
27403
  });
@@ -28885,7 +28923,7 @@ var init_commands = __esm({
28885
28923
  // packages/cli/dist/tui/project-context.js
28886
28924
  import { existsSync as existsSync26, readFileSync as readFileSync17, readdirSync as readdirSync8 } from "node:fs";
28887
28925
  import { join as join36, basename as basename10 } from "node:path";
28888
- import { execSync as execSync24 } from "node:child_process";
28926
+ import { execSync as execSync25 } from "node:child_process";
28889
28927
  import { homedir as homedir11, platform as platform2, release } from "node:os";
28890
28928
  function getModelTier(modelName) {
28891
28929
  const m = modelName.toLowerCase();
@@ -28931,19 +28969,19 @@ function loadProjectMap(repoRoot) {
28931
28969
  }
28932
28970
  function getGitInfo(repoRoot) {
28933
28971
  try {
28934
- execSync24("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
28972
+ execSync25("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
28935
28973
  } catch {
28936
28974
  return "";
28937
28975
  }
28938
28976
  const lines = [];
28939
28977
  try {
28940
- const branch = execSync24("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
28978
+ const branch = execSync25("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
28941
28979
  if (branch)
28942
28980
  lines.push(`Branch: ${branch}`);
28943
28981
  } catch {
28944
28982
  }
28945
28983
  try {
28946
- const status = execSync24("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
28984
+ const status = execSync25("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
28947
28985
  if (status) {
28948
28986
  const changed = status.split("\n").length;
28949
28987
  lines.push(`Working tree: ${changed} changed file(s)`);
@@ -28953,7 +28991,7 @@ function getGitInfo(repoRoot) {
28953
28991
  } catch {
28954
28992
  }
28955
28993
  try {
28956
- const log = execSync24("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
28994
+ const log = execSync25("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
28957
28995
  if (log)
28958
28996
  lines.push(`Recent commits:
28959
28997
  ${log}`);
@@ -30370,7 +30408,7 @@ var init_carousel_descriptors = __esm({
30370
30408
  import { existsSync as existsSync28, mkdirSync as mkdirSync11, writeFileSync as writeFileSync11, readFileSync as readFileSync19, unlinkSync as unlinkSync4 } from "node:fs";
30371
30409
  import { join as join38 } from "node:path";
30372
30410
  import { homedir as homedir12, tmpdir as tmpdir6, platform as platform3 } from "node:os";
30373
- import { execSync as execSync25, spawn as nodeSpawn } from "node:child_process";
30411
+ import { execSync as execSync26, spawn as nodeSpawn } from "node:child_process";
30374
30412
  import { createRequire } from "node:module";
30375
30413
  function voiceDir() {
30376
30414
  return join38(homedir12(), ".open-agents", "voice");
@@ -31197,7 +31235,7 @@ var init_voice = __esm({
31197
31235
  }
31198
31236
  for (const player of ["paplay", "pw-play", "aplay"]) {
31199
31237
  try {
31200
- execSync25(`which ${player}`, { stdio: "pipe" });
31238
+ execSync26(`which ${player}`, { stdio: "pipe" });
31201
31239
  return [player, path];
31202
31240
  } catch {
31203
31241
  }
@@ -31253,7 +31291,7 @@ var init_voice = __esm({
31253
31291
  }
31254
31292
  renderInfo("Installing ONNX runtime for voice synthesis...");
31255
31293
  try {
31256
- execSync25("npm install --no-audit --no-fund", {
31294
+ execSync26("npm install --no-audit --no-fund", {
31257
31295
  cwd: voiceDir(),
31258
31296
  stdio: "pipe",
31259
31297
  timeout: 12e4
@@ -31274,7 +31312,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
31274
31312
  }
31275
31313
  renderInfo("Installing phonemizer for voice synthesis...");
31276
31314
  try {
31277
- execSync25("npm install --no-audit --no-fund", {
31315
+ execSync26("npm install --no-audit --no-fund", {
31278
31316
  cwd: voiceDir(),
31279
31317
  stdio: "pipe",
31280
31318
  timeout: 12e4
@@ -32328,7 +32366,7 @@ var init_edit_history = __esm({
32328
32366
  // packages/cli/dist/tui/dream-engine.js
32329
32367
  import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync12, readFileSync as readFileSync20, existsSync as existsSync29, cpSync, rmSync, readdirSync as readdirSync10 } from "node:fs";
32330
32368
  import { join as join40, basename as basename12 } from "node:path";
32331
- import { execSync as execSync26 } from "node:child_process";
32369
+ import { execSync as execSync27 } from "node:child_process";
32332
32370
  function loadAutoresearchMemory(repoRoot) {
32333
32371
  const memoryPath = join40(repoRoot, ".oa", "memory", "autoresearch.json");
32334
32372
  if (!existsSync29(memoryPath))
@@ -32722,7 +32760,7 @@ var init_dream_engine = __esm({
32722
32760
  }
32723
32761
  }
32724
32762
  try {
32725
- const output = execSync26(cmd, {
32763
+ const output = execSync27(cmd, {
32726
32764
  cwd: this.repoRoot,
32727
32765
  timeout: 3e4,
32728
32766
  encoding: "utf-8",
@@ -33499,17 +33537,17 @@ ${summaryResult}
33499
33537
  try {
33500
33538
  mkdirSync13(checkpointDir, { recursive: true });
33501
33539
  try {
33502
- const gitStatus = execSync26("git status --porcelain", {
33540
+ const gitStatus = execSync27("git status --porcelain", {
33503
33541
  cwd: this.repoRoot,
33504
33542
  encoding: "utf-8",
33505
33543
  timeout: 1e4
33506
33544
  });
33507
- const gitDiff = execSync26("git diff", {
33545
+ const gitDiff = execSync27("git diff", {
33508
33546
  cwd: this.repoRoot,
33509
33547
  encoding: "utf-8",
33510
33548
  timeout: 1e4
33511
33549
  });
33512
- const gitHash = execSync26("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
33550
+ const gitHash = execSync27("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
33513
33551
  cwd: this.repoRoot,
33514
33552
  encoding: "utf-8",
33515
33553
  timeout: 5e3
@@ -38656,6 +38694,26 @@ async function startInteractive(config, repoPath) {
38656
38694
  }
38657
38695
  })).catch(() => {
38658
38696
  });
38697
+ if (!isResumed) {
38698
+ checkForUpdate(version).then((updateInfo) => {
38699
+ if (updateInfo) {
38700
+ const writeMsg = () => {
38701
+ if (statusBar?.isActive)
38702
+ statusBar.beginContentWrite();
38703
+ renderWarning(`Update available: v${updateInfo.currentVersion} \u2192 v${c2.bold(c2.green(updateInfo.latestVersion))}`);
38704
+ renderInfo(`Run /update to install now, or it will auto-install after your next task.`);
38705
+ if (statusBar?.isActive)
38706
+ statusBar.endContentWrite();
38707
+ };
38708
+ writeMsg();
38709
+ const updateMode = savedSettings.updateMode ?? "auto";
38710
+ if (updateMode !== "manual") {
38711
+ performSilentUpdate();
38712
+ }
38713
+ }
38714
+ }).catch(() => {
38715
+ });
38716
+ }
38659
38717
  const voiceEngine = new VoiceEngine();
38660
38718
  let voiceSession = null;
38661
38719
  let exposeGateway = null;